hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/fs/cifs/xattr.c
....@@ -32,7 +32,8 @@
3232 #include "cifs_unicode.h"
3333
3434 #define MAX_EA_VALUE_SIZE CIFSMaxBufSize
35
-#define CIFS_XATTR_CIFS_ACL "system.cifs_acl"
35
+#define CIFS_XATTR_CIFS_ACL "system.cifs_acl" /* DACL only */
36
+#define CIFS_XATTR_CIFS_NTSD "system.cifs_ntsd" /* owner plus DACL */
3637 #define CIFS_XATTR_ATTRIB "cifs.dosattrib" /* full name: user.cifs.dosattrib */
3738 #define CIFS_XATTR_CREATETIME "cifs.creationtime" /* user.cifs.creationtime */
3839 /*
....@@ -40,12 +41,62 @@
4041 * confusing users and using the 20+ year old term 'cifs' when it is no longer
4142 * secure, replaced by SMB2 (then even more highly secure SMB3) many years ago
4243 */
43
-#define SMB3_XATTR_CIFS_ACL "system.smb3_acl"
44
+#define SMB3_XATTR_CIFS_ACL "system.smb3_acl" /* DACL only */
45
+#define SMB3_XATTR_CIFS_NTSD "system.smb3_ntsd" /* owner plus DACL */
4446 #define SMB3_XATTR_ATTRIB "smb3.dosattrib" /* full name: user.smb3.dosattrib */
4547 #define SMB3_XATTR_CREATETIME "smb3.creationtime" /* user.smb3.creationtime */
4648 /* BB need to add server (Samba e.g) support for security and trusted prefix */
4749
48
-enum { XATTR_USER, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT };
50
+enum { XATTR_USER, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT,
51
+ XATTR_CIFS_NTSD };
52
+
53
+static int cifs_attrib_set(unsigned int xid, struct cifs_tcon *pTcon,
54
+ struct inode *inode, char *full_path,
55
+ const void *value, size_t size)
56
+{
57
+ ssize_t rc = -EOPNOTSUPP;
58
+ __u32 *pattrib = (__u32 *)value;
59
+ __u32 attrib;
60
+ FILE_BASIC_INFO info_buf;
61
+
62
+ if ((value == NULL) || (size != sizeof(__u32)))
63
+ return -ERANGE;
64
+
65
+ memset(&info_buf, 0, sizeof(info_buf));
66
+ attrib = *pattrib;
67
+ info_buf.Attributes = cpu_to_le32(attrib);
68
+ if (pTcon->ses->server->ops->set_file_info)
69
+ rc = pTcon->ses->server->ops->set_file_info(inode, full_path,
70
+ &info_buf, xid);
71
+ if (rc == 0)
72
+ CIFS_I(inode)->cifsAttrs = attrib;
73
+
74
+ return rc;
75
+}
76
+
77
+static int cifs_creation_time_set(unsigned int xid, struct cifs_tcon *pTcon,
78
+ struct inode *inode, char *full_path,
79
+ const void *value, size_t size)
80
+{
81
+ ssize_t rc = -EOPNOTSUPP;
82
+ __u64 *pcreation_time = (__u64 *)value;
83
+ __u64 creation_time;
84
+ FILE_BASIC_INFO info_buf;
85
+
86
+ if ((value == NULL) || (size != sizeof(__u64)))
87
+ return -ERANGE;
88
+
89
+ memset(&info_buf, 0, sizeof(info_buf));
90
+ creation_time = *pcreation_time;
91
+ info_buf.CreationTime = cpu_to_le64(creation_time);
92
+ if (pTcon->ses->server->ops->set_file_info)
93
+ rc = pTcon->ses->server->ops->set_file_info(inode, full_path,
94
+ &info_buf, xid);
95
+ if (rc == 0)
96
+ CIFS_I(inode)->createtime = creation_time;
97
+
98
+ return rc;
99
+}
49100
50101 static int cifs_xattr_set(const struct xattr_handler *handler,
51102 struct dentry *dentry, struct inode *inode,
....@@ -86,6 +137,23 @@
86137
87138 switch (handler->flags) {
88139 case XATTR_USER:
140
+ cifs_dbg(FYI, "%s:setting user xattr %s\n", __func__, name);
141
+ if ((strcmp(name, CIFS_XATTR_ATTRIB) == 0) ||
142
+ (strcmp(name, SMB3_XATTR_ATTRIB) == 0)) {
143
+ rc = cifs_attrib_set(xid, pTcon, inode, full_path,
144
+ value, size);
145
+ if (rc == 0) /* force revalidate of the inode */
146
+ CIFS_I(inode)->time = 0;
147
+ break;
148
+ } else if ((strcmp(name, CIFS_XATTR_CREATETIME) == 0) ||
149
+ (strcmp(name, SMB3_XATTR_CREATETIME) == 0)) {
150
+ rc = cifs_creation_time_set(xid, pTcon, inode,
151
+ full_path, value, size);
152
+ if (rc == 0) /* force revalidate of the inode */
153
+ CIFS_I(inode)->time = 0;
154
+ break;
155
+ }
156
+
89157 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
90158 goto out;
91159
....@@ -95,8 +163,8 @@
95163 cifs_sb->local_nls, cifs_sb);
96164 break;
97165
98
- case XATTR_CIFS_ACL: {
99
-#ifdef CONFIG_CIFS_ACL
166
+ case XATTR_CIFS_ACL:
167
+ case XATTR_CIFS_NTSD: {
100168 struct cifs_ntsd *pacl;
101169
102170 if (!value)
....@@ -107,17 +175,29 @@
107175 } else {
108176 memcpy(pacl, value, size);
109177 if (value &&
110
- pTcon->ses->server->ops->set_acl)
111
- rc = pTcon->ses->server->ops->set_acl(pacl,
112
- size, inode,
113
- full_path, CIFS_ACL_DACL);
114
- else
178
+ pTcon->ses->server->ops->set_acl) {
179
+ rc = 0;
180
+ if (handler->flags == XATTR_CIFS_NTSD) {
181
+ /* set owner and DACL */
182
+ rc = pTcon->ses->server->ops->set_acl(
183
+ pacl, size, inode,
184
+ full_path,
185
+ CIFS_ACL_OWNER);
186
+ }
187
+ if (rc == 0) {
188
+ /* set DACL */
189
+ rc = pTcon->ses->server->ops->set_acl(
190
+ pacl, size, inode,
191
+ full_path,
192
+ CIFS_ACL_DACL);
193
+ }
194
+ } else {
115195 rc = -EOPNOTSUPP;
196
+ }
116197 if (rc == 0) /* force revalidate of the inode */
117198 CIFS_I(inode)->time = 0;
118199 kfree(pacl);
119200 }
120
-#endif /* CONFIG_CIFS_ACL */
121201 break;
122202 }
123203
....@@ -181,7 +261,7 @@
181261 void *value, size_t size)
182262 {
183263 ssize_t rc;
184
- __u64 * pcreatetime;
264
+ __u64 *pcreatetime;
185265
186266 rc = cifs_revalidate_dentry_attr(dentry);
187267 if (rc)
....@@ -201,7 +281,7 @@
201281
202282 static int cifs_xattr_get(const struct xattr_handler *handler,
203283 struct dentry *dentry, struct inode *inode,
204
- const char *name, void *value, size_t size)
284
+ const char *name, void *value, size_t size, int flags)
205285 {
206286 ssize_t rc = -EOPNOTSUPP;
207287 unsigned int xid;
....@@ -246,8 +326,9 @@
246326 full_path, name, value, size, cifs_sb);
247327 break;
248328
249
- case XATTR_CIFS_ACL: {
250
-#ifdef CONFIG_CIFS_ACL
329
+ case XATTR_CIFS_ACL:
330
+ case XATTR_CIFS_NTSD: {
331
+ /* the whole ntsd is fetched regardless */
251332 u32 acllen;
252333 struct cifs_ntsd *pacl;
253334
....@@ -270,7 +351,6 @@
270351 rc = acllen;
271352 kfree(pacl);
272353 }
273
-#endif /* CONFIG_CIFS_ACL */
274354 break;
275355 }
276356
....@@ -386,6 +466,26 @@
386466 .set = cifs_xattr_set,
387467 };
388468
469
+static const struct xattr_handler cifs_cifs_ntsd_xattr_handler = {
470
+ .name = CIFS_XATTR_CIFS_NTSD,
471
+ .flags = XATTR_CIFS_NTSD,
472
+ .get = cifs_xattr_get,
473
+ .set = cifs_xattr_set,
474
+};
475
+
476
+/*
477
+ * Although this is just an alias for the above, need to move away from
478
+ * confusing users and using the 20 year old term 'cifs' when it is no
479
+ * longer secure and was replaced by SMB2/SMB3 a long time ago, and
480
+ * SMB3 and later are highly secure.
481
+ */
482
+static const struct xattr_handler smb3_ntsd_xattr_handler = {
483
+ .name = SMB3_XATTR_CIFS_NTSD,
484
+ .flags = XATTR_CIFS_NTSD,
485
+ .get = cifs_xattr_get,
486
+ .set = cifs_xattr_set,
487
+};
488
+
389489 static const struct xattr_handler cifs_posix_acl_access_xattr_handler = {
390490 .name = XATTR_NAME_POSIX_ACL_ACCESS,
391491 .flags = XATTR_ACL_ACCESS,
....@@ -405,6 +505,8 @@
405505 &cifs_os2_xattr_handler,
406506 &cifs_cifs_acl_xattr_handler,
407507 &smb3_acl_xattr_handler, /* alias for above since avoiding "cifs" */
508
+ &cifs_cifs_ntsd_xattr_handler,
509
+ &smb3_ntsd_xattr_handler, /* alias for above since avoiding "cifs" */
408510 &cifs_posix_acl_access_xattr_handler,
409511 &cifs_posix_acl_default_xattr_handler,
410512 NULL