Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: LGPL-2.1
0002 /*
0003  *
0004  *   Copyright (C) International Business Machines  Corp., 2007,2008
0005  *   Author(s): Steve French (sfrench@us.ibm.com)
0006  *
0007  *   Contains the routines for mapping CIFS/NTFS ACLs
0008  *
0009  */
0010 
0011 #include <linux/fs.h>
0012 #include <linux/slab.h>
0013 #include <linux/string.h>
0014 #include <linux/keyctl.h>
0015 #include <linux/key-type.h>
0016 #include <keys/user-type.h>
0017 #include "cifspdu.h"
0018 #include "cifsglob.h"
0019 #include "cifsacl.h"
0020 #include "cifsproto.h"
0021 #include "cifs_debug.h"
0022 #include "fs_context.h"
0023 
0024 /* security id for everyone/world system group */
0025 static const struct cifs_sid sid_everyone = {
0026     1, 1, {0, 0, 0, 0, 0, 1}, {0} };
0027 /* security id for Authenticated Users system group */
0028 static const struct cifs_sid sid_authusers = {
0029     1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
0030 
0031 /* S-1-22-1 Unmapped Unix users */
0032 static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
0033         {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0034 
0035 /* S-1-22-2 Unmapped Unix groups */
0036 static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
0037         {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0038 
0039 /*
0040  * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
0041  */
0042 
0043 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
0044 
0045 /* S-1-5-88-1 Unix uid */
0046 static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
0047     {cpu_to_le32(88),
0048      cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0049 
0050 /* S-1-5-88-2 Unix gid */
0051 static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
0052     {cpu_to_le32(88),
0053      cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0054 
0055 /* S-1-5-88-3 Unix mode */
0056 static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
0057     {cpu_to_le32(88),
0058      cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0059 
0060 static const struct cred *root_cred;
0061 
0062 static int
0063 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
0064 {
0065     char *payload;
0066 
0067     /*
0068      * If the payload is less than or equal to the size of a pointer, then
0069      * an allocation here is wasteful. Just copy the data directly to the
0070      * payload.value union member instead.
0071      *
0072      * With this however, you must check the datalen before trying to
0073      * dereference payload.data!
0074      */
0075     if (prep->datalen <= sizeof(key->payload)) {
0076         key->payload.data[0] = NULL;
0077         memcpy(&key->payload, prep->data, prep->datalen);
0078     } else {
0079         payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
0080         if (!payload)
0081             return -ENOMEM;
0082         key->payload.data[0] = payload;
0083     }
0084 
0085     key->datalen = prep->datalen;
0086     return 0;
0087 }
0088 
0089 static inline void
0090 cifs_idmap_key_destroy(struct key *key)
0091 {
0092     if (key->datalen > sizeof(key->payload))
0093         kfree(key->payload.data[0]);
0094 }
0095 
0096 static struct key_type cifs_idmap_key_type = {
0097     .name        = "cifs.idmap",
0098     .instantiate = cifs_idmap_key_instantiate,
0099     .destroy     = cifs_idmap_key_destroy,
0100     .describe    = user_describe,
0101 };
0102 
0103 static char *
0104 sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
0105 {
0106     int i, len;
0107     unsigned int saval;
0108     char *sidstr, *strptr;
0109     unsigned long long id_auth_val;
0110 
0111     /* 3 bytes for prefix */
0112     sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
0113              (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
0114              GFP_KERNEL);
0115     if (!sidstr)
0116         return sidstr;
0117 
0118     strptr = sidstr;
0119     len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
0120             sidptr->revision);
0121     strptr += len;
0122 
0123     /* The authority field is a single 48-bit number */
0124     id_auth_val = (unsigned long long)sidptr->authority[5];
0125     id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
0126     id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
0127     id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
0128     id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
0129     id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
0130 
0131     /*
0132      * MS-DTYP states that if the authority is >= 2^32, then it should be
0133      * expressed as a hex value.
0134      */
0135     if (id_auth_val <= UINT_MAX)
0136         len = sprintf(strptr, "-%llu", id_auth_val);
0137     else
0138         len = sprintf(strptr, "-0x%llx", id_auth_val);
0139 
0140     strptr += len;
0141 
0142     for (i = 0; i < sidptr->num_subauth; ++i) {
0143         saval = le32_to_cpu(sidptr->sub_auth[i]);
0144         len = sprintf(strptr, "-%u", saval);
0145         strptr += len;
0146     }
0147 
0148     return sidstr;
0149 }
0150 
0151 /*
0152  * if the two SIDs (roughly equivalent to a UUID for a user or group) are
0153  * the same returns zero, if they do not match returns non-zero.
0154  */
0155 static int
0156 compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
0157 {
0158     int i;
0159     int num_subauth, num_sat, num_saw;
0160 
0161     if ((!ctsid) || (!cwsid))
0162         return 1;
0163 
0164     /* compare the revision */
0165     if (ctsid->revision != cwsid->revision) {
0166         if (ctsid->revision > cwsid->revision)
0167             return 1;
0168         else
0169             return -1;
0170     }
0171 
0172     /* compare all of the six auth values */
0173     for (i = 0; i < NUM_AUTHS; ++i) {
0174         if (ctsid->authority[i] != cwsid->authority[i]) {
0175             if (ctsid->authority[i] > cwsid->authority[i])
0176                 return 1;
0177             else
0178                 return -1;
0179         }
0180     }
0181 
0182     /* compare all of the subauth values if any */
0183     num_sat = ctsid->num_subauth;
0184     num_saw = cwsid->num_subauth;
0185     num_subauth = num_sat < num_saw ? num_sat : num_saw;
0186     if (num_subauth) {
0187         for (i = 0; i < num_subauth; ++i) {
0188             if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
0189                 if (le32_to_cpu(ctsid->sub_auth[i]) >
0190                     le32_to_cpu(cwsid->sub_auth[i]))
0191                     return 1;
0192                 else
0193                     return -1;
0194             }
0195         }
0196     }
0197 
0198     return 0; /* sids compare/match */
0199 }
0200 
0201 static bool
0202 is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
0203 {
0204     int i;
0205     int num_subauth;
0206     const struct cifs_sid *pwell_known_sid;
0207 
0208     if (!psid || (puid == NULL))
0209         return false;
0210 
0211     num_subauth = psid->num_subauth;
0212 
0213     /* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
0214     if (num_subauth == 2) {
0215         if (is_group)
0216             pwell_known_sid = &sid_unix_groups;
0217         else
0218             pwell_known_sid = &sid_unix_users;
0219     } else if (num_subauth == 3) {
0220         if (is_group)
0221             pwell_known_sid = &sid_unix_NFS_groups;
0222         else
0223             pwell_known_sid = &sid_unix_NFS_users;
0224     } else
0225         return false;
0226 
0227     /* compare the revision */
0228     if (psid->revision != pwell_known_sid->revision)
0229         return false;
0230 
0231     /* compare all of the six auth values */
0232     for (i = 0; i < NUM_AUTHS; ++i) {
0233         if (psid->authority[i] != pwell_known_sid->authority[i]) {
0234             cifs_dbg(FYI, "auth %d did not match\n", i);
0235             return false;
0236         }
0237     }
0238 
0239     if (num_subauth == 2) {
0240         if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
0241             return false;
0242 
0243         *puid = le32_to_cpu(psid->sub_auth[1]);
0244     } else /* 3 subauths, ie Windows/Mac style */ {
0245         *puid = le32_to_cpu(psid->sub_auth[0]);
0246         if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
0247             (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
0248             return false;
0249 
0250         *puid = le32_to_cpu(psid->sub_auth[2]);
0251     }
0252 
0253     cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
0254     return true; /* well known sid found, uid returned */
0255 }
0256 
0257 static __u16
0258 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
0259 {
0260     int i;
0261     __u16 size = 1 + 1 + 6;
0262 
0263     dst->revision = src->revision;
0264     dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
0265     for (i = 0; i < NUM_AUTHS; ++i)
0266         dst->authority[i] = src->authority[i];
0267     for (i = 0; i < dst->num_subauth; ++i)
0268         dst->sub_auth[i] = src->sub_auth[i];
0269     size += (dst->num_subauth * 4);
0270 
0271     return size;
0272 }
0273 
0274 static int
0275 id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
0276 {
0277     int rc;
0278     struct key *sidkey;
0279     struct cifs_sid *ksid;
0280     unsigned int ksid_size;
0281     char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
0282     const struct cred *saved_cred;
0283 
0284     rc = snprintf(desc, sizeof(desc), "%ci:%u",
0285             sidtype == SIDOWNER ? 'o' : 'g', cid);
0286     if (rc >= sizeof(desc))
0287         return -EINVAL;
0288 
0289     rc = 0;
0290     saved_cred = override_creds(root_cred);
0291     sidkey = request_key(&cifs_idmap_key_type, desc, "");
0292     if (IS_ERR(sidkey)) {
0293         rc = -EINVAL;
0294         cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
0295              __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
0296         goto out_revert_creds;
0297     } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
0298         rc = -EIO;
0299         cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
0300              __func__, sidkey->datalen);
0301         goto invalidate_key;
0302     }
0303 
0304     /*
0305      * A sid is usually too large to be embedded in payload.value, but if
0306      * there are no subauthorities and the host has 8-byte pointers, then
0307      * it could be.
0308      */
0309     ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
0310         (struct cifs_sid *)&sidkey->payload :
0311         (struct cifs_sid *)sidkey->payload.data[0];
0312 
0313     ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
0314     if (ksid_size > sidkey->datalen) {
0315         rc = -EIO;
0316         cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
0317              __func__, sidkey->datalen, ksid_size);
0318         goto invalidate_key;
0319     }
0320 
0321     cifs_copy_sid(ssid, ksid);
0322 out_key_put:
0323     key_put(sidkey);
0324 out_revert_creds:
0325     revert_creds(saved_cred);
0326     return rc;
0327 
0328 invalidate_key:
0329     key_invalidate(sidkey);
0330     goto out_key_put;
0331 }
0332 
0333 int
0334 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
0335         struct cifs_fattr *fattr, uint sidtype)
0336 {
0337     int rc = 0;
0338     struct key *sidkey;
0339     char *sidstr;
0340     const struct cred *saved_cred;
0341     kuid_t fuid = cifs_sb->ctx->linux_uid;
0342     kgid_t fgid = cifs_sb->ctx->linux_gid;
0343 
0344     /*
0345      * If we have too many subauthorities, then something is really wrong.
0346      * Just return an error.
0347      */
0348     if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
0349         cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
0350              __func__, psid->num_subauth);
0351         return -EIO;
0352     }
0353 
0354     if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
0355         (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
0356         uint32_t unix_id;
0357         bool is_group;
0358 
0359         if (sidtype != SIDOWNER)
0360             is_group = true;
0361         else
0362             is_group = false;
0363 
0364         if (is_well_known_sid(psid, &unix_id, is_group) == false)
0365             goto try_upcall_to_get_id;
0366 
0367         if (is_group) {
0368             kgid_t gid;
0369             gid_t id;
0370 
0371             id = (gid_t)unix_id;
0372             gid = make_kgid(&init_user_ns, id);
0373             if (gid_valid(gid)) {
0374                 fgid = gid;
0375                 goto got_valid_id;
0376             }
0377         } else {
0378             kuid_t uid;
0379             uid_t id;
0380 
0381             id = (uid_t)unix_id;
0382             uid = make_kuid(&init_user_ns, id);
0383             if (uid_valid(uid)) {
0384                 fuid = uid;
0385                 goto got_valid_id;
0386             }
0387         }
0388         /* If unable to find uid/gid easily from SID try via upcall */
0389     }
0390 
0391 try_upcall_to_get_id:
0392     sidstr = sid_to_key_str(psid, sidtype);
0393     if (!sidstr)
0394         return -ENOMEM;
0395 
0396     saved_cred = override_creds(root_cred);
0397     sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
0398     if (IS_ERR(sidkey)) {
0399         cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
0400              __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
0401         goto out_revert_creds;
0402     }
0403 
0404     /*
0405      * FIXME: Here we assume that uid_t and gid_t are same size. It's
0406      * probably a safe assumption but might be better to check based on
0407      * sidtype.
0408      */
0409     BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
0410     if (sidkey->datalen != sizeof(uid_t)) {
0411         cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
0412              __func__, sidkey->datalen);
0413         key_invalidate(sidkey);
0414         goto out_key_put;
0415     }
0416 
0417     if (sidtype == SIDOWNER) {
0418         kuid_t uid;
0419         uid_t id;
0420         memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
0421         uid = make_kuid(&init_user_ns, id);
0422         if (uid_valid(uid))
0423             fuid = uid;
0424     } else {
0425         kgid_t gid;
0426         gid_t id;
0427         memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
0428         gid = make_kgid(&init_user_ns, id);
0429         if (gid_valid(gid))
0430             fgid = gid;
0431     }
0432 
0433 out_key_put:
0434     key_put(sidkey);
0435 out_revert_creds:
0436     revert_creds(saved_cred);
0437     kfree(sidstr);
0438 
0439     /*
0440      * Note that we return 0 here unconditionally. If the mapping
0441      * fails then we just fall back to using the ctx->linux_uid/linux_gid.
0442      */
0443 got_valid_id:
0444     rc = 0;
0445     if (sidtype == SIDOWNER)
0446         fattr->cf_uid = fuid;
0447     else
0448         fattr->cf_gid = fgid;
0449     return rc;
0450 }
0451 
0452 int
0453 init_cifs_idmap(void)
0454 {
0455     struct cred *cred;
0456     struct key *keyring;
0457     int ret;
0458 
0459     cifs_dbg(FYI, "Registering the %s key type\n",
0460          cifs_idmap_key_type.name);
0461 
0462     /* create an override credential set with a special thread keyring in
0463      * which requests are cached
0464      *
0465      * this is used to prevent malicious redirections from being installed
0466      * with add_key().
0467      */
0468     cred = prepare_kernel_cred(NULL);
0469     if (!cred)
0470         return -ENOMEM;
0471 
0472     keyring = keyring_alloc(".cifs_idmap",
0473                 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
0474                 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
0475                 KEY_USR_VIEW | KEY_USR_READ,
0476                 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
0477     if (IS_ERR(keyring)) {
0478         ret = PTR_ERR(keyring);
0479         goto failed_put_cred;
0480     }
0481 
0482     ret = register_key_type(&cifs_idmap_key_type);
0483     if (ret < 0)
0484         goto failed_put_key;
0485 
0486     /* instruct request_key() to use this special keyring as a cache for
0487      * the results it looks up */
0488     set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
0489     cred->thread_keyring = keyring;
0490     cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
0491     root_cred = cred;
0492 
0493     cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
0494     return 0;
0495 
0496 failed_put_key:
0497     key_put(keyring);
0498 failed_put_cred:
0499     put_cred(cred);
0500     return ret;
0501 }
0502 
0503 void
0504 exit_cifs_idmap(void)
0505 {
0506     key_revoke(root_cred->thread_keyring);
0507     unregister_key_type(&cifs_idmap_key_type);
0508     put_cred(root_cred);
0509     cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
0510 }
0511 
0512 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
0513 static __u32 copy_sec_desc(const struct cifs_ntsd *pntsd,
0514                 struct cifs_ntsd *pnntsd,
0515                 __u32 sidsoffset,
0516                 struct cifs_sid *pownersid,
0517                 struct cifs_sid *pgrpsid)
0518 {
0519     struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
0520     struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
0521 
0522     /* copy security descriptor control portion */
0523     pnntsd->revision = pntsd->revision;
0524     pnntsd->type = pntsd->type;
0525     pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
0526     pnntsd->sacloffset = 0;
0527     pnntsd->osidoffset = cpu_to_le32(sidsoffset);
0528     pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
0529 
0530     /* copy owner sid */
0531     if (pownersid)
0532         owner_sid_ptr = pownersid;
0533     else
0534         owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
0535                 le32_to_cpu(pntsd->osidoffset));
0536     nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
0537     cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
0538 
0539     /* copy group sid */
0540     if (pgrpsid)
0541         group_sid_ptr = pgrpsid;
0542     else
0543         group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
0544                 le32_to_cpu(pntsd->gsidoffset));
0545     ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
0546                     sizeof(struct cifs_sid));
0547     cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
0548 
0549     return sidsoffset + (2 * sizeof(struct cifs_sid));
0550 }
0551 
0552 
0553 /*
0554    change posix mode to reflect permissions
0555    pmode is the existing mode (we only want to overwrite part of this
0556    bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
0557 */
0558 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
0559                  umode_t *pdenied, umode_t mask)
0560 {
0561     __u32 flags = le32_to_cpu(ace_flags);
0562     /*
0563      * Do not assume "preferred" or "canonical" order.
0564      * The first DENY or ALLOW ACE which matches perfectly is
0565      * the permission to be used. Once allowed or denied, same
0566      * permission in later ACEs do not matter.
0567      */
0568 
0569     /* If not already allowed, deny these bits */
0570     if (type == ACCESS_DENIED) {
0571         if (flags & GENERIC_ALL &&
0572                 !(*pmode & mask & 0777))
0573             *pdenied |= mask & 0777;
0574 
0575         if (((flags & GENERIC_WRITE) ||
0576                 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
0577                 !(*pmode & mask & 0222))
0578             *pdenied |= mask & 0222;
0579 
0580         if (((flags & GENERIC_READ) ||
0581                 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
0582                 !(*pmode & mask & 0444))
0583             *pdenied |= mask & 0444;
0584 
0585         if (((flags & GENERIC_EXECUTE) ||
0586                 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
0587                 !(*pmode & mask & 0111))
0588             *pdenied |= mask & 0111;
0589 
0590         return;
0591     } else if (type != ACCESS_ALLOWED) {
0592         cifs_dbg(VFS, "unknown access control type %d\n", type);
0593         return;
0594     }
0595     /* else ACCESS_ALLOWED type */
0596 
0597     if ((flags & GENERIC_ALL) &&
0598             !(*pdenied & mask & 0777)) {
0599         *pmode |= mask & 0777;
0600         cifs_dbg(NOISY, "all perms\n");
0601         return;
0602     }
0603 
0604     if (((flags & GENERIC_WRITE) ||
0605             ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
0606             !(*pdenied & mask & 0222))
0607         *pmode |= mask & 0222;
0608 
0609     if (((flags & GENERIC_READ) ||
0610             ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
0611             !(*pdenied & mask & 0444))
0612         *pmode |= mask & 0444;
0613 
0614     if (((flags & GENERIC_EXECUTE) ||
0615             ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
0616             !(*pdenied & mask & 0111))
0617         *pmode |= mask & 0111;
0618 
0619     /* If DELETE_CHILD is set only on an owner ACE, set sticky bit */
0620     if (flags & FILE_DELETE_CHILD) {
0621         if (mask == ACL_OWNER_MASK) {
0622             if (!(*pdenied & 01000))
0623                 *pmode |= 01000;
0624         } else if (!(*pdenied & 01000)) {
0625             *pmode &= ~01000;
0626             *pdenied |= 01000;
0627         }
0628     }
0629 
0630     cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
0631     return;
0632 }
0633 
0634 /*
0635    Generate access flags to reflect permissions mode is the existing mode.
0636    This function is called for every ACE in the DACL whose SID matches
0637    with either owner or group or everyone.
0638 */
0639 
0640 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
0641                 __u32 *pace_flags)
0642 {
0643     /* reset access mask */
0644     *pace_flags = 0x0;
0645 
0646     /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
0647     mode &= bits_to_use;
0648 
0649     /* check for R/W/X UGO since we do not know whose flags
0650        is this but we have cleared all the bits sans RWX for
0651        either user or group or other as per bits_to_use */
0652     if (mode & S_IRUGO)
0653         *pace_flags |= SET_FILE_READ_RIGHTS;
0654     if (mode & S_IWUGO)
0655         *pace_flags |= SET_FILE_WRITE_RIGHTS;
0656     if (mode & S_IXUGO)
0657         *pace_flags |= SET_FILE_EXEC_RIGHTS;
0658 
0659     cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
0660          mode, *pace_flags);
0661     return;
0662 }
0663 
0664 static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct cifs_sid *psid)
0665 {
0666     __u16 size = 1 + 1 + 2 + 4;
0667 
0668     dst->type = src->type;
0669     dst->flags = src->flags;
0670     dst->access_req = src->access_req;
0671 
0672     /* Check if there's a replacement sid specified */
0673     if (psid)
0674         size += cifs_copy_sid(&dst->sid, psid);
0675     else
0676         size += cifs_copy_sid(&dst->sid, &src->sid);
0677 
0678     dst->size = cpu_to_le16(size);
0679 
0680     return size;
0681 }
0682 
0683 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
0684             const struct cifs_sid *psid, __u64 nmode,
0685             umode_t bits, __u8 access_type,
0686             bool allow_delete_child)
0687 {
0688     int i;
0689     __u16 size = 0;
0690     __u32 access_req = 0;
0691 
0692     pntace->type = access_type;
0693     pntace->flags = 0x0;
0694     mode_to_access_flags(nmode, bits, &access_req);
0695 
0696     if (access_type == ACCESS_ALLOWED && allow_delete_child)
0697         access_req |= FILE_DELETE_CHILD;
0698 
0699     if (access_type == ACCESS_ALLOWED && !access_req)
0700         access_req = SET_MINIMUM_RIGHTS;
0701     else if (access_type == ACCESS_DENIED)
0702         access_req &= ~SET_MINIMUM_RIGHTS;
0703 
0704     pntace->access_req = cpu_to_le32(access_req);
0705 
0706     pntace->sid.revision = psid->revision;
0707     pntace->sid.num_subauth = psid->num_subauth;
0708     for (i = 0; i < NUM_AUTHS; i++)
0709         pntace->sid.authority[i] = psid->authority[i];
0710     for (i = 0; i < psid->num_subauth; i++)
0711         pntace->sid.sub_auth[i] = psid->sub_auth[i];
0712 
0713     size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
0714     pntace->size = cpu_to_le16(size);
0715 
0716     return size;
0717 }
0718 
0719 
0720 #ifdef CONFIG_CIFS_DEBUG2
0721 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
0722 {
0723     int num_subauth;
0724 
0725     /* validate that we do not go past end of acl */
0726 
0727     if (le16_to_cpu(pace->size) < 16) {
0728         cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
0729         return;
0730     }
0731 
0732     if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
0733         cifs_dbg(VFS, "ACL too small to parse ACE\n");
0734         return;
0735     }
0736 
0737     num_subauth = pace->sid.num_subauth;
0738     if (num_subauth) {
0739         int i;
0740         cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
0741              pace->sid.revision, pace->sid.num_subauth, pace->type,
0742              pace->flags, le16_to_cpu(pace->size));
0743         for (i = 0; i < num_subauth; ++i) {
0744             cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
0745                  i, le32_to_cpu(pace->sid.sub_auth[i]));
0746         }
0747 
0748         /* BB add length check to make sure that we do not have huge
0749             num auths and therefore go off the end */
0750     }
0751 
0752     return;
0753 }
0754 #endif
0755 
0756 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
0757                struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
0758                struct cifs_fattr *fattr, bool mode_from_special_sid)
0759 {
0760     int i;
0761     int num_aces = 0;
0762     int acl_size;
0763     char *acl_base;
0764     struct cifs_ace **ppace;
0765 
0766     /* BB need to add parm so we can store the SID BB */
0767 
0768     if (!pdacl) {
0769         /* no DACL in the security descriptor, set
0770            all the permissions for user/group/other */
0771         fattr->cf_mode |= 0777;
0772         return;
0773     }
0774 
0775     /* validate that we do not go past end of acl */
0776     if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
0777         cifs_dbg(VFS, "ACL too small to parse DACL\n");
0778         return;
0779     }
0780 
0781     cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
0782          le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
0783          le32_to_cpu(pdacl->num_aces));
0784 
0785     /* reset rwx permissions for user/group/other.
0786        Also, if num_aces is 0 i.e. DACL has no ACEs,
0787        user/group/other have no permissions */
0788     fattr->cf_mode &= ~(0777);
0789 
0790     acl_base = (char *)pdacl;
0791     acl_size = sizeof(struct cifs_acl);
0792 
0793     num_aces = le32_to_cpu(pdacl->num_aces);
0794     if (num_aces > 0) {
0795         umode_t denied_mode = 0;
0796 
0797         if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
0798             return;
0799         ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
0800                       GFP_KERNEL);
0801         if (!ppace)
0802             return;
0803 
0804         for (i = 0; i < num_aces; ++i) {
0805             ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
0806 #ifdef CONFIG_CIFS_DEBUG2
0807             dump_ace(ppace[i], end_of_acl);
0808 #endif
0809             if (mode_from_special_sid &&
0810                 (compare_sids(&(ppace[i]->sid),
0811                       &sid_unix_NFS_mode) == 0)) {
0812                 /*
0813                  * Full permissions are:
0814                  * 07777 = S_ISUID | S_ISGID | S_ISVTX |
0815                  *         S_IRWXU | S_IRWXG | S_IRWXO
0816                  */
0817                 fattr->cf_mode &= ~07777;
0818                 fattr->cf_mode |=
0819                     le32_to_cpu(ppace[i]->sid.sub_auth[2]);
0820                 break;
0821             } else {
0822                 if (compare_sids(&(ppace[i]->sid), pownersid) == 0) {
0823                     access_flags_to_mode(ppace[i]->access_req,
0824                             ppace[i]->type,
0825                             &fattr->cf_mode,
0826                             &denied_mode,
0827                             ACL_OWNER_MASK);
0828                 } else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) {
0829                     access_flags_to_mode(ppace[i]->access_req,
0830                             ppace[i]->type,
0831                             &fattr->cf_mode,
0832                             &denied_mode,
0833                             ACL_GROUP_MASK);
0834                 } else if ((compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) ||
0835                         (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)) {
0836                     access_flags_to_mode(ppace[i]->access_req,
0837                             ppace[i]->type,
0838                             &fattr->cf_mode,
0839                             &denied_mode,
0840                             ACL_EVERYONE_MASK);
0841                 }
0842             }
0843 
0844 
0845 /*          memcpy((void *)(&(cifscred->aces[i])),
0846                 (void *)ppace[i],
0847                 sizeof(struct cifs_ace)); */
0848 
0849             acl_base = (char *)ppace[i];
0850             acl_size = le16_to_cpu(ppace[i]->size);
0851         }
0852 
0853         kfree(ppace);
0854     }
0855 
0856     return;
0857 }
0858 
0859 unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
0860 {
0861     int i;
0862     unsigned int ace_size = 20;
0863 
0864     pntace->type = ACCESS_ALLOWED_ACE_TYPE;
0865     pntace->flags = 0x0;
0866     pntace->access_req = cpu_to_le32(GENERIC_ALL);
0867     pntace->sid.num_subauth = 1;
0868     pntace->sid.revision = 1;
0869     for (i = 0; i < NUM_AUTHS; i++)
0870         pntace->sid.authority[i] =  sid_authusers.authority[i];
0871 
0872     pntace->sid.sub_auth[0] =  sid_authusers.sub_auth[0];
0873 
0874     /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
0875     pntace->size = cpu_to_le16(ace_size);
0876     return ace_size;
0877 }
0878 
0879 /*
0880  * Fill in the special SID based on the mode. See
0881  * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
0882  */
0883 unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
0884 {
0885     int i;
0886     unsigned int ace_size = 28;
0887 
0888     pntace->type = ACCESS_DENIED_ACE_TYPE;
0889     pntace->flags = 0x0;
0890     pntace->access_req = 0;
0891     pntace->sid.num_subauth = 3;
0892     pntace->sid.revision = 1;
0893     for (i = 0; i < NUM_AUTHS; i++)
0894         pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
0895 
0896     pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
0897     pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
0898     pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
0899 
0900     /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
0901     pntace->size = cpu_to_le16(ace_size);
0902     return ace_size;
0903 }
0904 
0905 unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
0906 {
0907     int i;
0908     unsigned int ace_size = 28;
0909 
0910     pntace->type = ACCESS_ALLOWED_ACE_TYPE;
0911     pntace->flags = 0x0;
0912     pntace->access_req = cpu_to_le32(GENERIC_ALL);
0913     pntace->sid.num_subauth = 3;
0914     pntace->sid.revision = 1;
0915     for (i = 0; i < NUM_AUTHS; i++)
0916         pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
0917 
0918     pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
0919     pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
0920     pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
0921 
0922     /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
0923     pntace->size = cpu_to_le16(ace_size);
0924     return ace_size;
0925 }
0926 
0927 static void populate_new_aces(char *nacl_base,
0928         struct cifs_sid *pownersid,
0929         struct cifs_sid *pgrpsid,
0930         __u64 *pnmode, u32 *pnum_aces, u16 *pnsize,
0931         bool modefromsid)
0932 {
0933     __u64 nmode;
0934     u32 num_aces = 0;
0935     u16 nsize = 0;
0936     __u64 user_mode;
0937     __u64 group_mode;
0938     __u64 other_mode;
0939     __u64 deny_user_mode = 0;
0940     __u64 deny_group_mode = 0;
0941     bool sticky_set = false;
0942     struct cifs_ace *pnntace = NULL;
0943 
0944     nmode = *pnmode;
0945     num_aces = *pnum_aces;
0946     nsize = *pnsize;
0947 
0948     if (modefromsid) {
0949         pnntace = (struct cifs_ace *) (nacl_base + nsize);
0950         nsize += setup_special_mode_ACE(pnntace, nmode);
0951         num_aces++;
0952         pnntace = (struct cifs_ace *) (nacl_base + nsize);
0953         nsize += setup_authusers_ACE(pnntace);
0954         num_aces++;
0955         goto set_size;
0956     }
0957 
0958     /*
0959      * We'll try to keep the mode as requested by the user.
0960      * But in cases where we cannot meaningfully convert that
0961      * into ACL, return back the updated mode, so that it is
0962      * updated in the inode.
0963      */
0964 
0965     if (!memcmp(pownersid, pgrpsid, sizeof(struct cifs_sid))) {
0966         /*
0967          * Case when owner and group SIDs are the same.
0968          * Set the more restrictive of the two modes.
0969          */
0970         user_mode = nmode & (nmode << 3) & 0700;
0971         group_mode = nmode & (nmode >> 3) & 0070;
0972     } else {
0973         user_mode = nmode & 0700;
0974         group_mode = nmode & 0070;
0975     }
0976 
0977     other_mode = nmode & 0007;
0978 
0979     /* We need DENY ACE when the perm is more restrictive than the next sets. */
0980     deny_user_mode = ~(user_mode) & ((group_mode << 3) | (other_mode << 6)) & 0700;
0981     deny_group_mode = ~(group_mode) & (other_mode << 3) & 0070;
0982 
0983     *pnmode = user_mode | group_mode | other_mode | (nmode & ~0777);
0984 
0985     /* This tells if we should allow delete child for group and everyone. */
0986     if (nmode & 01000)
0987         sticky_set = true;
0988 
0989     if (deny_user_mode) {
0990         pnntace = (struct cifs_ace *) (nacl_base + nsize);
0991         nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode,
0992                 0700, ACCESS_DENIED, false);
0993         num_aces++;
0994     }
0995 
0996     /* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/
0997     if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) {
0998         pnntace = (struct cifs_ace *) (nacl_base + nsize);
0999         nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1000                 0070, ACCESS_DENIED, false);
1001         num_aces++;
1002     }
1003 
1004     pnntace = (struct cifs_ace *) (nacl_base + nsize);
1005     nsize += fill_ace_for_sid(pnntace, pownersid, user_mode,
1006             0700, ACCESS_ALLOWED, true);
1007     num_aces++;
1008 
1009     /* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */
1010     if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) {
1011         pnntace = (struct cifs_ace *) (nacl_base + nsize);
1012         nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1013                 0070, ACCESS_DENIED, false);
1014         num_aces++;
1015     }
1016 
1017     pnntace = (struct cifs_ace *) (nacl_base + nsize);
1018     nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode,
1019             0070, ACCESS_ALLOWED, !sticky_set);
1020     num_aces++;
1021 
1022     pnntace = (struct cifs_ace *) (nacl_base + nsize);
1023     nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode,
1024             0007, ACCESS_ALLOWED, !sticky_set);
1025     num_aces++;
1026 
1027 set_size:
1028     *pnum_aces = num_aces;
1029     *pnsize = nsize;
1030 }
1031 
1032 static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
1033         struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
1034         struct cifs_sid *pnownersid, struct cifs_sid *pngrpsid)
1035 {
1036     int i;
1037     u16 size = 0;
1038     struct cifs_ace *pntace = NULL;
1039     char *acl_base = NULL;
1040     u32 src_num_aces = 0;
1041     u16 nsize = 0;
1042     struct cifs_ace *pnntace = NULL;
1043     char *nacl_base = NULL;
1044     u16 ace_size = 0;
1045 
1046     acl_base = (char *)pdacl;
1047     size = sizeof(struct cifs_acl);
1048     src_num_aces = le32_to_cpu(pdacl->num_aces);
1049 
1050     nacl_base = (char *)pndacl;
1051     nsize = sizeof(struct cifs_acl);
1052 
1053     /* Go through all the ACEs */
1054     for (i = 0; i < src_num_aces; ++i) {
1055         pntace = (struct cifs_ace *) (acl_base + size);
1056         pnntace = (struct cifs_ace *) (nacl_base + nsize);
1057 
1058         if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0)
1059             ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
1060         else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0)
1061             ace_size = cifs_copy_ace(pnntace, pntace, pngrpsid);
1062         else
1063             ace_size = cifs_copy_ace(pnntace, pntace, NULL);
1064 
1065         size += le16_to_cpu(pntace->size);
1066         nsize += ace_size;
1067     }
1068 
1069     return nsize;
1070 }
1071 
1072 static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
1073         struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
1074         __u64 *pnmode, bool mode_from_sid)
1075 {
1076     int i;
1077     u16 size = 0;
1078     struct cifs_ace *pntace = NULL;
1079     char *acl_base = NULL;
1080     u32 src_num_aces = 0;
1081     u16 nsize = 0;
1082     struct cifs_ace *pnntace = NULL;
1083     char *nacl_base = NULL;
1084     u32 num_aces = 0;
1085     bool new_aces_set = false;
1086 
1087     /* Assuming that pndacl and pnmode are never NULL */
1088     nacl_base = (char *)pndacl;
1089     nsize = sizeof(struct cifs_acl);
1090 
1091     /* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
1092     if (!pdacl) {
1093         populate_new_aces(nacl_base,
1094                 pownersid, pgrpsid,
1095                 pnmode, &num_aces, &nsize,
1096                 mode_from_sid);
1097         goto finalize_dacl;
1098     }
1099 
1100     acl_base = (char *)pdacl;
1101     size = sizeof(struct cifs_acl);
1102     src_num_aces = le32_to_cpu(pdacl->num_aces);
1103 
1104     /* Retain old ACEs which we can retain */
1105     for (i = 0; i < src_num_aces; ++i) {
1106         pntace = (struct cifs_ace *) (acl_base + size);
1107 
1108         if (!new_aces_set && (pntace->flags & INHERITED_ACE)) {
1109             /* Place the new ACEs in between existing explicit and inherited */
1110             populate_new_aces(nacl_base,
1111                     pownersid, pgrpsid,
1112                     pnmode, &num_aces, &nsize,
1113                     mode_from_sid);
1114 
1115             new_aces_set = true;
1116         }
1117 
1118         /* If it's any one of the ACE we're replacing, skip! */
1119         if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
1120                 (compare_sids(&pntace->sid, pownersid) == 0) ||
1121                 (compare_sids(&pntace->sid, pgrpsid) == 0) ||
1122                 (compare_sids(&pntace->sid, &sid_everyone) == 0) ||
1123                 (compare_sids(&pntace->sid, &sid_authusers) == 0))) {
1124             goto next_ace;
1125         }
1126 
1127         /* update the pointer to the next ACE to populate*/
1128         pnntace = (struct cifs_ace *) (nacl_base + nsize);
1129 
1130         nsize += cifs_copy_ace(pnntace, pntace, NULL);
1131         num_aces++;
1132 
1133 next_ace:
1134         size += le16_to_cpu(pntace->size);
1135     }
1136 
1137     /* If inherited ACEs are not present, place the new ones at the tail */
1138     if (!new_aces_set) {
1139         populate_new_aces(nacl_base,
1140                 pownersid, pgrpsid,
1141                 pnmode, &num_aces, &nsize,
1142                 mode_from_sid);
1143 
1144         new_aces_set = true;
1145     }
1146 
1147 finalize_dacl:
1148     pndacl->num_aces = cpu_to_le32(num_aces);
1149     pndacl->size = cpu_to_le16(nsize);
1150 
1151     return 0;
1152 }
1153 
1154 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
1155 {
1156     /* BB need to add parm so we can store the SID BB */
1157 
1158     /* validate that we do not go past end of ACL - sid must be at least 8
1159        bytes long (assuming no sub-auths - e.g. the null SID */
1160     if (end_of_acl < (char *)psid + 8) {
1161         cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
1162         return -EINVAL;
1163     }
1164 
1165 #ifdef CONFIG_CIFS_DEBUG2
1166     if (psid->num_subauth) {
1167         int i;
1168         cifs_dbg(FYI, "SID revision %d num_auth %d\n",
1169              psid->revision, psid->num_subauth);
1170 
1171         for (i = 0; i < psid->num_subauth; i++) {
1172             cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
1173                  i, le32_to_cpu(psid->sub_auth[i]));
1174         }
1175 
1176         /* BB add length check to make sure that we do not have huge
1177             num auths and therefore go off the end */
1178         cifs_dbg(FYI, "RID 0x%x\n",
1179              le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1180     }
1181 #endif
1182 
1183     return 0;
1184 }
1185 
1186 
1187 /* Convert CIFS ACL to POSIX form */
1188 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1189         struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
1190         bool get_mode_from_special_sid)
1191 {
1192     int rc = 0;
1193     struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1194     struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
1195     char *end_of_acl = ((char *)pntsd) + acl_len;
1196     __u32 dacloffset;
1197 
1198     if (pntsd == NULL)
1199         return -EIO;
1200 
1201     owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1202                 le32_to_cpu(pntsd->osidoffset));
1203     group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1204                 le32_to_cpu(pntsd->gsidoffset));
1205     dacloffset = le32_to_cpu(pntsd->dacloffset);
1206     dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1207     cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1208          pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1209          le32_to_cpu(pntsd->gsidoffset),
1210          le32_to_cpu(pntsd->sacloffset), dacloffset);
1211 /*  cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1212     rc = parse_sid(owner_sid_ptr, end_of_acl);
1213     if (rc) {
1214         cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1215         return rc;
1216     }
1217     rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1218     if (rc) {
1219         cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1220              __func__, rc);
1221         return rc;
1222     }
1223 
1224     rc = parse_sid(group_sid_ptr, end_of_acl);
1225     if (rc) {
1226         cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
1227              __func__, rc);
1228         return rc;
1229     }
1230     rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1231     if (rc) {
1232         cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1233              __func__, rc);
1234         return rc;
1235     }
1236 
1237     if (dacloffset)
1238         parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1239                group_sid_ptr, fattr, get_mode_from_special_sid);
1240     else
1241         cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
1242 
1243     return rc;
1244 }
1245 
1246 /* Convert permission bits from mode to equivalent CIFS ACL */
1247 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1248     __u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
1249     bool mode_from_sid, bool id_from_sid, int *aclflag)
1250 {
1251     int rc = 0;
1252     __u32 dacloffset;
1253     __u32 ndacloffset;
1254     __u32 sidsoffset;
1255     struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1256     struct cifs_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
1257     struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
1258     struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1259     char *end_of_acl = ((char *)pntsd) + secdesclen;
1260     u16 size = 0;
1261 
1262     dacloffset = le32_to_cpu(pntsd->dacloffset);
1263     if (dacloffset) {
1264         dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1265         if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) {
1266             cifs_dbg(VFS, "Server returned illegal ACL size\n");
1267             return -EINVAL;
1268         }
1269     }
1270 
1271     owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1272             le32_to_cpu(pntsd->osidoffset));
1273     group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1274             le32_to_cpu(pntsd->gsidoffset));
1275 
1276     if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1277         ndacloffset = sizeof(struct cifs_ntsd);
1278         ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1279         ndacl_ptr->revision =
1280             dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1281 
1282         ndacl_ptr->size = cpu_to_le16(0);
1283         ndacl_ptr->num_aces = cpu_to_le32(0);
1284 
1285         rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1286                     pnmode, mode_from_sid);
1287 
1288         sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1289         /* copy the non-dacl portion of secdesc */
1290         *pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1291                 NULL, NULL);
1292 
1293         *aclflag |= CIFS_ACL_DACL;
1294     } else {
1295         ndacloffset = sizeof(struct cifs_ntsd);
1296         ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1297         ndacl_ptr->revision =
1298             dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1299         ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0;
1300 
1301         if (uid_valid(uid)) { /* chown */
1302             uid_t id;
1303             nowner_sid_ptr = kzalloc(sizeof(struct cifs_sid),
1304                                 GFP_KERNEL);
1305             if (!nowner_sid_ptr) {
1306                 rc = -ENOMEM;
1307                 goto chown_chgrp_exit;
1308             }
1309             id = from_kuid(&init_user_ns, uid);
1310             if (id_from_sid) {
1311                 struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1312                 /* Populate the user ownership fields S-1-5-88-1 */
1313                 osid->Revision = 1;
1314                 osid->NumAuth = 3;
1315                 osid->Authority[5] = 5;
1316                 osid->SubAuthorities[0] = cpu_to_le32(88);
1317                 osid->SubAuthorities[1] = cpu_to_le32(1);
1318                 osid->SubAuthorities[2] = cpu_to_le32(id);
1319 
1320             } else { /* lookup sid with upcall */
1321                 rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1322                 if (rc) {
1323                     cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1324                          __func__, rc, id);
1325                     goto chown_chgrp_exit;
1326                 }
1327             }
1328             *aclflag |= CIFS_ACL_OWNER;
1329         }
1330         if (gid_valid(gid)) { /* chgrp */
1331             gid_t id;
1332             ngroup_sid_ptr = kzalloc(sizeof(struct cifs_sid),
1333                                 GFP_KERNEL);
1334             if (!ngroup_sid_ptr) {
1335                 rc = -ENOMEM;
1336                 goto chown_chgrp_exit;
1337             }
1338             id = from_kgid(&init_user_ns, gid);
1339             if (id_from_sid) {
1340                 struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1341                 /* Populate the group ownership fields S-1-5-88-2 */
1342                 gsid->Revision = 1;
1343                 gsid->NumAuth = 3;
1344                 gsid->Authority[5] = 5;
1345                 gsid->SubAuthorities[0] = cpu_to_le32(88);
1346                 gsid->SubAuthorities[1] = cpu_to_le32(2);
1347                 gsid->SubAuthorities[2] = cpu_to_le32(id);
1348 
1349             } else { /* lookup sid with upcall */
1350                 rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1351                 if (rc) {
1352                     cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1353                          __func__, rc, id);
1354                     goto chown_chgrp_exit;
1355                 }
1356             }
1357             *aclflag |= CIFS_ACL_GROUP;
1358         }
1359 
1360         if (dacloffset) {
1361             /* Replace ACEs for old owner with new one */
1362             size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1363                     owner_sid_ptr, group_sid_ptr,
1364                     nowner_sid_ptr, ngroup_sid_ptr);
1365             ndacl_ptr->size = cpu_to_le16(size);
1366         }
1367 
1368         sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1369         /* copy the non-dacl portion of secdesc */
1370         *pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1371                 nowner_sid_ptr, ngroup_sid_ptr);
1372 
1373 chown_chgrp_exit:
1374         /* errors could jump here. So make sure we return soon after this */
1375         kfree(nowner_sid_ptr);
1376         kfree(ngroup_sid_ptr);
1377     }
1378 
1379     return rc;
1380 }
1381 
1382 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1383 struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1384                       const struct cifs_fid *cifsfid, u32 *pacllen,
1385                       u32 __maybe_unused unused)
1386 {
1387     struct cifs_ntsd *pntsd = NULL;
1388     unsigned int xid;
1389     int rc;
1390     struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1391 
1392     if (IS_ERR(tlink))
1393         return ERR_CAST(tlink);
1394 
1395     xid = get_xid();
1396     rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1397                 pacllen);
1398     free_xid(xid);
1399 
1400     cifs_put_tlink(tlink);
1401 
1402     cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1403     if (rc)
1404         return ERR_PTR(rc);
1405     return pntsd;
1406 }
1407 
1408 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1409         const char *path, u32 *pacllen)
1410 {
1411     struct cifs_ntsd *pntsd = NULL;
1412     int oplock = 0;
1413     unsigned int xid;
1414     int rc;
1415     struct cifs_tcon *tcon;
1416     struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1417     struct cifs_fid fid;
1418     struct cifs_open_parms oparms;
1419 
1420     if (IS_ERR(tlink))
1421         return ERR_CAST(tlink);
1422 
1423     tcon = tlink_tcon(tlink);
1424     xid = get_xid();
1425 
1426     oparms.tcon = tcon;
1427     oparms.cifs_sb = cifs_sb;
1428     oparms.desired_access = READ_CONTROL;
1429     oparms.create_options = cifs_create_options(cifs_sb, 0);
1430     oparms.disposition = FILE_OPEN;
1431     oparms.path = path;
1432     oparms.fid = &fid;
1433     oparms.reconnect = false;
1434 
1435     rc = CIFS_open(xid, &oparms, &oplock, NULL);
1436     if (!rc) {
1437         rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1438         CIFSSMBClose(xid, tcon, fid.netfid);
1439     }
1440 
1441     cifs_put_tlink(tlink);
1442     free_xid(xid);
1443 
1444     cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1445     if (rc)
1446         return ERR_PTR(rc);
1447     return pntsd;
1448 }
1449 
1450 /* Retrieve an ACL from the server */
1451 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1452                       struct inode *inode, const char *path,
1453                    u32 *pacllen, u32 info)
1454 {
1455     struct cifs_ntsd *pntsd = NULL;
1456     struct cifsFileInfo *open_file = NULL;
1457 
1458     if (inode)
1459         open_file = find_readable_file(CIFS_I(inode), true);
1460     if (!open_file)
1461         return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1462 
1463     pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1464     cifsFileInfo_put(open_file);
1465     return pntsd;
1466 }
1467 
1468  /* Set an ACL on the server */
1469 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1470             struct inode *inode, const char *path, int aclflag)
1471 {
1472     int oplock = 0;
1473     unsigned int xid;
1474     int rc, access_flags;
1475     struct cifs_tcon *tcon;
1476     struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1477     struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1478     struct cifs_fid fid;
1479     struct cifs_open_parms oparms;
1480 
1481     if (IS_ERR(tlink))
1482         return PTR_ERR(tlink);
1483 
1484     tcon = tlink_tcon(tlink);
1485     xid = get_xid();
1486 
1487     if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1488         access_flags = WRITE_OWNER;
1489     else
1490         access_flags = WRITE_DAC;
1491 
1492     oparms.tcon = tcon;
1493     oparms.cifs_sb = cifs_sb;
1494     oparms.desired_access = access_flags;
1495     oparms.create_options = cifs_create_options(cifs_sb, 0);
1496     oparms.disposition = FILE_OPEN;
1497     oparms.path = path;
1498     oparms.fid = &fid;
1499     oparms.reconnect = false;
1500 
1501     rc = CIFS_open(xid, &oparms, &oplock, NULL);
1502     if (rc) {
1503         cifs_dbg(VFS, "Unable to open file to set ACL\n");
1504         goto out;
1505     }
1506 
1507     rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1508     cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1509 
1510     CIFSSMBClose(xid, tcon, fid.netfid);
1511 out:
1512     free_xid(xid);
1513     cifs_put_tlink(tlink);
1514     return rc;
1515 }
1516 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1517 
1518 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1519 int
1520 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1521           struct inode *inode, bool mode_from_special_sid,
1522           const char *path, const struct cifs_fid *pfid)
1523 {
1524     struct cifs_ntsd *pntsd = NULL;
1525     u32 acllen = 0;
1526     int rc = 0;
1527     struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1528     struct smb_version_operations *ops;
1529     const u32 info = 0;
1530 
1531     cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1532 
1533     if (IS_ERR(tlink))
1534         return PTR_ERR(tlink);
1535 
1536     ops = tlink_tcon(tlink)->ses->server->ops;
1537 
1538     if (pfid && (ops->get_acl_by_fid))
1539         pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1540     else if (ops->get_acl)
1541         pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1542     else {
1543         cifs_put_tlink(tlink);
1544         return -EOPNOTSUPP;
1545     }
1546     /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1547     if (IS_ERR(pntsd)) {
1548         rc = PTR_ERR(pntsd);
1549         cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1550     } else if (mode_from_special_sid) {
1551         rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1552         kfree(pntsd);
1553     } else {
1554         /* get approximated mode from ACL */
1555         rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1556         kfree(pntsd);
1557         if (rc)
1558             cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1559     }
1560 
1561     cifs_put_tlink(tlink);
1562 
1563     return rc;
1564 }
1565 
1566 /* Convert mode bits to an ACL so we can update the ACL on the server */
1567 int
1568 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1569             kuid_t uid, kgid_t gid)
1570 {
1571     int rc = 0;
1572     int aclflag = CIFS_ACL_DACL; /* default flag to set */
1573     __u32 secdesclen = 0;
1574     __u32 nsecdesclen = 0;
1575     __u32 dacloffset = 0;
1576     struct cifs_acl *dacl_ptr = NULL;
1577     struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1578     struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1579     struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1580     struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1581     struct smb_version_operations *ops;
1582     bool mode_from_sid, id_from_sid;
1583     const u32 info = 0;
1584 
1585     if (IS_ERR(tlink))
1586         return PTR_ERR(tlink);
1587 
1588     ops = tlink_tcon(tlink)->ses->server->ops;
1589 
1590     cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1591 
1592     /* Get the security descriptor */
1593 
1594     if (ops->get_acl == NULL) {
1595         cifs_put_tlink(tlink);
1596         return -EOPNOTSUPP;
1597     }
1598 
1599     pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1600     if (IS_ERR(pntsd)) {
1601         rc = PTR_ERR(pntsd);
1602         cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1603         cifs_put_tlink(tlink);
1604         return rc;
1605     }
1606 
1607     if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1608         mode_from_sid = true;
1609     else
1610         mode_from_sid = false;
1611 
1612     if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1613         id_from_sid = true;
1614     else
1615         id_from_sid = false;
1616 
1617     /* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1618     nsecdesclen = secdesclen;
1619     if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1620         if (mode_from_sid)
1621             nsecdesclen += 2 * sizeof(struct cifs_ace);
1622         else /* cifsacl */
1623             nsecdesclen += 5 * sizeof(struct cifs_ace);
1624     } else { /* chown */
1625         /* When ownership changes, changes new owner sid length could be different */
1626         nsecdesclen = sizeof(struct cifs_ntsd) + (sizeof(struct cifs_sid) * 2);
1627         dacloffset = le32_to_cpu(pntsd->dacloffset);
1628         if (dacloffset) {
1629             dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1630             if (mode_from_sid)
1631                 nsecdesclen +=
1632                     le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace);
1633             else /* cifsacl */
1634                 nsecdesclen += le16_to_cpu(dacl_ptr->size);
1635         }
1636     }
1637 
1638     /*
1639      * Add three ACEs for owner, group, everyone getting rid of other ACEs
1640      * as chmod disables ACEs and set the security descriptor. Allocate
1641      * memory for the smb header, set security descriptor request security
1642      * descriptor parameters, and security descriptor itself
1643      */
1644     nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1645     pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);
1646     if (!pnntsd) {
1647         kfree(pntsd);
1648         cifs_put_tlink(tlink);
1649         return -ENOMEM;
1650     }
1651 
1652     rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1653                 mode_from_sid, id_from_sid, &aclflag);
1654 
1655     cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1656 
1657     if (ops->set_acl == NULL)
1658         rc = -EOPNOTSUPP;
1659 
1660     if (!rc) {
1661         /* Set the security descriptor */
1662         rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1663         cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1664     }
1665     cifs_put_tlink(tlink);
1666 
1667     kfree(pnntsd);
1668     kfree(pntsd);
1669     return rc;
1670 }