hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/cifs/ioctl.c
....@@ -32,7 +32,50 @@
3232 #include "cifs_debug.h"
3333 #include "cifsfs.h"
3434 #include "cifs_ioctl.h"
35
+#include "smb2proto.h"
3536 #include <linux/btrfs.h>
37
+
38
+static long cifs_ioctl_query_info(unsigned int xid, struct file *filep,
39
+ unsigned long p)
40
+{
41
+ struct inode *inode = file_inode(filep);
42
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
43
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
44
+ struct dentry *dentry = filep->f_path.dentry;
45
+ unsigned char *path;
46
+ __le16 *utf16_path = NULL, root_path;
47
+ int rc = 0;
48
+
49
+ path = build_path_from_dentry(dentry);
50
+ if (path == NULL)
51
+ return -ENOMEM;
52
+
53
+ cifs_dbg(FYI, "%s %s\n", __func__, path);
54
+
55
+ if (!path[0]) {
56
+ root_path = 0;
57
+ utf16_path = &root_path;
58
+ } else {
59
+ utf16_path = cifs_convert_path_to_utf16(path + 1, cifs_sb);
60
+ if (!utf16_path) {
61
+ rc = -ENOMEM;
62
+ goto ici_exit;
63
+ }
64
+ }
65
+
66
+ if (tcon->ses->server->ops->ioctl_query_info)
67
+ rc = tcon->ses->server->ops->ioctl_query_info(
68
+ xid, tcon, cifs_sb, utf16_path,
69
+ filep->private_data ? 0 : 1, p);
70
+ else
71
+ rc = -EOPNOTSUPP;
72
+
73
+ ici_exit:
74
+ if (utf16_path != &root_path)
75
+ kfree(utf16_path);
76
+ kfree(path);
77
+ return rc;
78
+}
3679
3780 static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file,
3881 unsigned long srcfd)
....@@ -121,17 +164,18 @@
121164 long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
122165 {
123166 struct inode *inode = file_inode(filep);
167
+ struct smb3_key_debug_info pkey_inf;
124168 int rc = -ENOTTY; /* strange error - but the precedent */
125169 unsigned int xid;
126
- struct cifs_sb_info *cifs_sb;
127170 struct cifsFileInfo *pSMBFile = filep->private_data;
128171 struct cifs_tcon *tcon;
172
+ struct tcon_link *tlink;
173
+ struct cifs_sb_info *cifs_sb;
129174 __u64 ExtAttrBits = 0;
130175 __u64 caps;
131176
132177 xid = get_xid();
133178
134
- cifs_sb = CIFS_SB(inode->i_sb);
135179 cifs_dbg(FYI, "cifs ioctl 0x%x\n", command);
136180 switch (command) {
137181 case FS_IOC_GETFLAGS:
....@@ -149,7 +193,7 @@
149193 rc = put_user(ExtAttrBits &
150194 FS_FL_USER_VISIBLE,
151195 (int __user *)arg);
152
- if (rc != EOPNOTSUPP)
196
+ if (rc != -EOPNOTSUPP)
153197 break;
154198 }
155199 #endif /* CONFIG_CIFS_POSIX */
....@@ -178,7 +222,7 @@
178222 * pSMBFile->fid.netfid,
179223 * extAttrBits,
180224 * &ExtAttrMask);
181
- * if (rc != EOPNOTSUPP)
225
+ * if (rc != -EOPNOTSUPP)
182226 * break;
183227 */
184228
....@@ -195,6 +239,9 @@
195239 break;
196240 case CIFS_IOC_COPYCHUNK_FILE:
197241 rc = cifs_ioctl_copychunk(xid, filep, arg);
242
+ break;
243
+ case CIFS_QUERY_INFO:
244
+ rc = cifs_ioctl_query_info(xid, filep, arg);
198245 break;
199246 case CIFS_IOC_SET_INTEGRITY:
200247 if (pSMBFile == NULL)
....@@ -226,6 +273,55 @@
226273 else
227274 rc = -EOPNOTSUPP;
228275 break;
276
+ case CIFS_DUMP_KEY:
277
+ if (pSMBFile == NULL)
278
+ break;
279
+ if (!capable(CAP_SYS_ADMIN)) {
280
+ rc = -EACCES;
281
+ break;
282
+ }
283
+
284
+ tcon = tlink_tcon(pSMBFile->tlink);
285
+ if (!smb3_encryption_required(tcon)) {
286
+ rc = -EOPNOTSUPP;
287
+ break;
288
+ }
289
+ pkey_inf.cipher_type =
290
+ le16_to_cpu(tcon->ses->server->cipher_type);
291
+ pkey_inf.Suid = tcon->ses->Suid;
292
+ memcpy(pkey_inf.auth_key, tcon->ses->auth_key.response,
293
+ 16 /* SMB2_NTLMV2_SESSKEY_SIZE */);
294
+ memcpy(pkey_inf.smb3decryptionkey,
295
+ tcon->ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
296
+ memcpy(pkey_inf.smb3encryptionkey,
297
+ tcon->ses->smb3encryptionkey, SMB3_SIGN_KEY_SIZE);
298
+ if (copy_to_user((void __user *)arg, &pkey_inf,
299
+ sizeof(struct smb3_key_debug_info)))
300
+ rc = -EFAULT;
301
+ else
302
+ rc = 0;
303
+ break;
304
+ case CIFS_IOC_NOTIFY:
305
+ if (!S_ISDIR(inode->i_mode)) {
306
+ /* Notify can only be done on directories */
307
+ rc = -EOPNOTSUPP;
308
+ break;
309
+ }
310
+ cifs_sb = CIFS_SB(inode->i_sb);
311
+ tlink = cifs_sb_tlink(cifs_sb);
312
+ if (IS_ERR(tlink)) {
313
+ rc = PTR_ERR(tlink);
314
+ break;
315
+ }
316
+ tcon = tlink_tcon(tlink);
317
+ if (tcon && tcon->ses->server->ops->notify) {
318
+ rc = tcon->ses->server->ops->notify(xid,
319
+ filep, (void __user *)arg);
320
+ cifs_dbg(FYI, "ioctl notify rc %d\n", rc);
321
+ } else
322
+ rc = -EOPNOTSUPP;
323
+ cifs_put_tlink(tlink);
324
+ break;
229325 default:
230326 cifs_dbg(FYI, "unsupported ioctl\n");
231327 break;