~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/smb/client/cifsacl.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: LGPL-2.1
  2 /*
  3  *
  4  *   Copyright (C) International Business Machines  Corp., 2007,2008
  5  *   Author(s): Steve French (sfrench@us.ibm.com)
  6  *
  7  *   Contains the routines for mapping CIFS/NTFS ACLs
  8  *
  9  */
 10 
 11 #include <linux/fs.h>
 12 #include <linux/slab.h>
 13 #include <linux/string.h>
 14 #include <linux/keyctl.h>
 15 #include <linux/key-type.h>
 16 #include <uapi/linux/posix_acl.h>
 17 #include <linux/posix_acl.h>
 18 #include <linux/posix_acl_xattr.h>
 19 #include <keys/user-type.h>
 20 #include "cifspdu.h"
 21 #include "cifsglob.h"
 22 #include "cifsacl.h"
 23 #include "cifsproto.h"
 24 #include "cifs_debug.h"
 25 #include "fs_context.h"
 26 #include "cifs_fs_sb.h"
 27 #include "cifs_unicode.h"
 28 
 29 /* security id for everyone/world system group */
 30 static const struct cifs_sid sid_everyone = {
 31         1, 1, {0, 0, 0, 0, 0, 1}, {0} };
 32 /* security id for Authenticated Users system group */
 33 static const struct cifs_sid sid_authusers = {
 34         1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
 35 
 36 /* S-1-22-1 Unmapped Unix users */
 37 static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
 38                 {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
 39 
 40 /* S-1-22-2 Unmapped Unix groups */
 41 static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
 42                 {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
 43 
 44 /*
 45  * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
 46  */
 47 
 48 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
 49 
 50 /* S-1-5-88-1 Unix uid */
 51 static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
 52         {cpu_to_le32(88),
 53          cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
 54 
 55 /* S-1-5-88-2 Unix gid */
 56 static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
 57         {cpu_to_le32(88),
 58          cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
 59 
 60 /* S-1-5-88-3 Unix mode */
 61 static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
 62         {cpu_to_le32(88),
 63          cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
 64 
 65 static const struct cred *root_cred;
 66 
 67 static int
 68 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
 69 {
 70         char *payload;
 71 
 72         /*
 73          * If the payload is less than or equal to the size of a pointer, then
 74          * an allocation here is wasteful. Just copy the data directly to the
 75          * payload.value union member instead.
 76          *
 77          * With this however, you must check the datalen before trying to
 78          * dereference payload.data!
 79          */
 80         if (prep->datalen <= sizeof(key->payload)) {
 81                 key->payload.data[0] = NULL;
 82                 memcpy(&key->payload, prep->data, prep->datalen);
 83         } else {
 84                 payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
 85                 if (!payload)
 86                         return -ENOMEM;
 87                 key->payload.data[0] = payload;
 88         }
 89 
 90         key->datalen = prep->datalen;
 91         return 0;
 92 }
 93 
 94 static inline void
 95 cifs_idmap_key_destroy(struct key *key)
 96 {
 97         if (key->datalen > sizeof(key->payload))
 98                 kfree(key->payload.data[0]);
 99 }
100 
101 static struct key_type cifs_idmap_key_type = {
102         .name        = "cifs.idmap",
103         .instantiate = cifs_idmap_key_instantiate,
104         .destroy     = cifs_idmap_key_destroy,
105         .describe    = user_describe,
106 };
107 
108 static char *
109 sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
110 {
111         int i, len;
112         unsigned int saval;
113         char *sidstr, *strptr;
114         unsigned long long id_auth_val;
115 
116         /* 3 bytes for prefix */
117         sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
118                          (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
119                          GFP_KERNEL);
120         if (!sidstr)
121                 return sidstr;
122 
123         strptr = sidstr;
124         len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
125                         sidptr->revision);
126         strptr += len;
127 
128         /* The authority field is a single 48-bit number */
129         id_auth_val = (unsigned long long)sidptr->authority[5];
130         id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
131         id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
132         id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
133         id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
134         id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
135 
136         /*
137          * MS-DTYP states that if the authority is >= 2^32, then it should be
138          * expressed as a hex value.
139          */
140         if (id_auth_val <= UINT_MAX)
141                 len = sprintf(strptr, "-%llu", id_auth_val);
142         else
143                 len = sprintf(strptr, "-0x%llx", id_auth_val);
144 
145         strptr += len;
146 
147         for (i = 0; i < sidptr->num_subauth; ++i) {
148                 saval = le32_to_cpu(sidptr->sub_auth[i]);
149                 len = sprintf(strptr, "-%u", saval);
150                 strptr += len;
151         }
152 
153         return sidstr;
154 }
155 
156 /*
157  * if the two SIDs (roughly equivalent to a UUID for a user or group) are
158  * the same returns zero, if they do not match returns non-zero.
159  */
160 static int
161 compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
162 {
163         int i;
164         int num_subauth, num_sat, num_saw;
165 
166         if ((!ctsid) || (!cwsid))
167                 return 1;
168 
169         /* compare the revision */
170         if (ctsid->revision != cwsid->revision) {
171                 if (ctsid->revision > cwsid->revision)
172                         return 1;
173                 else
174                         return -1;
175         }
176 
177         /* compare all of the six auth values */
178         for (i = 0; i < NUM_AUTHS; ++i) {
179                 if (ctsid->authority[i] != cwsid->authority[i]) {
180                         if (ctsid->authority[i] > cwsid->authority[i])
181                                 return 1;
182                         else
183                                 return -1;
184                 }
185         }
186 
187         /* compare all of the subauth values if any */
188         num_sat = ctsid->num_subauth;
189         num_saw = cwsid->num_subauth;
190         num_subauth = num_sat < num_saw ? num_sat : num_saw;
191         if (num_subauth) {
192                 for (i = 0; i < num_subauth; ++i) {
193                         if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
194                                 if (le32_to_cpu(ctsid->sub_auth[i]) >
195                                         le32_to_cpu(cwsid->sub_auth[i]))
196                                         return 1;
197                                 else
198                                         return -1;
199                         }
200                 }
201         }
202 
203         return 0; /* sids compare/match */
204 }
205 
206 static bool
207 is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
208 {
209         int i;
210         int num_subauth;
211         const struct cifs_sid *pwell_known_sid;
212 
213         if (!psid || (puid == NULL))
214                 return false;
215 
216         num_subauth = psid->num_subauth;
217 
218         /* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
219         if (num_subauth == 2) {
220                 if (is_group)
221                         pwell_known_sid = &sid_unix_groups;
222                 else
223                         pwell_known_sid = &sid_unix_users;
224         } else if (num_subauth == 3) {
225                 if (is_group)
226                         pwell_known_sid = &sid_unix_NFS_groups;
227                 else
228                         pwell_known_sid = &sid_unix_NFS_users;
229         } else
230                 return false;
231 
232         /* compare the revision */
233         if (psid->revision != pwell_known_sid->revision)
234                 return false;
235 
236         /* compare all of the six auth values */
237         for (i = 0; i < NUM_AUTHS; ++i) {
238                 if (psid->authority[i] != pwell_known_sid->authority[i]) {
239                         cifs_dbg(FYI, "auth %d did not match\n", i);
240                         return false;
241                 }
242         }
243 
244         if (num_subauth == 2) {
245                 if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
246                         return false;
247 
248                 *puid = le32_to_cpu(psid->sub_auth[1]);
249         } else /* 3 subauths, ie Windows/Mac style */ {
250                 *puid = le32_to_cpu(psid->sub_auth[0]);
251                 if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
252                     (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
253                         return false;
254 
255                 *puid = le32_to_cpu(psid->sub_auth[2]);
256         }
257 
258         cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
259         return true; /* well known sid found, uid returned */
260 }
261 
262 static __u16
263 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
264 {
265         int i;
266         __u16 size = 1 + 1 + 6;
267 
268         dst->revision = src->revision;
269         dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
270         for (i = 0; i < NUM_AUTHS; ++i)
271                 dst->authority[i] = src->authority[i];
272         for (i = 0; i < dst->num_subauth; ++i)
273                 dst->sub_auth[i] = src->sub_auth[i];
274         size += (dst->num_subauth * 4);
275 
276         return size;
277 }
278 
279 static int
280 id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
281 {
282         int rc;
283         struct key *sidkey;
284         struct cifs_sid *ksid;
285         unsigned int ksid_size;
286         char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
287         const struct cred *saved_cred;
288 
289         rc = snprintf(desc, sizeof(desc), "%ci:%u",
290                         sidtype == SIDOWNER ? 'o' : 'g', cid);
291         if (rc >= sizeof(desc))
292                 return -EINVAL;
293 
294         rc = 0;
295         saved_cred = override_creds(root_cred);
296         sidkey = request_key(&cifs_idmap_key_type, desc, "");
297         if (IS_ERR(sidkey)) {
298                 rc = -EINVAL;
299                 cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
300                          __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
301                 goto out_revert_creds;
302         } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
303                 rc = -EIO;
304                 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
305                          __func__, sidkey->datalen);
306                 goto invalidate_key;
307         }
308 
309         /*
310          * A sid is usually too large to be embedded in payload.value, but if
311          * there are no subauthorities and the host has 8-byte pointers, then
312          * it could be.
313          */
314         ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
315                 (struct cifs_sid *)&sidkey->payload :
316                 (struct cifs_sid *)sidkey->payload.data[0];
317 
318         ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
319         if (ksid_size > sidkey->datalen) {
320                 rc = -EIO;
321                 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
322                          __func__, sidkey->datalen, ksid_size);
323                 goto invalidate_key;
324         }
325 
326         cifs_copy_sid(ssid, ksid);
327 out_key_put:
328         key_put(sidkey);
329 out_revert_creds:
330         revert_creds(saved_cred);
331         return rc;
332 
333 invalidate_key:
334         key_invalidate(sidkey);
335         goto out_key_put;
336 }
337 
338 int
339 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
340                 struct cifs_fattr *fattr, uint sidtype)
341 {
342         int rc = 0;
343         struct key *sidkey;
344         char *sidstr;
345         const struct cred *saved_cred;
346         kuid_t fuid = cifs_sb->ctx->linux_uid;
347         kgid_t fgid = cifs_sb->ctx->linux_gid;
348 
349         /*
350          * If we have too many subauthorities, then something is really wrong.
351          * Just return an error.
352          */
353         if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
354                 cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
355                          __func__, psid->num_subauth);
356                 return -EIO;
357         }
358 
359         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
360             (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
361                 uint32_t unix_id;
362                 bool is_group;
363 
364                 if (sidtype != SIDOWNER)
365                         is_group = true;
366                 else
367                         is_group = false;
368 
369                 if (is_well_known_sid(psid, &unix_id, is_group) == false)
370                         goto try_upcall_to_get_id;
371 
372                 if (is_group) {
373                         kgid_t gid;
374                         gid_t id;
375 
376                         id = (gid_t)unix_id;
377                         gid = make_kgid(&init_user_ns, id);
378                         if (gid_valid(gid)) {
379                                 fgid = gid;
380                                 goto got_valid_id;
381                         }
382                 } else {
383                         kuid_t uid;
384                         uid_t id;
385 
386                         id = (uid_t)unix_id;
387                         uid = make_kuid(&init_user_ns, id);
388                         if (uid_valid(uid)) {
389                                 fuid = uid;
390                                 goto got_valid_id;
391                         }
392                 }
393                 /* If unable to find uid/gid easily from SID try via upcall */
394         }
395 
396 try_upcall_to_get_id:
397         sidstr = sid_to_key_str(psid, sidtype);
398         if (!sidstr)
399                 return -ENOMEM;
400 
401         saved_cred = override_creds(root_cred);
402         sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
403         if (IS_ERR(sidkey)) {
404                 cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
405                          __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
406                 goto out_revert_creds;
407         }
408 
409         /*
410          * FIXME: Here we assume that uid_t and gid_t are same size. It's
411          * probably a safe assumption but might be better to check based on
412          * sidtype.
413          */
414         BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
415         if (sidkey->datalen != sizeof(uid_t)) {
416                 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
417                          __func__, sidkey->datalen);
418                 key_invalidate(sidkey);
419                 goto out_key_put;
420         }
421 
422         if (sidtype == SIDOWNER) {
423                 kuid_t uid;
424                 uid_t id;
425                 memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
426                 uid = make_kuid(&init_user_ns, id);
427                 if (uid_valid(uid))
428                         fuid = uid;
429         } else {
430                 kgid_t gid;
431                 gid_t id;
432                 memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
433                 gid = make_kgid(&init_user_ns, id);
434                 if (gid_valid(gid))
435                         fgid = gid;
436         }
437 
438 out_key_put:
439         key_put(sidkey);
440 out_revert_creds:
441         revert_creds(saved_cred);
442         kfree(sidstr);
443 
444         /*
445          * Note that we return 0 here unconditionally. If the mapping
446          * fails then we just fall back to using the ctx->linux_uid/linux_gid.
447          */
448 got_valid_id:
449         rc = 0;
450         if (sidtype == SIDOWNER)
451                 fattr->cf_uid = fuid;
452         else
453                 fattr->cf_gid = fgid;
454         return rc;
455 }
456 
457 int
458 init_cifs_idmap(void)
459 {
460         struct cred *cred;
461         struct key *keyring;
462         int ret;
463 
464         cifs_dbg(FYI, "Registering the %s key type\n",
465                  cifs_idmap_key_type.name);
466 
467         /* create an override credential set with a special thread keyring in
468          * which requests are cached
469          *
470          * this is used to prevent malicious redirections from being installed
471          * with add_key().
472          */
473         cred = prepare_kernel_cred(&init_task);
474         if (!cred)
475                 return -ENOMEM;
476 
477         keyring = keyring_alloc(".cifs_idmap",
478                                 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
479                                 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
480                                 KEY_USR_VIEW | KEY_USR_READ,
481                                 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
482         if (IS_ERR(keyring)) {
483                 ret = PTR_ERR(keyring);
484                 goto failed_put_cred;
485         }
486 
487         ret = register_key_type(&cifs_idmap_key_type);
488         if (ret < 0)
489                 goto failed_put_key;
490 
491         /* instruct request_key() to use this special keyring as a cache for
492          * the results it looks up */
493         set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
494         cred->thread_keyring = keyring;
495         cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
496         root_cred = cred;
497 
498         cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
499         return 0;
500 
501 failed_put_key:
502         key_put(keyring);
503 failed_put_cred:
504         put_cred(cred);
505         return ret;
506 }
507 
508 void
509 exit_cifs_idmap(void)
510 {
511         key_revoke(root_cred->thread_keyring);
512         unregister_key_type(&cifs_idmap_key_type);
513         put_cred(root_cred);
514         cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
515 }
516 
517 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
518 static __u32 copy_sec_desc(const struct cifs_ntsd *pntsd,
519                                 struct cifs_ntsd *pnntsd,
520                                 __u32 sidsoffset,
521                                 struct cifs_sid *pownersid,
522                                 struct cifs_sid *pgrpsid)
523 {
524         struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
525         struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
526 
527         /* copy security descriptor control portion */
528         pnntsd->revision = pntsd->revision;
529         pnntsd->type = pntsd->type;
530         pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
531         pnntsd->sacloffset = 0;
532         pnntsd->osidoffset = cpu_to_le32(sidsoffset);
533         pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
534 
535         /* copy owner sid */
536         if (pownersid)
537                 owner_sid_ptr = pownersid;
538         else
539                 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
540                                 le32_to_cpu(pntsd->osidoffset));
541         nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
542         cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
543 
544         /* copy group sid */
545         if (pgrpsid)
546                 group_sid_ptr = pgrpsid;
547         else
548                 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
549                                 le32_to_cpu(pntsd->gsidoffset));
550         ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
551                                         sizeof(struct cifs_sid));
552         cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
553 
554         return sidsoffset + (2 * sizeof(struct cifs_sid));
555 }
556 
557 
558 /*
559    change posix mode to reflect permissions
560    pmode is the existing mode (we only want to overwrite part of this
561    bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
562 */
563 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
564                                  umode_t *pdenied, umode_t mask)
565 {
566         __u32 flags = le32_to_cpu(ace_flags);
567         /*
568          * Do not assume "preferred" or "canonical" order.
569          * The first DENY or ALLOW ACE which matches perfectly is
570          * the permission to be used. Once allowed or denied, same
571          * permission in later ACEs do not matter.
572          */
573 
574         /* If not already allowed, deny these bits */
575         if (type == ACCESS_DENIED) {
576                 if (flags & GENERIC_ALL &&
577                                 !(*pmode & mask & 0777))
578                         *pdenied |= mask & 0777;
579 
580                 if (((flags & GENERIC_WRITE) ||
581                                 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
582                                 !(*pmode & mask & 0222))
583                         *pdenied |= mask & 0222;
584 
585                 if (((flags & GENERIC_READ) ||
586                                 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
587                                 !(*pmode & mask & 0444))
588                         *pdenied |= mask & 0444;
589 
590                 if (((flags & GENERIC_EXECUTE) ||
591                                 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
592                                 !(*pmode & mask & 0111))
593                         *pdenied |= mask & 0111;
594 
595                 return;
596         } else if (type != ACCESS_ALLOWED) {
597                 cifs_dbg(VFS, "unknown access control type %d\n", type);
598                 return;
599         }
600         /* else ACCESS_ALLOWED type */
601 
602         if ((flags & GENERIC_ALL) &&
603                         !(*pdenied & mask & 0777)) {
604                 *pmode |= mask & 0777;
605                 cifs_dbg(NOISY, "all perms\n");
606                 return;
607         }
608 
609         if (((flags & GENERIC_WRITE) ||
610                         ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
611                         !(*pdenied & mask & 0222))
612                 *pmode |= mask & 0222;
613 
614         if (((flags & GENERIC_READ) ||
615                         ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
616                         !(*pdenied & mask & 0444))
617                 *pmode |= mask & 0444;
618 
619         if (((flags & GENERIC_EXECUTE) ||
620                         ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
621                         !(*pdenied & mask & 0111))
622                 *pmode |= mask & 0111;
623 
624         /* If DELETE_CHILD is set only on an owner ACE, set sticky bit */
625         if (flags & FILE_DELETE_CHILD) {
626                 if (mask == ACL_OWNER_MASK) {
627                         if (!(*pdenied & 01000))
628                                 *pmode |= 01000;
629                 } else if (!(*pdenied & 01000)) {
630                         *pmode &= ~01000;
631                         *pdenied |= 01000;
632                 }
633         }
634 
635         cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
636         return;
637 }
638 
639 /*
640    Generate access flags to reflect permissions mode is the existing mode.
641    This function is called for every ACE in the DACL whose SID matches
642    with either owner or group or everyone.
643 */
644 
645 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
646                                 __u32 *pace_flags)
647 {
648         /* reset access mask */
649         *pace_flags = 0x0;
650 
651         /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
652         mode &= bits_to_use;
653 
654         /* check for R/W/X UGO since we do not know whose flags
655            is this but we have cleared all the bits sans RWX for
656            either user or group or other as per bits_to_use */
657         if (mode & S_IRUGO)
658                 *pace_flags |= SET_FILE_READ_RIGHTS;
659         if (mode & S_IWUGO)
660                 *pace_flags |= SET_FILE_WRITE_RIGHTS;
661         if (mode & S_IXUGO)
662                 *pace_flags |= SET_FILE_EXEC_RIGHTS;
663 
664         cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
665                  mode, *pace_flags);
666         return;
667 }
668 
669 static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct cifs_sid *psid)
670 {
671         __u16 size = 1 + 1 + 2 + 4;
672 
673         dst->type = src->type;
674         dst->flags = src->flags;
675         dst->access_req = src->access_req;
676 
677         /* Check if there's a replacement sid specified */
678         if (psid)
679                 size += cifs_copy_sid(&dst->sid, psid);
680         else
681                 size += cifs_copy_sid(&dst->sid, &src->sid);
682 
683         dst->size = cpu_to_le16(size);
684 
685         return size;
686 }
687 
688 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
689                         const struct cifs_sid *psid, __u64 nmode,
690                         umode_t bits, __u8 access_type,
691                         bool allow_delete_child)
692 {
693         int i;
694         __u16 size = 0;
695         __u32 access_req = 0;
696 
697         pntace->type = access_type;
698         pntace->flags = 0x0;
699         mode_to_access_flags(nmode, bits, &access_req);
700 
701         if (access_type == ACCESS_ALLOWED && allow_delete_child)
702                 access_req |= FILE_DELETE_CHILD;
703 
704         if (access_type == ACCESS_ALLOWED && !access_req)
705                 access_req = SET_MINIMUM_RIGHTS;
706         else if (access_type == ACCESS_DENIED)
707                 access_req &= ~SET_MINIMUM_RIGHTS;
708 
709         pntace->access_req = cpu_to_le32(access_req);
710 
711         pntace->sid.revision = psid->revision;
712         pntace->sid.num_subauth = psid->num_subauth;
713         for (i = 0; i < NUM_AUTHS; i++)
714                 pntace->sid.authority[i] = psid->authority[i];
715         for (i = 0; i < psid->num_subauth; i++)
716                 pntace->sid.sub_auth[i] = psid->sub_auth[i];
717 
718         size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
719         pntace->size = cpu_to_le16(size);
720 
721         return size;
722 }
723 
724 
725 #ifdef CONFIG_CIFS_DEBUG2
726 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
727 {
728         int num_subauth;
729 
730         /* validate that we do not go past end of acl */
731 
732         if (le16_to_cpu(pace->size) < 16) {
733                 cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
734                 return;
735         }
736 
737         if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
738                 cifs_dbg(VFS, "ACL too small to parse ACE\n");
739                 return;
740         }
741 
742         num_subauth = pace->sid.num_subauth;
743         if (num_subauth) {
744                 int i;
745                 cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
746                          pace->sid.revision, pace->sid.num_subauth, pace->type,
747                          pace->flags, le16_to_cpu(pace->size));
748                 for (i = 0; i < num_subauth; ++i) {
749                         cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
750                                  i, le32_to_cpu(pace->sid.sub_auth[i]));
751                 }
752 
753                 /* BB add length check to make sure that we do not have huge
754                         num auths and therefore go off the end */
755         }
756 
757         return;
758 }
759 #endif
760 
761 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
762                        struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
763                        struct cifs_fattr *fattr, bool mode_from_special_sid)
764 {
765         int i;
766         int num_aces = 0;
767         int acl_size;
768         char *acl_base;
769         struct cifs_ace **ppace;
770 
771         /* BB need to add parm so we can store the SID BB */
772 
773         if (!pdacl) {
774                 /* no DACL in the security descriptor, set
775                    all the permissions for user/group/other */
776                 fattr->cf_mode |= 0777;
777                 return;
778         }
779 
780         /* validate that we do not go past end of acl */
781         if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
782                 cifs_dbg(VFS, "ACL too small to parse DACL\n");
783                 return;
784         }
785 
786         cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
787                  le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
788                  le32_to_cpu(pdacl->num_aces));
789 
790         /* reset rwx permissions for user/group/other.
791            Also, if num_aces is 0 i.e. DACL has no ACEs,
792            user/group/other have no permissions */
793         fattr->cf_mode &= ~(0777);
794 
795         acl_base = (char *)pdacl;
796         acl_size = sizeof(struct cifs_acl);
797 
798         num_aces = le32_to_cpu(pdacl->num_aces);
799         if (num_aces > 0) {
800                 umode_t denied_mode = 0;
801 
802                 if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
803                         return;
804                 ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
805                                       GFP_KERNEL);
806                 if (!ppace)
807                         return;
808 
809                 for (i = 0; i < num_aces; ++i) {
810                         ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
811 #ifdef CONFIG_CIFS_DEBUG2
812                         dump_ace(ppace[i], end_of_acl);
813 #endif
814                         if (mode_from_special_sid &&
815                             (compare_sids(&(ppace[i]->sid),
816                                           &sid_unix_NFS_mode) == 0)) {
817                                 /*
818                                  * Full permissions are:
819                                  * 07777 = S_ISUID | S_ISGID | S_ISVTX |
820                                  *         S_IRWXU | S_IRWXG | S_IRWXO
821                                  */
822                                 fattr->cf_mode &= ~07777;
823                                 fattr->cf_mode |=
824                                         le32_to_cpu(ppace[i]->sid.sub_auth[2]);
825                                 break;
826                         } else {
827                                 if (compare_sids(&(ppace[i]->sid), pownersid) == 0) {
828                                         access_flags_to_mode(ppace[i]->access_req,
829                                                         ppace[i]->type,
830                                                         &fattr->cf_mode,
831                                                         &denied_mode,
832                                                         ACL_OWNER_MASK);
833                                 } else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) {
834                                         access_flags_to_mode(ppace[i]->access_req,
835                                                         ppace[i]->type,
836                                                         &fattr->cf_mode,
837                                                         &denied_mode,
838                                                         ACL_GROUP_MASK);
839                                 } else if ((compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) ||
840                                                 (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)) {
841                                         access_flags_to_mode(ppace[i]->access_req,
842                                                         ppace[i]->type,
843                                                         &fattr->cf_mode,
844                                                         &denied_mode,
845                                                         ACL_EVERYONE_MASK);
846                                 }
847                         }
848 
849 
850 /*                      memcpy((void *)(&(cifscred->aces[i])),
851                                 (void *)ppace[i],
852                                 sizeof(struct cifs_ace)); */
853 
854                         acl_base = (char *)ppace[i];
855                         acl_size = le16_to_cpu(ppace[i]->size);
856                 }
857 
858                 kfree(ppace);
859         }
860 
861         return;
862 }
863 
864 unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
865 {
866         int i;
867         unsigned int ace_size = 20;
868 
869         pntace->type = ACCESS_ALLOWED_ACE_TYPE;
870         pntace->flags = 0x0;
871         pntace->access_req = cpu_to_le32(GENERIC_ALL);
872         pntace->sid.num_subauth = 1;
873         pntace->sid.revision = 1;
874         for (i = 0; i < NUM_AUTHS; i++)
875                 pntace->sid.authority[i] =  sid_authusers.authority[i];
876 
877         pntace->sid.sub_auth[0] =  sid_authusers.sub_auth[0];
878 
879         /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
880         pntace->size = cpu_to_le16(ace_size);
881         return ace_size;
882 }
883 
884 /*
885  * Fill in the special SID based on the mode. See
886  * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
887  */
888 unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
889 {
890         int i;
891         unsigned int ace_size = 28;
892 
893         pntace->type = ACCESS_DENIED_ACE_TYPE;
894         pntace->flags = 0x0;
895         pntace->access_req = 0;
896         pntace->sid.num_subauth = 3;
897         pntace->sid.revision = 1;
898         for (i = 0; i < NUM_AUTHS; i++)
899                 pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
900 
901         pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
902         pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
903         pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
904 
905         /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
906         pntace->size = cpu_to_le16(ace_size);
907         return ace_size;
908 }
909 
910 unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
911 {
912         int i;
913         unsigned int ace_size = 28;
914 
915         pntace->type = ACCESS_ALLOWED_ACE_TYPE;
916         pntace->flags = 0x0;
917         pntace->access_req = cpu_to_le32(GENERIC_ALL);
918         pntace->sid.num_subauth = 3;
919         pntace->sid.revision = 1;
920         for (i = 0; i < NUM_AUTHS; i++)
921                 pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
922 
923         pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
924         pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
925         pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
926 
927         /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
928         pntace->size = cpu_to_le16(ace_size);
929         return ace_size;
930 }
931 
932 static void populate_new_aces(char *nacl_base,
933                 struct cifs_sid *pownersid,
934                 struct cifs_sid *pgrpsid,
935                 __u64 *pnmode, u32 *pnum_aces, u16 *pnsize,
936                 bool modefromsid)
937 {
938         __u64 nmode;
939         u32 num_aces = 0;
940         u16 nsize = 0;
941         __u64 user_mode;
942         __u64 group_mode;
943         __u64 other_mode;
944         __u64 deny_user_mode = 0;
945         __u64 deny_group_mode = 0;
946         bool sticky_set = false;
947         struct cifs_ace *pnntace = NULL;
948 
949         nmode = *pnmode;
950         num_aces = *pnum_aces;
951         nsize = *pnsize;
952 
953         if (modefromsid) {
954                 pnntace = (struct cifs_ace *) (nacl_base + nsize);
955                 nsize += setup_special_mode_ACE(pnntace, nmode);
956                 num_aces++;
957                 pnntace = (struct cifs_ace *) (nacl_base + nsize);
958                 nsize += setup_authusers_ACE(pnntace);
959                 num_aces++;
960                 goto set_size;
961         }
962 
963         /*
964          * We'll try to keep the mode as requested by the user.
965          * But in cases where we cannot meaningfully convert that
966          * into ACL, return back the updated mode, so that it is
967          * updated in the inode.
968          */
969 
970         if (!memcmp(pownersid, pgrpsid, sizeof(struct cifs_sid))) {
971                 /*
972                  * Case when owner and group SIDs are the same.
973                  * Set the more restrictive of the two modes.
974                  */
975                 user_mode = nmode & (nmode << 3) & 0700;
976                 group_mode = nmode & (nmode >> 3) & 0070;
977         } else {
978                 user_mode = nmode & 0700;
979                 group_mode = nmode & 0070;
980         }
981 
982         other_mode = nmode & 0007;
983 
984         /* We need DENY ACE when the perm is more restrictive than the next sets. */
985         deny_user_mode = ~(user_mode) & ((group_mode << 3) | (other_mode << 6)) & 0700;
986         deny_group_mode = ~(group_mode) & (other_mode << 3) & 0070;
987 
988         *pnmode = user_mode | group_mode | other_mode | (nmode & ~0777);
989 
990         /* This tells if we should allow delete child for group and everyone. */
991         if (nmode & 01000)
992                 sticky_set = true;
993 
994         if (deny_user_mode) {
995                 pnntace = (struct cifs_ace *) (nacl_base + nsize);
996                 nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode,
997                                 0700, ACCESS_DENIED, false);
998                 num_aces++;
999         }
1000 
1001         /* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/
1002         if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) {
1003                 pnntace = (struct cifs_ace *) (nacl_base + nsize);
1004                 nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1005                                 0070, ACCESS_DENIED, false);
1006                 num_aces++;
1007         }
1008 
1009         pnntace = (struct cifs_ace *) (nacl_base + nsize);
1010         nsize += fill_ace_for_sid(pnntace, pownersid, user_mode,
1011                         0700, ACCESS_ALLOWED, true);
1012         num_aces++;
1013 
1014         /* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */
1015         if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) {
1016                 pnntace = (struct cifs_ace *) (nacl_base + nsize);
1017                 nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1018                                 0070, ACCESS_DENIED, false);
1019                 num_aces++;
1020         }
1021 
1022         pnntace = (struct cifs_ace *) (nacl_base + nsize);
1023         nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode,
1024                         0070, ACCESS_ALLOWED, !sticky_set);
1025         num_aces++;
1026 
1027         pnntace = (struct cifs_ace *) (nacl_base + nsize);
1028         nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode,
1029                         0007, ACCESS_ALLOWED, !sticky_set);
1030         num_aces++;
1031 
1032 set_size:
1033         *pnum_aces = num_aces;
1034         *pnsize = nsize;
1035 }
1036 
1037 static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
1038                 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
1039                 struct cifs_sid *pnownersid, struct cifs_sid *pngrpsid)
1040 {
1041         int i;
1042         u16 size = 0;
1043         struct cifs_ace *pntace = NULL;
1044         char *acl_base = NULL;
1045         u32 src_num_aces = 0;
1046         u16 nsize = 0;
1047         struct cifs_ace *pnntace = NULL;
1048         char *nacl_base = NULL;
1049         u16 ace_size = 0;
1050 
1051         acl_base = (char *)pdacl;
1052         size = sizeof(struct cifs_acl);
1053         src_num_aces = le32_to_cpu(pdacl->num_aces);
1054 
1055         nacl_base = (char *)pndacl;
1056         nsize = sizeof(struct cifs_acl);
1057 
1058         /* Go through all the ACEs */
1059         for (i = 0; i < src_num_aces; ++i) {
1060                 pntace = (struct cifs_ace *) (acl_base + size);
1061                 pnntace = (struct cifs_ace *) (nacl_base + nsize);
1062 
1063                 if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0)
1064                         ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
1065                 else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0)
1066                         ace_size = cifs_copy_ace(pnntace, pntace, pngrpsid);
1067                 else
1068                         ace_size = cifs_copy_ace(pnntace, pntace, NULL);
1069 
1070                 size += le16_to_cpu(pntace->size);
1071                 nsize += ace_size;
1072         }
1073 
1074         return nsize;
1075 }
1076 
1077 static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
1078                 struct cifs_sid *pownersid,     struct cifs_sid *pgrpsid,
1079                 __u64 *pnmode, bool mode_from_sid)
1080 {
1081         int i;
1082         u16 size = 0;
1083         struct cifs_ace *pntace = NULL;
1084         char *acl_base = NULL;
1085         u32 src_num_aces = 0;
1086         u16 nsize = 0;
1087         struct cifs_ace *pnntace = NULL;
1088         char *nacl_base = NULL;
1089         u32 num_aces = 0;
1090         bool new_aces_set = false;
1091 
1092         /* Assuming that pndacl and pnmode are never NULL */
1093         nacl_base = (char *)pndacl;
1094         nsize = sizeof(struct cifs_acl);
1095 
1096         /* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
1097         if (!pdacl) {
1098                 populate_new_aces(nacl_base,
1099                                 pownersid, pgrpsid,
1100                                 pnmode, &num_aces, &nsize,
1101                                 mode_from_sid);
1102                 goto finalize_dacl;
1103         }
1104 
1105         acl_base = (char *)pdacl;
1106         size = sizeof(struct cifs_acl);
1107         src_num_aces = le32_to_cpu(pdacl->num_aces);
1108 
1109         /* Retain old ACEs which we can retain */
1110         for (i = 0; i < src_num_aces; ++i) {
1111                 pntace = (struct cifs_ace *) (acl_base + size);
1112 
1113                 if (!new_aces_set && (pntace->flags & INHERITED_ACE)) {
1114                         /* Place the new ACEs in between existing explicit and inherited */
1115                         populate_new_aces(nacl_base,
1116                                         pownersid, pgrpsid,
1117                                         pnmode, &num_aces, &nsize,
1118                                         mode_from_sid);
1119 
1120                         new_aces_set = true;
1121                 }
1122 
1123                 /* If it's any one of the ACE we're replacing, skip! */
1124                 if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
1125                                 (compare_sids(&pntace->sid, pownersid) == 0) ||
1126                                 (compare_sids(&pntace->sid, pgrpsid) == 0) ||
1127                                 (compare_sids(&pntace->sid, &sid_everyone) == 0) ||
1128                                 (compare_sids(&pntace->sid, &sid_authusers) == 0))) {
1129                         goto next_ace;
1130                 }
1131 
1132                 /* update the pointer to the next ACE to populate*/
1133                 pnntace = (struct cifs_ace *) (nacl_base + nsize);
1134 
1135                 nsize += cifs_copy_ace(pnntace, pntace, NULL);
1136                 num_aces++;
1137 
1138 next_ace:
1139                 size += le16_to_cpu(pntace->size);
1140         }
1141 
1142         /* If inherited ACEs are not present, place the new ones at the tail */
1143         if (!new_aces_set) {
1144                 populate_new_aces(nacl_base,
1145                                 pownersid, pgrpsid,
1146                                 pnmode, &num_aces, &nsize,
1147                                 mode_from_sid);
1148 
1149                 new_aces_set = true;
1150         }
1151 
1152 finalize_dacl:
1153         pndacl->num_aces = cpu_to_le32(num_aces);
1154         pndacl->size = cpu_to_le16(nsize);
1155 
1156         return 0;
1157 }
1158 
1159 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
1160 {
1161         /* BB need to add parm so we can store the SID BB */
1162 
1163         /* validate that we do not go past end of ACL - sid must be at least 8
1164            bytes long (assuming no sub-auths - e.g. the null SID */
1165         if (end_of_acl < (char *)psid + 8) {
1166                 cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
1167                 return -EINVAL;
1168         }
1169 
1170 #ifdef CONFIG_CIFS_DEBUG2
1171         if (psid->num_subauth) {
1172                 int i;
1173                 cifs_dbg(FYI, "SID revision %d num_auth %d\n",
1174                          psid->revision, psid->num_subauth);
1175 
1176                 for (i = 0; i < psid->num_subauth; i++) {
1177                         cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
1178                                  i, le32_to_cpu(psid->sub_auth[i]));
1179                 }
1180 
1181                 /* BB add length check to make sure that we do not have huge
1182                         num auths and therefore go off the end */
1183                 cifs_dbg(FYI, "RID 0x%x\n",
1184                          le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1185         }
1186 #endif
1187 
1188         return 0;
1189 }
1190 
1191 
1192 /* Convert CIFS ACL to POSIX form */
1193 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1194                 struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
1195                 bool get_mode_from_special_sid)
1196 {
1197         int rc = 0;
1198         struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1199         struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
1200         char *end_of_acl = ((char *)pntsd) + acl_len;
1201         __u32 dacloffset;
1202 
1203         if (pntsd == NULL)
1204                 return -EIO;
1205 
1206         owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1207                                 le32_to_cpu(pntsd->osidoffset));
1208         group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1209                                 le32_to_cpu(pntsd->gsidoffset));
1210         dacloffset = le32_to_cpu(pntsd->dacloffset);
1211         dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1212         cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1213                  pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1214                  le32_to_cpu(pntsd->gsidoffset),
1215                  le32_to_cpu(pntsd->sacloffset), dacloffset);
1216 /*      cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1217         rc = parse_sid(owner_sid_ptr, end_of_acl);
1218         if (rc) {
1219                 cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1220                 return rc;
1221         }
1222         rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1223         if (rc) {
1224                 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1225                          __func__, rc);
1226                 return rc;
1227         }
1228 
1229         rc = parse_sid(group_sid_ptr, end_of_acl);
1230         if (rc) {
1231                 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
1232                          __func__, rc);
1233                 return rc;
1234         }
1235         rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1236         if (rc) {
1237                 cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1238                          __func__, rc);
1239                 return rc;
1240         }
1241 
1242         if (dacloffset)
1243                 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1244                            group_sid_ptr, fattr, get_mode_from_special_sid);
1245         else
1246                 cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
1247 
1248         return rc;
1249 }
1250 
1251 /* Convert permission bits from mode to equivalent CIFS ACL */
1252 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1253         __u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
1254         bool mode_from_sid, bool id_from_sid, int *aclflag)
1255 {
1256         int rc = 0;
1257         __u32 dacloffset;
1258         __u32 ndacloffset;
1259         __u32 sidsoffset;
1260         struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1261         struct cifs_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
1262         struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
1263         struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1264         char *end_of_acl = ((char *)pntsd) + secdesclen;
1265         u16 size = 0;
1266 
1267         dacloffset = le32_to_cpu(pntsd->dacloffset);
1268         if (dacloffset) {
1269                 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1270                 if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) {
1271                         cifs_dbg(VFS, "Server returned illegal ACL size\n");
1272                         return -EINVAL;
1273                 }
1274         }
1275 
1276         owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1277                         le32_to_cpu(pntsd->osidoffset));
1278         group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1279                         le32_to_cpu(pntsd->gsidoffset));
1280 
1281         if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1282                 ndacloffset = sizeof(struct cifs_ntsd);
1283                 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1284                 ndacl_ptr->revision =
1285                         dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1286 
1287                 ndacl_ptr->size = cpu_to_le16(0);
1288                 ndacl_ptr->num_aces = cpu_to_le32(0);
1289 
1290                 rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1291                                     pnmode, mode_from_sid);
1292 
1293                 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1294                 /* copy the non-dacl portion of secdesc */
1295                 *pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1296                                 NULL, NULL);
1297 
1298                 *aclflag |= CIFS_ACL_DACL;
1299         } else {
1300                 ndacloffset = sizeof(struct cifs_ntsd);
1301                 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1302                 ndacl_ptr->revision =
1303                         dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1304                 ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0;
1305 
1306                 if (uid_valid(uid)) { /* chown */
1307                         uid_t id;
1308                         nowner_sid_ptr = kzalloc(sizeof(struct cifs_sid),
1309                                                                 GFP_KERNEL);
1310                         if (!nowner_sid_ptr) {
1311                                 rc = -ENOMEM;
1312                                 goto chown_chgrp_exit;
1313                         }
1314                         id = from_kuid(&init_user_ns, uid);
1315                         if (id_from_sid) {
1316                                 struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1317                                 /* Populate the user ownership fields S-1-5-88-1 */
1318                                 osid->Revision = 1;
1319                                 osid->NumAuth = 3;
1320                                 osid->Authority[5] = 5;
1321                                 osid->SubAuthorities[0] = cpu_to_le32(88);
1322                                 osid->SubAuthorities[1] = cpu_to_le32(1);
1323                                 osid->SubAuthorities[2] = cpu_to_le32(id);
1324 
1325                         } else { /* lookup sid with upcall */
1326                                 rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1327                                 if (rc) {
1328                                         cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1329                                                  __func__, rc, id);
1330                                         goto chown_chgrp_exit;
1331                                 }
1332                         }
1333                         *aclflag |= CIFS_ACL_OWNER;
1334                 }
1335                 if (gid_valid(gid)) { /* chgrp */
1336                         gid_t id;
1337                         ngroup_sid_ptr = kzalloc(sizeof(struct cifs_sid),
1338                                                                 GFP_KERNEL);
1339                         if (!ngroup_sid_ptr) {
1340                                 rc = -ENOMEM;
1341                                 goto chown_chgrp_exit;
1342                         }
1343                         id = from_kgid(&init_user_ns, gid);
1344                         if (id_from_sid) {
1345                                 struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1346                                 /* Populate the group ownership fields S-1-5-88-2 */
1347                                 gsid->Revision = 1;
1348                                 gsid->NumAuth = 3;
1349                                 gsid->Authority[5] = 5;
1350                                 gsid->SubAuthorities[0] = cpu_to_le32(88);
1351                                 gsid->SubAuthorities[1] = cpu_to_le32(2);
1352                                 gsid->SubAuthorities[2] = cpu_to_le32(id);
1353 
1354                         } else { /* lookup sid with upcall */
1355                                 rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1356                                 if (rc) {
1357                                         cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1358                                                  __func__, rc, id);
1359                                         goto chown_chgrp_exit;
1360                                 }
1361                         }
1362                         *aclflag |= CIFS_ACL_GROUP;
1363                 }
1364 
1365                 if (dacloffset) {
1366                         /* Replace ACEs for old owner with new one */
1367                         size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1368                                         owner_sid_ptr, group_sid_ptr,
1369                                         nowner_sid_ptr, ngroup_sid_ptr);
1370                         ndacl_ptr->size = cpu_to_le16(size);
1371                 }
1372 
1373                 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1374                 /* copy the non-dacl portion of secdesc */
1375                 *pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1376                                 nowner_sid_ptr, ngroup_sid_ptr);
1377 
1378 chown_chgrp_exit:
1379                 /* errors could jump here. So make sure we return soon after this */
1380                 kfree(nowner_sid_ptr);
1381                 kfree(ngroup_sid_ptr);
1382         }
1383 
1384         return rc;
1385 }
1386 
1387 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1388 struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1389                                       const struct cifs_fid *cifsfid, u32 *pacllen,
1390                                       u32 __maybe_unused unused)
1391 {
1392         struct cifs_ntsd *pntsd = NULL;
1393         unsigned int xid;
1394         int rc;
1395         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1396 
1397         if (IS_ERR(tlink))
1398                 return ERR_CAST(tlink);
1399 
1400         xid = get_xid();
1401         rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1402                                 pacllen);
1403         free_xid(xid);
1404 
1405         cifs_put_tlink(tlink);
1406 
1407         cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1408         if (rc)
1409                 return ERR_PTR(rc);
1410         return pntsd;
1411 }
1412 
1413 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1414                 const char *path, u32 *pacllen)
1415 {
1416         struct cifs_ntsd *pntsd = NULL;
1417         int oplock = 0;
1418         unsigned int xid;
1419         int rc;
1420         struct cifs_tcon *tcon;
1421         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1422         struct cifs_fid fid;
1423         struct cifs_open_parms oparms;
1424 
1425         if (IS_ERR(tlink))
1426                 return ERR_CAST(tlink);
1427 
1428         tcon = tlink_tcon(tlink);
1429         xid = get_xid();
1430 
1431         oparms = (struct cifs_open_parms) {
1432                 .tcon = tcon,
1433                 .cifs_sb = cifs_sb,
1434                 .desired_access = READ_CONTROL,
1435                 .create_options = cifs_create_options(cifs_sb, 0),
1436                 .disposition = FILE_OPEN,
1437                 .path = path,
1438                 .fid = &fid,
1439         };
1440 
1441         rc = CIFS_open(xid, &oparms, &oplock, NULL);
1442         if (!rc) {
1443                 rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1444                 CIFSSMBClose(xid, tcon, fid.netfid);
1445         }
1446 
1447         cifs_put_tlink(tlink);
1448         free_xid(xid);
1449 
1450         cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1451         if (rc)
1452                 return ERR_PTR(rc);
1453         return pntsd;
1454 }
1455 
1456 /* Retrieve an ACL from the server */
1457 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1458                                       struct inode *inode, const char *path,
1459                                u32 *pacllen, u32 info)
1460 {
1461         struct cifs_ntsd *pntsd = NULL;
1462         struct cifsFileInfo *open_file = NULL;
1463 
1464         if (inode)
1465                 open_file = find_readable_file(CIFS_I(inode), true);
1466         if (!open_file)
1467                 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1468 
1469         pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1470         cifsFileInfo_put(open_file);
1471         return pntsd;
1472 }
1473 
1474  /* Set an ACL on the server */
1475 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1476                         struct inode *inode, const char *path, int aclflag)
1477 {
1478         int oplock = 0;
1479         unsigned int xid;
1480         int rc, access_flags;
1481         struct cifs_tcon *tcon;
1482         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1483         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1484         struct cifs_fid fid;
1485         struct cifs_open_parms oparms;
1486 
1487         if (IS_ERR(tlink))
1488                 return PTR_ERR(tlink);
1489 
1490         tcon = tlink_tcon(tlink);
1491         xid = get_xid();
1492 
1493         if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1494                 access_flags = WRITE_OWNER;
1495         else
1496                 access_flags = WRITE_DAC;
1497 
1498         oparms = (struct cifs_open_parms) {
1499                 .tcon = tcon,
1500                 .cifs_sb = cifs_sb,
1501                 .desired_access = access_flags,
1502                 .create_options = cifs_create_options(cifs_sb, 0),
1503                 .disposition = FILE_OPEN,
1504                 .path = path,
1505                 .fid = &fid,
1506         };
1507 
1508         rc = CIFS_open(xid, &oparms, &oplock, NULL);
1509         if (rc) {
1510                 cifs_dbg(VFS, "Unable to open file to set ACL\n");
1511                 goto out;
1512         }
1513 
1514         rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1515         cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1516 
1517         CIFSSMBClose(xid, tcon, fid.netfid);
1518 out:
1519         free_xid(xid);
1520         cifs_put_tlink(tlink);
1521         return rc;
1522 }
1523 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1524 
1525 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1526 int
1527 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1528                   struct inode *inode, bool mode_from_special_sid,
1529                   const char *path, const struct cifs_fid *pfid)
1530 {
1531         struct cifs_ntsd *pntsd = NULL;
1532         u32 acllen = 0;
1533         int rc = 0;
1534         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1535         struct smb_version_operations *ops;
1536         const u32 info = 0;
1537 
1538         cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1539 
1540         if (IS_ERR(tlink))
1541                 return PTR_ERR(tlink);
1542 
1543         ops = tlink_tcon(tlink)->ses->server->ops;
1544 
1545         if (pfid && (ops->get_acl_by_fid))
1546                 pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1547         else if (ops->get_acl)
1548                 pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1549         else {
1550                 cifs_put_tlink(tlink);
1551                 return -EOPNOTSUPP;
1552         }
1553         /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1554         if (IS_ERR(pntsd)) {
1555                 rc = PTR_ERR(pntsd);
1556                 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1557         } else if (mode_from_special_sid) {
1558                 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1559                 kfree(pntsd);
1560         } else {
1561                 /* get approximated mode from ACL */
1562                 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1563                 kfree(pntsd);
1564                 if (rc)
1565                         cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1566         }
1567 
1568         cifs_put_tlink(tlink);
1569 
1570         return rc;
1571 }
1572 
1573 /* Convert mode bits to an ACL so we can update the ACL on the server */
1574 int
1575 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1576                         kuid_t uid, kgid_t gid)
1577 {
1578         int rc = 0;
1579         int aclflag = CIFS_ACL_DACL; /* default flag to set */
1580         __u32 secdesclen = 0;
1581         __u32 nsecdesclen = 0;
1582         __u32 dacloffset = 0;
1583         struct cifs_acl *dacl_ptr = NULL;
1584         struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1585         struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1586         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1587         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1588         struct smb_version_operations *ops;
1589         bool mode_from_sid, id_from_sid;
1590         const u32 info = 0;
1591 
1592         if (IS_ERR(tlink))
1593                 return PTR_ERR(tlink);
1594 
1595         ops = tlink_tcon(tlink)->ses->server->ops;
1596 
1597         cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1598 
1599         /* Get the security descriptor */
1600 
1601         if (ops->get_acl == NULL) {
1602                 cifs_put_tlink(tlink);
1603                 return -EOPNOTSUPP;
1604         }
1605 
1606         pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1607         if (IS_ERR(pntsd)) {
1608                 rc = PTR_ERR(pntsd);
1609                 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1610                 cifs_put_tlink(tlink);
1611                 return rc;
1612         }
1613 
1614         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1615                 mode_from_sid = true;
1616         else
1617                 mode_from_sid = false;
1618 
1619         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1620                 id_from_sid = true;
1621         else
1622                 id_from_sid = false;
1623 
1624         /* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1625         nsecdesclen = secdesclen;
1626         if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1627                 if (mode_from_sid)
1628                         nsecdesclen += 2 * sizeof(struct cifs_ace);
1629                 else /* cifsacl */
1630                         nsecdesclen += 5 * sizeof(struct cifs_ace);
1631         } else { /* chown */
1632                 /* When ownership changes, changes new owner sid length could be different */
1633                 nsecdesclen = sizeof(struct cifs_ntsd) + (sizeof(struct cifs_sid) * 2);
1634                 dacloffset = le32_to_cpu(pntsd->dacloffset);
1635                 if (dacloffset) {
1636                         dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1637                         if (mode_from_sid)
1638                                 nsecdesclen +=
1639                                         le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace);
1640                         else /* cifsacl */
1641                                 nsecdesclen += le16_to_cpu(dacl_ptr->size);
1642                 }
1643         }
1644 
1645         /*
1646          * Add three ACEs for owner, group, everyone getting rid of other ACEs
1647          * as chmod disables ACEs and set the security descriptor. Allocate
1648          * memory for the smb header, set security descriptor request security
1649          * descriptor parameters, and security descriptor itself
1650          */
1651         nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1652         pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);
1653         if (!pnntsd) {
1654                 kfree(pntsd);
1655                 cifs_put_tlink(tlink);
1656                 return -ENOMEM;
1657         }
1658 
1659         rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1660                             mode_from_sid, id_from_sid, &aclflag);
1661 
1662         cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1663 
1664         if (ops->set_acl == NULL)
1665                 rc = -EOPNOTSUPP;
1666 
1667         if (!rc) {
1668                 /* Set the security descriptor */
1669                 rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1670                 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1671         }
1672         cifs_put_tlink(tlink);
1673 
1674         kfree(pnntsd);
1675         kfree(pntsd);
1676         return rc;
1677 }
1678 
1679 struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap,
1680                                struct dentry *dentry, int type)
1681 {
1682 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1683         struct posix_acl *acl = NULL;
1684         ssize_t rc = -EOPNOTSUPP;
1685         unsigned int xid;
1686         struct super_block *sb = dentry->d_sb;
1687         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1688         struct tcon_link *tlink;
1689         struct cifs_tcon *pTcon;
1690         const char *full_path;
1691         void *page;
1692 
1693         tlink = cifs_sb_tlink(cifs_sb);
1694         if (IS_ERR(tlink))
1695                 return ERR_CAST(tlink);
1696         pTcon = tlink_tcon(tlink);
1697 
1698         xid = get_xid();
1699         page = alloc_dentry_path();
1700 
1701         full_path = build_path_from_dentry(dentry, page);
1702         if (IS_ERR(full_path)) {
1703                 acl = ERR_CAST(full_path);
1704                 goto out;
1705         }
1706 
1707         /* return alt name if available as pseudo attr */
1708         switch (type) {
1709         case ACL_TYPE_ACCESS:
1710                 if (sb->s_flags & SB_POSIXACL)
1711                         rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1712                                              ACL_TYPE_ACCESS,
1713                                              cifs_sb->local_nls,
1714                                              cifs_remap(cifs_sb));
1715                 break;
1716 
1717         case ACL_TYPE_DEFAULT:
1718                 if (sb->s_flags & SB_POSIXACL)
1719                         rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1720                                              ACL_TYPE_DEFAULT,
1721                                              cifs_sb->local_nls,
1722                                              cifs_remap(cifs_sb));
1723                 break;
1724         }
1725 
1726         if (rc < 0) {
1727                 if (rc == -EINVAL)
1728                         acl = ERR_PTR(-EOPNOTSUPP);
1729                 else
1730                         acl = ERR_PTR(rc);
1731         }
1732 
1733 out:
1734         free_dentry_path(page);
1735         free_xid(xid);
1736         cifs_put_tlink(tlink);
1737         return acl;
1738 #else
1739         return ERR_PTR(-EOPNOTSUPP);
1740 #endif
1741 }
1742 
1743 int cifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
1744                  struct posix_acl *acl, int type)
1745 {
1746 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1747         int rc = -EOPNOTSUPP;
1748         unsigned int xid;
1749         struct super_block *sb = dentry->d_sb;
1750         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1751         struct tcon_link *tlink;
1752         struct cifs_tcon *pTcon;
1753         const char *full_path;
1754         void *page;
1755 
1756         tlink = cifs_sb_tlink(cifs_sb);
1757         if (IS_ERR(tlink))
1758                 return PTR_ERR(tlink);
1759         pTcon = tlink_tcon(tlink);
1760 
1761         xid = get_xid();
1762         page = alloc_dentry_path();
1763 
1764         full_path = build_path_from_dentry(dentry, page);
1765         if (IS_ERR(full_path)) {
1766                 rc = PTR_ERR(full_path);
1767                 goto out;
1768         }
1769 
1770         if (!acl)
1771                 goto out;
1772 
1773         /* return dos attributes as pseudo xattr */
1774         /* return alt name if available as pseudo attr */
1775 
1776         /* if proc/fs/cifs/streamstoxattr is set then
1777                 search server for EAs or streams to
1778                 returns as xattrs */
1779         if (posix_acl_xattr_size(acl->a_count) > CIFSMaxBufSize) {
1780                 cifs_dbg(FYI, "size of EA value too large\n");
1781                 rc = -EOPNOTSUPP;
1782                 goto out;
1783         }
1784 
1785         switch (type) {
1786         case ACL_TYPE_ACCESS:
1787                 if (sb->s_flags & SB_POSIXACL)
1788                         rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1789                                              ACL_TYPE_ACCESS,
1790                                              cifs_sb->local_nls,
1791                                              cifs_remap(cifs_sb));
1792                 break;
1793 
1794         case ACL_TYPE_DEFAULT:
1795                 if (sb->s_flags & SB_POSIXACL)
1796                         rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1797                                              ACL_TYPE_DEFAULT,
1798                                              cifs_sb->local_nls,
1799                                              cifs_remap(cifs_sb));
1800                 break;
1801         }
1802 
1803 out:
1804         free_dentry_path(page);
1805         free_xid(xid);
1806         cifs_put_tlink(tlink);
1807         return rc;
1808 #else
1809         return -EOPNOTSUPP;
1810 #endif
1811 }
1812 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php