aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/xattr.c')
-rw-r--r--fs/cifs/xattr.c143
1 files changed, 93 insertions, 50 deletions
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index a1509207bfa6..2a22fb2989e4 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -30,10 +30,11 @@
30 30
31#define MAX_EA_VALUE_SIZE 65535 31#define MAX_EA_VALUE_SIZE 65535
32#define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib" 32#define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
33#define CIFS_XATTR_CIFS_ACL "system.cifs_acl"
33#define CIFS_XATTR_USER_PREFIX "user." 34#define CIFS_XATTR_USER_PREFIX "user."
34#define CIFS_XATTR_SYSTEM_PREFIX "system." 35#define CIFS_XATTR_SYSTEM_PREFIX "system."
35#define CIFS_XATTR_OS2_PREFIX "os2." 36#define CIFS_XATTR_OS2_PREFIX "os2."
36#define CIFS_XATTR_SECURITY_PREFIX ".security" 37#define CIFS_XATTR_SECURITY_PREFIX "security."
37#define CIFS_XATTR_TRUSTED_PREFIX "trusted." 38#define CIFS_XATTR_TRUSTED_PREFIX "trusted."
38#define XATTR_TRUSTED_PREFIX_LEN 8 39#define XATTR_TRUSTED_PREFIX_LEN 8
39#define XATTR_SECURITY_PREFIX_LEN 9 40#define XATTR_SECURITY_PREFIX_LEN 9
@@ -47,9 +48,10 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
47#ifdef CONFIG_CIFS_XATTR 48#ifdef CONFIG_CIFS_XATTR
48 int xid; 49 int xid;
49 struct cifs_sb_info *cifs_sb; 50 struct cifs_sb_info *cifs_sb;
50 struct cifsTconInfo *pTcon; 51 struct tcon_link *tlink;
52 struct cifs_tcon *pTcon;
51 struct super_block *sb; 53 struct super_block *sb;
52 char *full_path; 54 char *full_path = NULL;
53 55
54 if (direntry == NULL) 56 if (direntry == NULL)
55 return -EIO; 57 return -EIO;
@@ -58,16 +60,19 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
58 sb = direntry->d_inode->i_sb; 60 sb = direntry->d_inode->i_sb;
59 if (sb == NULL) 61 if (sb == NULL)
60 return -EIO; 62 return -EIO;
61 xid = GetXid();
62 63
63 cifs_sb = CIFS_SB(sb); 64 cifs_sb = CIFS_SB(sb);
64 pTcon = cifs_sb->tcon; 65 tlink = cifs_sb_tlink(cifs_sb);
66 if (IS_ERR(tlink))
67 return PTR_ERR(tlink);
68 pTcon = tlink_tcon(tlink);
69
70 xid = GetXid();
65 71
66 full_path = build_path_from_dentry(direntry); 72 full_path = build_path_from_dentry(direntry);
67 if (full_path == NULL) { 73 if (full_path == NULL) {
68 rc = -ENOMEM; 74 rc = -ENOMEM;
69 FreeXid(xid); 75 goto remove_ea_exit;
70 return rc;
71 } 76 }
72 if (ea_name == NULL) { 77 if (ea_name == NULL) {
73 cFYI(1, "Null xattr names not supported"); 78 cFYI(1, "Null xattr names not supported");
@@ -91,6 +96,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
91remove_ea_exit: 96remove_ea_exit:
92 kfree(full_path); 97 kfree(full_path);
93 FreeXid(xid); 98 FreeXid(xid);
99 cifs_put_tlink(tlink);
94#endif 100#endif
95 return rc; 101 return rc;
96} 102}
@@ -102,9 +108,11 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
102#ifdef CONFIG_CIFS_XATTR 108#ifdef CONFIG_CIFS_XATTR
103 int xid; 109 int xid;
104 struct cifs_sb_info *cifs_sb; 110 struct cifs_sb_info *cifs_sb;
105 struct cifsTconInfo *pTcon; 111 struct tcon_link *tlink;
112 struct cifs_tcon *pTcon;
106 struct super_block *sb; 113 struct super_block *sb;
107 char *full_path; 114 char *full_path;
115 struct cifs_ntsd *pacl;
108 116
109 if (direntry == NULL) 117 if (direntry == NULL)
110 return -EIO; 118 return -EIO;
@@ -113,16 +121,19 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
113 sb = direntry->d_inode->i_sb; 121 sb = direntry->d_inode->i_sb;
114 if (sb == NULL) 122 if (sb == NULL)
115 return -EIO; 123 return -EIO;
116 xid = GetXid();
117 124
118 cifs_sb = CIFS_SB(sb); 125 cifs_sb = CIFS_SB(sb);
119 pTcon = cifs_sb->tcon; 126 tlink = cifs_sb_tlink(cifs_sb);
127 if (IS_ERR(tlink))
128 return PTR_ERR(tlink);
129 pTcon = tlink_tcon(tlink);
130
131 xid = GetXid();
120 132
121 full_path = build_path_from_dentry(direntry); 133 full_path = build_path_from_dentry(direntry);
122 if (full_path == NULL) { 134 if (full_path == NULL) {
123 rc = -ENOMEM; 135 rc = -ENOMEM;
124 FreeXid(xid); 136 goto set_ea_exit;
125 return rc;
126 } 137 }
127 /* return dos attributes as pseudo xattr */ 138 /* return dos attributes as pseudo xattr */
128 /* return alt name if available as pseudo attr */ 139 /* return alt name if available as pseudo attr */
@@ -132,9 +143,8 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
132 returns as xattrs */ 143 returns as xattrs */
133 if (value_size > MAX_EA_VALUE_SIZE) { 144 if (value_size > MAX_EA_VALUE_SIZE) {
134 cFYI(1, "size of EA value too large"); 145 cFYI(1, "size of EA value too large");
135 kfree(full_path); 146 rc = -EOPNOTSUPP;
136 FreeXid(xid); 147 goto set_ea_exit;
137 return -EOPNOTSUPP;
138 } 148 }
139 149
140 if (ea_name == NULL) { 150 if (ea_name == NULL) {
@@ -157,6 +167,25 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
157 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value, 167 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
158 (__u16)value_size, cifs_sb->local_nls, 168 (__u16)value_size, cifs_sb->local_nls,
159 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 169 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
170 } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
171 strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
172 pacl = kmalloc(value_size, GFP_KERNEL);
173 if (!pacl) {
174 cFYI(1, "%s: Can't allocate memory for ACL",
175 __func__);
176 rc = -ENOMEM;
177 } else {
178#ifdef CONFIG_CIFS_ACL
179 memcpy(pacl, ea_value, value_size);
180 rc = set_cifs_acl(pacl, value_size,
181 direntry->d_inode, full_path);
182 if (rc == 0) /* force revalidate of the inode */
183 CIFS_I(direntry->d_inode)->time = 0;
184 kfree(pacl);
185#else
186 cFYI(1, "Set CIFS ACL not supported yet");
187#endif /* CONFIG_CIFS_ACL */
188 }
160 } else { 189 } else {
161 int temp; 190 int temp;
162 temp = strncmp(ea_name, POSIX_ACL_XATTR_ACCESS, 191 temp = strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,
@@ -198,6 +227,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
198set_ea_exit: 227set_ea_exit:
199 kfree(full_path); 228 kfree(full_path);
200 FreeXid(xid); 229 FreeXid(xid);
230 cifs_put_tlink(tlink);
201#endif 231#endif
202 return rc; 232 return rc;
203} 233}
@@ -209,7 +239,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
209#ifdef CONFIG_CIFS_XATTR 239#ifdef CONFIG_CIFS_XATTR
210 int xid; 240 int xid;
211 struct cifs_sb_info *cifs_sb; 241 struct cifs_sb_info *cifs_sb;
212 struct cifsTconInfo *pTcon; 242 struct tcon_link *tlink;
243 struct cifs_tcon *pTcon;
213 struct super_block *sb; 244 struct super_block *sb;
214 char *full_path; 245 char *full_path;
215 246
@@ -221,16 +252,18 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
221 if (sb == NULL) 252 if (sb == NULL)
222 return -EIO; 253 return -EIO;
223 254
224 xid = GetXid();
225
226 cifs_sb = CIFS_SB(sb); 255 cifs_sb = CIFS_SB(sb);
227 pTcon = cifs_sb->tcon; 256 tlink = cifs_sb_tlink(cifs_sb);
257 if (IS_ERR(tlink))
258 return PTR_ERR(tlink);
259 pTcon = tlink_tcon(tlink);
260
261 xid = GetXid();
228 262
229 full_path = build_path_from_dentry(direntry); 263 full_path = build_path_from_dentry(direntry);
230 if (full_path == NULL) { 264 if (full_path == NULL) {
231 rc = -ENOMEM; 265 rc = -ENOMEM;
232 FreeXid(xid); 266 goto get_ea_exit;
233 return rc;
234 } 267 }
235 /* return dos attributes as pseudo xattr */ 268 /* return dos attributes as pseudo xattr */
236 /* return alt name if available as pseudo attr */ 269 /* return alt name if available as pseudo attr */
@@ -265,29 +298,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
265 cifs_sb->local_nls, 298 cifs_sb->local_nls,
266 cifs_sb->mnt_cifs_flags & 299 cifs_sb->mnt_cifs_flags &
267 CIFS_MOUNT_MAP_SPECIAL_CHR); 300 CIFS_MOUNT_MAP_SPECIAL_CHR);
268#ifdef CONFIG_CIFS_EXPERIMENTAL
269 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
270 __u16 fid;
271 int oplock = 0;
272 struct cifs_ntsd *pacl = NULL;
273 __u32 buflen = 0;
274 if (experimEnabled)
275 rc = CIFSSMBOpen(xid, pTcon, full_path,
276 FILE_OPEN, GENERIC_READ, 0, &fid,
277 &oplock, NULL, cifs_sb->local_nls,
278 cifs_sb->mnt_cifs_flags &
279 CIFS_MOUNT_MAP_SPECIAL_CHR);
280 /* else rc is EOPNOTSUPP from above */
281
282 if (rc == 0) {
283 rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &pacl,
284 &buflen);
285 CIFSSMBClose(xid, pTcon, fid);
286 }
287 }
288#endif /* EXPERIMENTAL */
289#else 301#else
290 cFYI(1, "query POSIX ACL not supported yet"); 302 cFYI(1, "Query POSIX ACL not supported yet");
291#endif /* CONFIG_CIFS_POSIX */ 303#endif /* CONFIG_CIFS_POSIX */
292 } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT, 304 } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
293 strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { 305 strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
@@ -299,8 +311,33 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
299 cifs_sb->mnt_cifs_flags & 311 cifs_sb->mnt_cifs_flags &
300 CIFS_MOUNT_MAP_SPECIAL_CHR); 312 CIFS_MOUNT_MAP_SPECIAL_CHR);
301#else 313#else
302 cFYI(1, "query POSIX default ACL not supported yet"); 314 cFYI(1, "Query POSIX default ACL not supported yet");
303#endif 315#endif /* CONFIG_CIFS_POSIX */
316 } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
317 strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
318#ifdef CONFIG_CIFS_ACL
319 u32 acllen;
320 struct cifs_ntsd *pacl;
321
322 pacl = get_cifs_acl(cifs_sb, direntry->d_inode,
323 full_path, &acllen);
324 if (IS_ERR(pacl)) {
325 rc = PTR_ERR(pacl);
326 cERROR(1, "%s: error %zd getting sec desc",
327 __func__, rc);
328 } else {
329 if (ea_value) {
330 if (acllen > buf_size)
331 acllen = -ERANGE;
332 else
333 memcpy(ea_value, pacl, acllen);
334 }
335 rc = acllen;
336 kfree(pacl);
337 }
338#else
339 cFYI(1, "Query CIFS ACL not supported yet");
340#endif /* CONFIG_CIFS_ACL */
304 } else if (strncmp(ea_name, 341 } else if (strncmp(ea_name,
305 CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) { 342 CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
306 cFYI(1, "Trusted xattr namespace not supported yet"); 343 cFYI(1, "Trusted xattr namespace not supported yet");
@@ -323,6 +360,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
323get_ea_exit: 360get_ea_exit:
324 kfree(full_path); 361 kfree(full_path);
325 FreeXid(xid); 362 FreeXid(xid);
363 cifs_put_tlink(tlink);
326#endif 364#endif
327 return rc; 365 return rc;
328} 366}
@@ -333,7 +371,8 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
333#ifdef CONFIG_CIFS_XATTR 371#ifdef CONFIG_CIFS_XATTR
334 int xid; 372 int xid;
335 struct cifs_sb_info *cifs_sb; 373 struct cifs_sb_info *cifs_sb;
336 struct cifsTconInfo *pTcon; 374 struct tcon_link *tlink;
375 struct cifs_tcon *pTcon;
337 struct super_block *sb; 376 struct super_block *sb;
338 char *full_path; 377 char *full_path;
339 378
@@ -346,18 +385,20 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
346 return -EIO; 385 return -EIO;
347 386
348 cifs_sb = CIFS_SB(sb); 387 cifs_sb = CIFS_SB(sb);
349 pTcon = cifs_sb->tcon;
350
351 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 388 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
352 return -EOPNOTSUPP; 389 return -EOPNOTSUPP;
353 390
391 tlink = cifs_sb_tlink(cifs_sb);
392 if (IS_ERR(tlink))
393 return PTR_ERR(tlink);
394 pTcon = tlink_tcon(tlink);
395
354 xid = GetXid(); 396 xid = GetXid();
355 397
356 full_path = build_path_from_dentry(direntry); 398 full_path = build_path_from_dentry(direntry);
357 if (full_path == NULL) { 399 if (full_path == NULL) {
358 rc = -ENOMEM; 400 rc = -ENOMEM;
359 FreeXid(xid); 401 goto list_ea_exit;
360 return rc;
361 } 402 }
362 /* return dos attributes as pseudo xattr */ 403 /* return dos attributes as pseudo xattr */
363 /* return alt name if available as pseudo attr */ 404 /* return alt name if available as pseudo attr */
@@ -370,8 +411,10 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
370 cifs_sb->mnt_cifs_flags & 411 cifs_sb->mnt_cifs_flags &
371 CIFS_MOUNT_MAP_SPECIAL_CHR); 412 CIFS_MOUNT_MAP_SPECIAL_CHR);
372 413
414list_ea_exit:
373 kfree(full_path); 415 kfree(full_path);
374 FreeXid(xid); 416 FreeXid(xid);
417 cifs_put_tlink(tlink);
375#endif 418#endif
376 return rc; 419 return rc;
377} 420}