Merge tag 'platform-drivers-x86-v5.14-3' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / fs / cifs / xattr.c
1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3  *   fs/cifs/xattr.c
4  *
5  *   Copyright (c) International Business Machines  Corp., 2003, 2007
6  *   Author(s): Steve French (sfrench@us.ibm.com)
7  *
8  */
9
10 #include <linux/fs.h>
11 #include <linux/posix_acl_xattr.h>
12 #include <linux/slab.h>
13 #include <linux/xattr.h>
14 #include "cifsfs.h"
15 #include "cifspdu.h"
16 #include "cifsglob.h"
17 #include "cifsproto.h"
18 #include "cifs_debug.h"
19 #include "cifs_fs_sb.h"
20 #include "cifs_unicode.h"
21 #include "cifs_ioctl.h"
22
23 #define MAX_EA_VALUE_SIZE CIFSMaxBufSize
24 #define CIFS_XATTR_CIFS_ACL "system.cifs_acl" /* DACL only */
25 #define CIFS_XATTR_CIFS_NTSD "system.cifs_ntsd" /* owner plus DACL */
26 #define CIFS_XATTR_CIFS_NTSD_FULL "system.cifs_ntsd_full" /* owner/DACL/SACL */
27 #define CIFS_XATTR_ATTRIB "cifs.dosattrib"  /* full name: user.cifs.dosattrib */
28 #define CIFS_XATTR_CREATETIME "cifs.creationtime"  /* user.cifs.creationtime */
29 /*
30  * Although these three are just aliases for the above, need to move away from
31  * confusing users and using the 20+ year old term 'cifs' when it is no longer
32  * secure, replaced by SMB2 (then even more highly secure SMB3) many years ago
33  */
34 #define SMB3_XATTR_CIFS_ACL "system.smb3_acl" /* DACL only */
35 #define SMB3_XATTR_CIFS_NTSD "system.smb3_ntsd" /* owner plus DACL */
36 #define SMB3_XATTR_CIFS_NTSD_FULL "system.smb3_ntsd_full" /* owner/DACL/SACL */
37 #define SMB3_XATTR_ATTRIB "smb3.dosattrib"  /* full name: user.smb3.dosattrib */
38 #define SMB3_XATTR_CREATETIME "smb3.creationtime"  /* user.smb3.creationtime */
39 /* BB need to add server (Samba e.g) support for security and trusted prefix */
40
41 enum { XATTR_USER, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT,
42         XATTR_CIFS_NTSD, XATTR_CIFS_NTSD_FULL };
43
44 static int cifs_attrib_set(unsigned int xid, struct cifs_tcon *pTcon,
45                            struct inode *inode, const char *full_path,
46                            const void *value, size_t size)
47 {
48         ssize_t rc = -EOPNOTSUPP;
49         __u32 *pattrib = (__u32 *)value;
50         __u32 attrib;
51         FILE_BASIC_INFO info_buf;
52
53         if ((value == NULL) || (size != sizeof(__u32)))
54                 return -ERANGE;
55
56         memset(&info_buf, 0, sizeof(info_buf));
57         attrib = *pattrib;
58         info_buf.Attributes = cpu_to_le32(attrib);
59         if (pTcon->ses->server->ops->set_file_info)
60                 rc = pTcon->ses->server->ops->set_file_info(inode, full_path,
61                                 &info_buf, xid);
62         if (rc == 0)
63                 CIFS_I(inode)->cifsAttrs = attrib;
64
65         return rc;
66 }
67
68 static int cifs_creation_time_set(unsigned int xid, struct cifs_tcon *pTcon,
69                                   struct inode *inode, const char *full_path,
70                                   const void *value, size_t size)
71 {
72         ssize_t rc = -EOPNOTSUPP;
73         __u64 *pcreation_time = (__u64 *)value;
74         __u64 creation_time;
75         FILE_BASIC_INFO info_buf;
76
77         if ((value == NULL) || (size != sizeof(__u64)))
78                 return -ERANGE;
79
80         memset(&info_buf, 0, sizeof(info_buf));
81         creation_time = *pcreation_time;
82         info_buf.CreationTime = cpu_to_le64(creation_time);
83         if (pTcon->ses->server->ops->set_file_info)
84                 rc = pTcon->ses->server->ops->set_file_info(inode, full_path,
85                                 &info_buf, xid);
86         if (rc == 0)
87                 CIFS_I(inode)->createtime = creation_time;
88
89         return rc;
90 }
91
92 static int cifs_xattr_set(const struct xattr_handler *handler,
93                           struct user_namespace *mnt_userns,
94                           struct dentry *dentry, struct inode *inode,
95                           const char *name, const void *value,
96                           size_t size, int flags)
97 {
98         int rc = -EOPNOTSUPP;
99         unsigned int xid;
100         struct super_block *sb = dentry->d_sb;
101         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
102         struct tcon_link *tlink;
103         struct cifs_tcon *pTcon;
104         const char *full_path;
105         void *page;
106
107         tlink = cifs_sb_tlink(cifs_sb);
108         if (IS_ERR(tlink))
109                 return PTR_ERR(tlink);
110         pTcon = tlink_tcon(tlink);
111
112         xid = get_xid();
113         page = alloc_dentry_path();
114
115         full_path = build_path_from_dentry(dentry, page);
116         if (IS_ERR(full_path)) {
117                 rc = PTR_ERR(full_path);
118                 goto out;
119         }
120         /* return dos attributes as pseudo xattr */
121         /* return alt name if available as pseudo attr */
122
123         /* if proc/fs/cifs/streamstoxattr is set then
124                 search server for EAs or streams to
125                 returns as xattrs */
126         if (size > MAX_EA_VALUE_SIZE) {
127                 cifs_dbg(FYI, "size of EA value too large\n");
128                 rc = -EOPNOTSUPP;
129                 goto out;
130         }
131
132         switch (handler->flags) {
133         case XATTR_USER:
134                 cifs_dbg(FYI, "%s:setting user xattr %s\n", __func__, name);
135                 if ((strcmp(name, CIFS_XATTR_ATTRIB) == 0) ||
136                     (strcmp(name, SMB3_XATTR_ATTRIB) == 0)) {
137                         rc = cifs_attrib_set(xid, pTcon, inode, full_path,
138                                         value, size);
139                         if (rc == 0) /* force revalidate of the inode */
140                                 CIFS_I(inode)->time = 0;
141                         break;
142                 } else if ((strcmp(name, CIFS_XATTR_CREATETIME) == 0) ||
143                            (strcmp(name, SMB3_XATTR_CREATETIME) == 0)) {
144                         rc = cifs_creation_time_set(xid, pTcon, inode,
145                                         full_path, value, size);
146                         if (rc == 0) /* force revalidate of the inode */
147                                 CIFS_I(inode)->time = 0;
148                         break;
149                 }
150
151                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
152                         goto out;
153
154                 if (pTcon->ses->server->ops->set_EA)
155                         rc = pTcon->ses->server->ops->set_EA(xid, pTcon,
156                                 full_path, name, value, (__u16)size,
157                                 cifs_sb->local_nls, cifs_sb);
158                 break;
159
160         case XATTR_CIFS_ACL:
161         case XATTR_CIFS_NTSD:
162         case XATTR_CIFS_NTSD_FULL: {
163                 struct cifs_ntsd *pacl;
164
165                 if (!value)
166                         goto out;
167                 pacl = kmalloc(size, GFP_KERNEL);
168                 if (!pacl) {
169                         rc = -ENOMEM;
170                 } else {
171                         memcpy(pacl, value, size);
172                         if (pTcon->ses->server->ops->set_acl) {
173                                 int aclflags = 0;
174                                 rc = 0;
175
176                                 switch (handler->flags) {
177                                 case XATTR_CIFS_NTSD_FULL:
178                                         aclflags = (CIFS_ACL_OWNER |
179                                                     CIFS_ACL_DACL |
180                                                     CIFS_ACL_SACL);
181                                         break;
182                                 case XATTR_CIFS_NTSD:
183                                         aclflags = (CIFS_ACL_OWNER |
184                                                     CIFS_ACL_DACL);
185                                         break;
186                                 case XATTR_CIFS_ACL:
187                                 default:
188                                         aclflags = CIFS_ACL_DACL;
189                                 }
190
191                                 rc = pTcon->ses->server->ops->set_acl(pacl,
192                                         size, inode, full_path, aclflags);
193                         } else {
194                                 rc = -EOPNOTSUPP;
195                         }
196                         if (rc == 0) /* force revalidate of the inode */
197                                 CIFS_I(inode)->time = 0;
198                         kfree(pacl);
199                 }
200                 break;
201         }
202
203         case XATTR_ACL_ACCESS:
204 #ifdef CONFIG_CIFS_POSIX
205                 if (!value)
206                         goto out;
207                 if (sb->s_flags & SB_POSIXACL)
208                         rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
209                                 value, (const int)size,
210                                 ACL_TYPE_ACCESS, cifs_sb->local_nls,
211                                 cifs_remap(cifs_sb));
212 #endif  /* CONFIG_CIFS_POSIX */
213                 break;
214
215         case XATTR_ACL_DEFAULT:
216 #ifdef CONFIG_CIFS_POSIX
217                 if (!value)
218                         goto out;
219                 if (sb->s_flags & SB_POSIXACL)
220                         rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
221                                 value, (const int)size,
222                                 ACL_TYPE_DEFAULT, cifs_sb->local_nls,
223                                 cifs_remap(cifs_sb));
224 #endif  /* CONFIG_CIFS_POSIX */
225                 break;
226         }
227
228 out:
229         free_dentry_path(page);
230         free_xid(xid);
231         cifs_put_tlink(tlink);
232         return rc;
233 }
234
235 static int cifs_attrib_get(struct dentry *dentry,
236                            struct inode *inode, void *value,
237                            size_t size)
238 {
239         ssize_t rc;
240         __u32 *pattribute;
241
242         rc = cifs_revalidate_dentry_attr(dentry);
243
244         if (rc)
245                 return rc;
246
247         if ((value == NULL) || (size == 0))
248                 return sizeof(__u32);
249         else if (size < sizeof(__u32))
250                 return -ERANGE;
251
252         /* return dos attributes as pseudo xattr */
253         pattribute = (__u32 *)value;
254         *pattribute = CIFS_I(inode)->cifsAttrs;
255
256         return sizeof(__u32);
257 }
258
259 static int cifs_creation_time_get(struct dentry *dentry, struct inode *inode,
260                                   void *value, size_t size)
261 {
262         ssize_t rc;
263         __u64 *pcreatetime;
264
265         rc = cifs_revalidate_dentry_attr(dentry);
266         if (rc)
267                 return rc;
268
269         if ((value == NULL) || (size == 0))
270                 return sizeof(__u64);
271         else if (size < sizeof(__u64))
272                 return -ERANGE;
273
274         /* return dos attributes as pseudo xattr */
275         pcreatetime = (__u64 *)value;
276         *pcreatetime = CIFS_I(inode)->createtime;
277         return sizeof(__u64);
278 }
279
280
281 static int cifs_xattr_get(const struct xattr_handler *handler,
282                           struct dentry *dentry, struct inode *inode,
283                           const char *name, void *value, size_t size)
284 {
285         ssize_t rc = -EOPNOTSUPP;
286         unsigned int xid;
287         struct super_block *sb = dentry->d_sb;
288         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
289         struct tcon_link *tlink;
290         struct cifs_tcon *pTcon;
291         const char *full_path;
292         void *page;
293
294         tlink = cifs_sb_tlink(cifs_sb);
295         if (IS_ERR(tlink))
296                 return PTR_ERR(tlink);
297         pTcon = tlink_tcon(tlink);
298
299         xid = get_xid();
300         page = alloc_dentry_path();
301
302         full_path = build_path_from_dentry(dentry, page);
303         if (IS_ERR(full_path)) {
304                 rc = PTR_ERR(full_path);
305                 goto out;
306         }
307
308         /* return alt name if available as pseudo attr */
309         switch (handler->flags) {
310         case XATTR_USER:
311                 cifs_dbg(FYI, "%s:querying user xattr %s\n", __func__, name);
312                 if ((strcmp(name, CIFS_XATTR_ATTRIB) == 0) ||
313                     (strcmp(name, SMB3_XATTR_ATTRIB) == 0)) {
314                         rc = cifs_attrib_get(dentry, inode, value, size);
315                         break;
316                 } else if ((strcmp(name, CIFS_XATTR_CREATETIME) == 0) ||
317                     (strcmp(name, SMB3_XATTR_CREATETIME) == 0)) {
318                         rc = cifs_creation_time_get(dentry, inode, value, size);
319                         break;
320                 }
321
322                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
323                         goto out;
324
325                 if (pTcon->ses->server->ops->query_all_EAs)
326                         rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon,
327                                 full_path, name, value, size, cifs_sb);
328                 break;
329
330         case XATTR_CIFS_ACL:
331         case XATTR_CIFS_NTSD:
332         case XATTR_CIFS_NTSD_FULL: {
333                 /*
334                  * fetch owner, DACL, and SACL if asked for full descriptor,
335                  * fetch owner and DACL otherwise
336                  */
337                 u32 acllen, extra_info;
338                 struct cifs_ntsd *pacl;
339
340                 if (pTcon->ses->server->ops->get_acl == NULL)
341                         goto out; /* rc already EOPNOTSUPP */
342
343                 if (handler->flags == XATTR_CIFS_NTSD_FULL) {
344                         extra_info = SACL_SECINFO;
345                 } else {
346                         extra_info = 0;
347                 }
348                 pacl = pTcon->ses->server->ops->get_acl(cifs_sb,
349                                 inode, full_path, &acllen, extra_info);
350                 if (IS_ERR(pacl)) {
351                         rc = PTR_ERR(pacl);
352                         cifs_dbg(VFS, "%s: error %zd getting sec desc\n",
353                                  __func__, rc);
354                 } else {
355                         if (value) {
356                                 if (acllen > size)
357                                         acllen = -ERANGE;
358                                 else
359                                         memcpy(value, pacl, acllen);
360                         }
361                         rc = acllen;
362                         kfree(pacl);
363                 }
364                 break;
365         }
366
367         case XATTR_ACL_ACCESS:
368 #ifdef CONFIG_CIFS_POSIX
369                 if (sb->s_flags & SB_POSIXACL)
370                         rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
371                                 value, size, ACL_TYPE_ACCESS,
372                                 cifs_sb->local_nls,
373                                 cifs_remap(cifs_sb));
374 #endif  /* CONFIG_CIFS_POSIX */
375                 break;
376
377         case XATTR_ACL_DEFAULT:
378 #ifdef CONFIG_CIFS_POSIX
379                 if (sb->s_flags & SB_POSIXACL)
380                         rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
381                                 value, size, ACL_TYPE_DEFAULT,
382                                 cifs_sb->local_nls,
383                                 cifs_remap(cifs_sb));
384 #endif  /* CONFIG_CIFS_POSIX */
385                 break;
386         }
387
388         /* We could add an additional check for streams ie
389             if proc/fs/cifs/streamstoxattr is set then
390                 search server for EAs or streams to
391                 returns as xattrs */
392
393         if (rc == -EINVAL)
394                 rc = -EOPNOTSUPP;
395
396 out:
397         free_dentry_path(page);
398         free_xid(xid);
399         cifs_put_tlink(tlink);
400         return rc;
401 }
402
403 ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
404 {
405         ssize_t rc = -EOPNOTSUPP;
406         unsigned int xid;
407         struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
408         struct tcon_link *tlink;
409         struct cifs_tcon *pTcon;
410         const char *full_path;
411         void *page;
412
413         if (unlikely(cifs_forced_shutdown(cifs_sb)))
414                 return -EIO;
415
416         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
417                 return -EOPNOTSUPP;
418
419         tlink = cifs_sb_tlink(cifs_sb);
420         if (IS_ERR(tlink))
421                 return PTR_ERR(tlink);
422         pTcon = tlink_tcon(tlink);
423
424         xid = get_xid();
425         page = alloc_dentry_path();
426
427         full_path = build_path_from_dentry(direntry, page);
428         if (IS_ERR(full_path)) {
429                 rc = PTR_ERR(full_path);
430                 goto list_ea_exit;
431         }
432         /* return dos attributes as pseudo xattr */
433         /* return alt name if available as pseudo attr */
434
435         /* if proc/fs/cifs/streamstoxattr is set then
436                 search server for EAs or streams to
437                 returns as xattrs */
438
439         if (pTcon->ses->server->ops->query_all_EAs)
440                 rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon,
441                                 full_path, NULL, data, buf_size, cifs_sb);
442 list_ea_exit:
443         free_dentry_path(page);
444         free_xid(xid);
445         cifs_put_tlink(tlink);
446         return rc;
447 }
448
449 static const struct xattr_handler cifs_user_xattr_handler = {
450         .prefix = XATTR_USER_PREFIX,
451         .flags = XATTR_USER,
452         .get = cifs_xattr_get,
453         .set = cifs_xattr_set,
454 };
455
456 /* os2.* attributes are treated like user.* attributes */
457 static const struct xattr_handler cifs_os2_xattr_handler = {
458         .prefix = XATTR_OS2_PREFIX,
459         .flags = XATTR_USER,
460         .get = cifs_xattr_get,
461         .set = cifs_xattr_set,
462 };
463
464 static const struct xattr_handler cifs_cifs_acl_xattr_handler = {
465         .name = CIFS_XATTR_CIFS_ACL,
466         .flags = XATTR_CIFS_ACL,
467         .get = cifs_xattr_get,
468         .set = cifs_xattr_set,
469 };
470
471 /*
472  * Although this is just an alias for the above, need to move away from
473  * confusing users and using the 20 year old term 'cifs' when it is no
474  * longer secure and was replaced by SMB2/SMB3 a long time ago, and
475  * SMB3 and later are highly secure.
476  */
477 static const struct xattr_handler smb3_acl_xattr_handler = {
478         .name = SMB3_XATTR_CIFS_ACL,
479         .flags = XATTR_CIFS_ACL,
480         .get = cifs_xattr_get,
481         .set = cifs_xattr_set,
482 };
483
484 static const struct xattr_handler cifs_cifs_ntsd_xattr_handler = {
485         .name = CIFS_XATTR_CIFS_NTSD,
486         .flags = XATTR_CIFS_NTSD,
487         .get = cifs_xattr_get,
488         .set = cifs_xattr_set,
489 };
490
491 /*
492  * Although this is just an alias for the above, need to move away from
493  * confusing users and using the 20 year old term 'cifs' when it is no
494  * longer secure and was replaced by SMB2/SMB3 a long time ago, and
495  * SMB3 and later are highly secure.
496  */
497 static const struct xattr_handler smb3_ntsd_xattr_handler = {
498         .name = SMB3_XATTR_CIFS_NTSD,
499         .flags = XATTR_CIFS_NTSD,
500         .get = cifs_xattr_get,
501         .set = cifs_xattr_set,
502 };
503
504 static const struct xattr_handler cifs_cifs_ntsd_full_xattr_handler = {
505         .name = CIFS_XATTR_CIFS_NTSD_FULL,
506         .flags = XATTR_CIFS_NTSD_FULL,
507         .get = cifs_xattr_get,
508         .set = cifs_xattr_set,
509 };
510
511 /*
512  * Although this is just an alias for the above, need to move away from
513  * confusing users and using the 20 year old term 'cifs' when it is no
514  * longer secure and was replaced by SMB2/SMB3 a long time ago, and
515  * SMB3 and later are highly secure.
516  */
517 static const struct xattr_handler smb3_ntsd_full_xattr_handler = {
518         .name = SMB3_XATTR_CIFS_NTSD_FULL,
519         .flags = XATTR_CIFS_NTSD_FULL,
520         .get = cifs_xattr_get,
521         .set = cifs_xattr_set,
522 };
523
524
525 static const struct xattr_handler cifs_posix_acl_access_xattr_handler = {
526         .name = XATTR_NAME_POSIX_ACL_ACCESS,
527         .flags = XATTR_ACL_ACCESS,
528         .get = cifs_xattr_get,
529         .set = cifs_xattr_set,
530 };
531
532 static const struct xattr_handler cifs_posix_acl_default_xattr_handler = {
533         .name = XATTR_NAME_POSIX_ACL_DEFAULT,
534         .flags = XATTR_ACL_DEFAULT,
535         .get = cifs_xattr_get,
536         .set = cifs_xattr_set,
537 };
538
539 const struct xattr_handler *cifs_xattr_handlers[] = {
540         &cifs_user_xattr_handler,
541         &cifs_os2_xattr_handler,
542         &cifs_cifs_acl_xattr_handler,
543         &smb3_acl_xattr_handler, /* alias for above since avoiding "cifs" */
544         &cifs_cifs_ntsd_xattr_handler,
545         &smb3_ntsd_xattr_handler, /* alias for above since avoiding "cifs" */
546         &cifs_cifs_ntsd_full_xattr_handler,
547         &smb3_ntsd_full_xattr_handler, /* alias for above since avoiding "cifs" */
548         &cifs_posix_acl_access_xattr_handler,
549         &cifs_posix_acl_default_xattr_handler,
550         NULL
551 };