Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: LGPL-2.1+
0002 /*
0003  *   Copyright (C) International Business Machines  Corp., 2007,2008
0004  *   Author(s): Steve French (sfrench@us.ibm.com)
0005  *   Copyright (C) 2020 Samsung Electronics Co., Ltd.
0006  *   Author(s): Namjae Jeon <linkinjeon@kernel.org>
0007  */
0008 
0009 #include <linux/fs.h>
0010 #include <linux/slab.h>
0011 #include <linux/string.h>
0012 #include <linux/mnt_idmapping.h>
0013 
0014 #include "smbacl.h"
0015 #include "smb_common.h"
0016 #include "server.h"
0017 #include "misc.h"
0018 #include "mgmt/share_config.h"
0019 
0020 static const struct smb_sid domain = {1, 4, {0, 0, 0, 0, 0, 5},
0021     {cpu_to_le32(21), cpu_to_le32(1), cpu_to_le32(2), cpu_to_le32(3),
0022     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0023 
0024 /* security id for everyone/world system group */
0025 static const struct smb_sid creator_owner = {
0026     1, 1, {0, 0, 0, 0, 0, 3}, {0} };
0027 /* security id for everyone/world system group */
0028 static const struct smb_sid creator_group = {
0029     1, 1, {0, 0, 0, 0, 0, 3}, {cpu_to_le32(1)} };
0030 
0031 /* security id for everyone/world system group */
0032 static const struct smb_sid sid_everyone = {
0033     1, 1, {0, 0, 0, 0, 0, 1}, {0} };
0034 /* security id for Authenticated Users system group */
0035 static const struct smb_sid sid_authusers = {
0036     1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
0037 
0038 /* S-1-22-1 Unmapped Unix users */
0039 static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
0040         {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0041 
0042 /* S-1-22-2 Unmapped Unix groups */
0043 static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
0044         {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0045 
0046 /*
0047  * See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
0048  */
0049 
0050 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
0051 
0052 /* S-1-5-88-1 Unix uid */
0053 static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
0054     {cpu_to_le32(88),
0055      cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0056 
0057 /* S-1-5-88-2 Unix gid */
0058 static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
0059     {cpu_to_le32(88),
0060      cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0061 
0062 /* S-1-5-88-3 Unix mode */
0063 static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
0064     {cpu_to_le32(88),
0065      cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0066 
0067 /*
0068  * if the two SIDs (roughly equivalent to a UUID for a user or group) are
0069  * the same returns zero, if they do not match returns non-zero.
0070  */
0071 int compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
0072 {
0073     int i;
0074     int num_subauth, num_sat, num_saw;
0075 
0076     if (!ctsid || !cwsid)
0077         return 1;
0078 
0079     /* compare the revision */
0080     if (ctsid->revision != cwsid->revision) {
0081         if (ctsid->revision > cwsid->revision)
0082             return 1;
0083         else
0084             return -1;
0085     }
0086 
0087     /* compare all of the six auth values */
0088     for (i = 0; i < NUM_AUTHS; ++i) {
0089         if (ctsid->authority[i] != cwsid->authority[i]) {
0090             if (ctsid->authority[i] > cwsid->authority[i])
0091                 return 1;
0092             else
0093                 return -1;
0094         }
0095     }
0096 
0097     /* compare all of the subauth values if any */
0098     num_sat = ctsid->num_subauth;
0099     num_saw = cwsid->num_subauth;
0100     num_subauth = num_sat < num_saw ? num_sat : num_saw;
0101     if (num_subauth) {
0102         for (i = 0; i < num_subauth; ++i) {
0103             if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
0104                 if (le32_to_cpu(ctsid->sub_auth[i]) >
0105                     le32_to_cpu(cwsid->sub_auth[i]))
0106                     return 1;
0107                 else
0108                     return -1;
0109             }
0110         }
0111     }
0112 
0113     return 0; /* sids compare/match */
0114 }
0115 
0116 static void smb_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
0117 {
0118     int i;
0119 
0120     dst->revision = src->revision;
0121     dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
0122     for (i = 0; i < NUM_AUTHS; ++i)
0123         dst->authority[i] = src->authority[i];
0124     for (i = 0; i < dst->num_subauth; ++i)
0125         dst->sub_auth[i] = src->sub_auth[i];
0126 }
0127 
0128 /*
0129  * change posix mode to reflect permissions
0130  * pmode is the existing mode (we only want to overwrite part of this
0131  * bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
0132  */
0133 static umode_t access_flags_to_mode(struct smb_fattr *fattr, __le32 ace_flags,
0134                     int type)
0135 {
0136     __u32 flags = le32_to_cpu(ace_flags);
0137     umode_t mode = 0;
0138 
0139     if (flags & GENERIC_ALL) {
0140         mode = 0777;
0141         ksmbd_debug(SMB, "all perms\n");
0142         return mode;
0143     }
0144 
0145     if ((flags & GENERIC_READ) || (flags & FILE_READ_RIGHTS))
0146         mode = 0444;
0147     if ((flags & GENERIC_WRITE) || (flags & FILE_WRITE_RIGHTS)) {
0148         mode |= 0222;
0149         if (S_ISDIR(fattr->cf_mode))
0150             mode |= 0111;
0151     }
0152     if ((flags & GENERIC_EXECUTE) || (flags & FILE_EXEC_RIGHTS))
0153         mode |= 0111;
0154 
0155     if (type == ACCESS_DENIED_ACE_TYPE || type == ACCESS_DENIED_OBJECT_ACE_TYPE)
0156         mode = ~mode;
0157 
0158     ksmbd_debug(SMB, "access flags 0x%x mode now %04o\n", flags, mode);
0159 
0160     return mode;
0161 }
0162 
0163 /*
0164  * Generate access flags to reflect permissions mode is the existing mode.
0165  * This function is called for every ACE in the DACL whose SID matches
0166  * with either owner or group or everyone.
0167  */
0168 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
0169                  __u32 *pace_flags)
0170 {
0171     /* reset access mask */
0172     *pace_flags = 0x0;
0173 
0174     /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
0175     mode &= bits_to_use;
0176 
0177     /*
0178      * check for R/W/X UGO since we do not know whose flags
0179      * is this but we have cleared all the bits sans RWX for
0180      * either user or group or other as per bits_to_use
0181      */
0182     if (mode & 0444)
0183         *pace_flags |= SET_FILE_READ_RIGHTS;
0184     if (mode & 0222)
0185         *pace_flags |= FILE_WRITE_RIGHTS;
0186     if (mode & 0111)
0187         *pace_flags |= SET_FILE_EXEC_RIGHTS;
0188 
0189     ksmbd_debug(SMB, "mode: %o, access flags now 0x%x\n",
0190             mode, *pace_flags);
0191 }
0192 
0193 static __u16 fill_ace_for_sid(struct smb_ace *pntace,
0194                   const struct smb_sid *psid, int type, int flags,
0195                   umode_t mode, umode_t bits)
0196 {
0197     int i;
0198     __u16 size = 0;
0199     __u32 access_req = 0;
0200 
0201     pntace->type = type;
0202     pntace->flags = flags;
0203     mode_to_access_flags(mode, bits, &access_req);
0204     if (!access_req)
0205         access_req = SET_MINIMUM_RIGHTS;
0206     pntace->access_req = cpu_to_le32(access_req);
0207 
0208     pntace->sid.revision = psid->revision;
0209     pntace->sid.num_subauth = psid->num_subauth;
0210     for (i = 0; i < NUM_AUTHS; i++)
0211         pntace->sid.authority[i] = psid->authority[i];
0212     for (i = 0; i < psid->num_subauth; i++)
0213         pntace->sid.sub_auth[i] = psid->sub_auth[i];
0214 
0215     size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
0216     pntace->size = cpu_to_le16(size);
0217 
0218     return size;
0219 }
0220 
0221 void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
0222 {
0223     switch (sidtype) {
0224     case SIDOWNER:
0225         smb_copy_sid(ssid, &server_conf.domain_sid);
0226         break;
0227     case SIDUNIX_USER:
0228         smb_copy_sid(ssid, &sid_unix_users);
0229         break;
0230     case SIDUNIX_GROUP:
0231         smb_copy_sid(ssid, &sid_unix_groups);
0232         break;
0233     case SIDCREATOR_OWNER:
0234         smb_copy_sid(ssid, &creator_owner);
0235         return;
0236     case SIDCREATOR_GROUP:
0237         smb_copy_sid(ssid, &creator_group);
0238         return;
0239     case SIDNFS_USER:
0240         smb_copy_sid(ssid, &sid_unix_NFS_users);
0241         break;
0242     case SIDNFS_GROUP:
0243         smb_copy_sid(ssid, &sid_unix_NFS_groups);
0244         break;
0245     case SIDNFS_MODE:
0246         smb_copy_sid(ssid, &sid_unix_NFS_mode);
0247         break;
0248     default:
0249         return;
0250     }
0251 
0252     /* RID */
0253     ssid->sub_auth[ssid->num_subauth] = cpu_to_le32(cid);
0254     ssid->num_subauth++;
0255 }
0256 
0257 static int sid_to_id(struct user_namespace *user_ns,
0258              struct smb_sid *psid, uint sidtype,
0259              struct smb_fattr *fattr)
0260 {
0261     int rc = -EINVAL;
0262 
0263     /*
0264      * If we have too many subauthorities, then something is really wrong.
0265      * Just return an error.
0266      */
0267     if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
0268         pr_err("%s: %u subauthorities is too many!\n",
0269                __func__, psid->num_subauth);
0270         return -EIO;
0271     }
0272 
0273     if (sidtype == SIDOWNER) {
0274         kuid_t uid;
0275         uid_t id;
0276 
0277         id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
0278         uid = mapped_kuid_user(user_ns, &init_user_ns, KUIDT_INIT(id));
0279         if (uid_valid(uid)) {
0280             fattr->cf_uid = uid;
0281             rc = 0;
0282         }
0283     } else {
0284         kgid_t gid;
0285         gid_t id;
0286 
0287         id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
0288         gid = mapped_kgid_user(user_ns, &init_user_ns, KGIDT_INIT(id));
0289         if (gid_valid(gid)) {
0290             fattr->cf_gid = gid;
0291             rc = 0;
0292         }
0293     }
0294 
0295     return rc;
0296 }
0297 
0298 void posix_state_to_acl(struct posix_acl_state *state,
0299             struct posix_acl_entry *pace)
0300 {
0301     int i;
0302 
0303     pace->e_tag = ACL_USER_OBJ;
0304     pace->e_perm = state->owner.allow;
0305     for (i = 0; i < state->users->n; i++) {
0306         pace++;
0307         pace->e_tag = ACL_USER;
0308         pace->e_uid = state->users->aces[i].uid;
0309         pace->e_perm = state->users->aces[i].perms.allow;
0310     }
0311 
0312     pace++;
0313     pace->e_tag = ACL_GROUP_OBJ;
0314     pace->e_perm = state->group.allow;
0315 
0316     for (i = 0; i < state->groups->n; i++) {
0317         pace++;
0318         pace->e_tag = ACL_GROUP;
0319         pace->e_gid = state->groups->aces[i].gid;
0320         pace->e_perm = state->groups->aces[i].perms.allow;
0321     }
0322 
0323     if (state->users->n || state->groups->n) {
0324         pace++;
0325         pace->e_tag = ACL_MASK;
0326         pace->e_perm = state->mask.allow;
0327     }
0328 
0329     pace++;
0330     pace->e_tag = ACL_OTHER;
0331     pace->e_perm = state->other.allow;
0332 }
0333 
0334 int init_acl_state(struct posix_acl_state *state, int cnt)
0335 {
0336     int alloc;
0337 
0338     memset(state, 0, sizeof(struct posix_acl_state));
0339     /*
0340      * In the worst case, each individual acl could be for a distinct
0341      * named user or group, but we don't know which, so we allocate
0342      * enough space for either:
0343      */
0344     alloc = sizeof(struct posix_ace_state_array)
0345         + cnt * sizeof(struct posix_user_ace_state);
0346     state->users = kzalloc(alloc, GFP_KERNEL);
0347     if (!state->users)
0348         return -ENOMEM;
0349     state->groups = kzalloc(alloc, GFP_KERNEL);
0350     if (!state->groups) {
0351         kfree(state->users);
0352         return -ENOMEM;
0353     }
0354     return 0;
0355 }
0356 
0357 void free_acl_state(struct posix_acl_state *state)
0358 {
0359     kfree(state->users);
0360     kfree(state->groups);
0361 }
0362 
0363 static void parse_dacl(struct user_namespace *user_ns,
0364                struct smb_acl *pdacl, char *end_of_acl,
0365                struct smb_sid *pownersid, struct smb_sid *pgrpsid,
0366                struct smb_fattr *fattr)
0367 {
0368     int i, ret;
0369     int num_aces = 0;
0370     unsigned int acl_size;
0371     char *acl_base;
0372     struct smb_ace **ppace;
0373     struct posix_acl_entry *cf_pace, *cf_pdace;
0374     struct posix_acl_state acl_state, default_acl_state;
0375     umode_t mode = 0, acl_mode;
0376     bool owner_found = false, group_found = false, others_found = false;
0377 
0378     if (!pdacl)
0379         return;
0380 
0381     /* validate that we do not go past end of acl */
0382     if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl) ||
0383         end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
0384         pr_err("ACL too small to parse DACL\n");
0385         return;
0386     }
0387 
0388     ksmbd_debug(SMB, "DACL revision %d size %d num aces %d\n",
0389             le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
0390             le32_to_cpu(pdacl->num_aces));
0391 
0392     acl_base = (char *)pdacl;
0393     acl_size = sizeof(struct smb_acl);
0394 
0395     num_aces = le32_to_cpu(pdacl->num_aces);
0396     if (num_aces <= 0)
0397         return;
0398 
0399     if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
0400         return;
0401 
0402     ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), GFP_KERNEL);
0403     if (!ppace)
0404         return;
0405 
0406     ret = init_acl_state(&acl_state, num_aces);
0407     if (ret)
0408         return;
0409     ret = init_acl_state(&default_acl_state, num_aces);
0410     if (ret) {
0411         free_acl_state(&acl_state);
0412         return;
0413     }
0414 
0415     /*
0416      * reset rwx permissions for user/group/other.
0417      * Also, if num_aces is 0 i.e. DACL has no ACEs,
0418      * user/group/other have no permissions
0419      */
0420     for (i = 0; i < num_aces; ++i) {
0421         if (end_of_acl - acl_base < acl_size)
0422             break;
0423 
0424         ppace[i] = (struct smb_ace *)(acl_base + acl_size);
0425         acl_base = (char *)ppace[i];
0426         acl_size = offsetof(struct smb_ace, sid) +
0427             offsetof(struct smb_sid, sub_auth);
0428 
0429         if (end_of_acl - acl_base < acl_size ||
0430             ppace[i]->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
0431             (end_of_acl - acl_base <
0432              acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) ||
0433             (le16_to_cpu(ppace[i]->size) <
0434              acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth))
0435             break;
0436 
0437         acl_size = le16_to_cpu(ppace[i]->size);
0438         ppace[i]->access_req =
0439             smb_map_generic_desired_access(ppace[i]->access_req);
0440 
0441         if (!(compare_sids(&ppace[i]->sid, &sid_unix_NFS_mode))) {
0442             fattr->cf_mode =
0443                 le32_to_cpu(ppace[i]->sid.sub_auth[2]);
0444             break;
0445         } else if (!compare_sids(&ppace[i]->sid, pownersid)) {
0446             acl_mode = access_flags_to_mode(fattr,
0447                             ppace[i]->access_req,
0448                             ppace[i]->type);
0449             acl_mode &= 0700;
0450 
0451             if (!owner_found) {
0452                 mode &= ~(0700);
0453                 mode |= acl_mode;
0454             }
0455             owner_found = true;
0456         } else if (!compare_sids(&ppace[i]->sid, pgrpsid) ||
0457                ppace[i]->sid.sub_auth[ppace[i]->sid.num_subauth - 1] ==
0458                 DOMAIN_USER_RID_LE) {
0459             acl_mode = access_flags_to_mode(fattr,
0460                             ppace[i]->access_req,
0461                             ppace[i]->type);
0462             acl_mode &= 0070;
0463             if (!group_found) {
0464                 mode &= ~(0070);
0465                 mode |= acl_mode;
0466             }
0467             group_found = true;
0468         } else if (!compare_sids(&ppace[i]->sid, &sid_everyone)) {
0469             acl_mode = access_flags_to_mode(fattr,
0470                             ppace[i]->access_req,
0471                             ppace[i]->type);
0472             acl_mode &= 0007;
0473             if (!others_found) {
0474                 mode &= ~(0007);
0475                 mode |= acl_mode;
0476             }
0477             others_found = true;
0478         } else if (!compare_sids(&ppace[i]->sid, &creator_owner)) {
0479             continue;
0480         } else if (!compare_sids(&ppace[i]->sid, &creator_group)) {
0481             continue;
0482         } else if (!compare_sids(&ppace[i]->sid, &sid_authusers)) {
0483             continue;
0484         } else {
0485             struct smb_fattr temp_fattr;
0486 
0487             acl_mode = access_flags_to_mode(fattr, ppace[i]->access_req,
0488                             ppace[i]->type);
0489             temp_fattr.cf_uid = INVALID_UID;
0490             ret = sid_to_id(user_ns, &ppace[i]->sid, SIDOWNER, &temp_fattr);
0491             if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) {
0492                 pr_err("%s: Error %d mapping Owner SID to uid\n",
0493                        __func__, ret);
0494                 continue;
0495             }
0496 
0497             acl_state.owner.allow = ((acl_mode & 0700) >> 6) | 0004;
0498             acl_state.users->aces[acl_state.users->n].uid =
0499                 temp_fattr.cf_uid;
0500             acl_state.users->aces[acl_state.users->n++].perms.allow =
0501                 ((acl_mode & 0700) >> 6) | 0004;
0502             default_acl_state.owner.allow = ((acl_mode & 0700) >> 6) | 0004;
0503             default_acl_state.users->aces[default_acl_state.users->n].uid =
0504                 temp_fattr.cf_uid;
0505             default_acl_state.users->aces[default_acl_state.users->n++].perms.allow =
0506                 ((acl_mode & 0700) >> 6) | 0004;
0507         }
0508     }
0509     kfree(ppace);
0510 
0511     if (owner_found) {
0512         /* The owner must be set to at least read-only. */
0513         acl_state.owner.allow = ((mode & 0700) >> 6) | 0004;
0514         acl_state.users->aces[acl_state.users->n].uid = fattr->cf_uid;
0515         acl_state.users->aces[acl_state.users->n++].perms.allow =
0516             ((mode & 0700) >> 6) | 0004;
0517         default_acl_state.owner.allow = ((mode & 0700) >> 6) | 0004;
0518         default_acl_state.users->aces[default_acl_state.users->n].uid =
0519             fattr->cf_uid;
0520         default_acl_state.users->aces[default_acl_state.users->n++].perms.allow =
0521             ((mode & 0700) >> 6) | 0004;
0522     }
0523 
0524     if (group_found) {
0525         acl_state.group.allow = (mode & 0070) >> 3;
0526         acl_state.groups->aces[acl_state.groups->n].gid =
0527             fattr->cf_gid;
0528         acl_state.groups->aces[acl_state.groups->n++].perms.allow =
0529             (mode & 0070) >> 3;
0530         default_acl_state.group.allow = (mode & 0070) >> 3;
0531         default_acl_state.groups->aces[default_acl_state.groups->n].gid =
0532             fattr->cf_gid;
0533         default_acl_state.groups->aces[default_acl_state.groups->n++].perms.allow =
0534             (mode & 0070) >> 3;
0535     }
0536 
0537     if (others_found) {
0538         fattr->cf_mode &= ~(0007);
0539         fattr->cf_mode |= mode & 0007;
0540 
0541         acl_state.other.allow = mode & 0007;
0542         default_acl_state.other.allow = mode & 0007;
0543     }
0544 
0545     if (acl_state.users->n || acl_state.groups->n) {
0546         acl_state.mask.allow = 0x07;
0547 
0548         if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
0549             fattr->cf_acls =
0550                 posix_acl_alloc(acl_state.users->n +
0551                     acl_state.groups->n + 4, GFP_KERNEL);
0552             if (fattr->cf_acls) {
0553                 cf_pace = fattr->cf_acls->a_entries;
0554                 posix_state_to_acl(&acl_state, cf_pace);
0555             }
0556         }
0557     }
0558 
0559     if (default_acl_state.users->n || default_acl_state.groups->n) {
0560         default_acl_state.mask.allow = 0x07;
0561 
0562         if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
0563             fattr->cf_dacls =
0564                 posix_acl_alloc(default_acl_state.users->n +
0565                 default_acl_state.groups->n + 4, GFP_KERNEL);
0566             if (fattr->cf_dacls) {
0567                 cf_pdace = fattr->cf_dacls->a_entries;
0568                 posix_state_to_acl(&default_acl_state, cf_pdace);
0569             }
0570         }
0571     }
0572     free_acl_state(&acl_state);
0573     free_acl_state(&default_acl_state);
0574 }
0575 
0576 static void set_posix_acl_entries_dacl(struct user_namespace *user_ns,
0577                        struct smb_ace *pndace,
0578                        struct smb_fattr *fattr, u32 *num_aces,
0579                        u16 *size, u32 nt_aces_num)
0580 {
0581     struct posix_acl_entry *pace;
0582     struct smb_sid *sid;
0583     struct smb_ace *ntace;
0584     int i, j;
0585 
0586     if (!fattr->cf_acls)
0587         goto posix_default_acl;
0588 
0589     pace = fattr->cf_acls->a_entries;
0590     for (i = 0; i < fattr->cf_acls->a_count; i++, pace++) {
0591         int flags = 0;
0592 
0593         sid = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
0594         if (!sid)
0595             break;
0596 
0597         if (pace->e_tag == ACL_USER) {
0598             uid_t uid;
0599             unsigned int sid_type = SIDOWNER;
0600 
0601             uid = posix_acl_uid_translate(user_ns, pace);
0602             if (!uid)
0603                 sid_type = SIDUNIX_USER;
0604             id_to_sid(uid, sid_type, sid);
0605         } else if (pace->e_tag == ACL_GROUP) {
0606             gid_t gid;
0607 
0608             gid = posix_acl_gid_translate(user_ns, pace);
0609             id_to_sid(gid, SIDUNIX_GROUP, sid);
0610         } else if (pace->e_tag == ACL_OTHER && !nt_aces_num) {
0611             smb_copy_sid(sid, &sid_everyone);
0612         } else {
0613             kfree(sid);
0614             continue;
0615         }
0616         ntace = pndace;
0617         for (j = 0; j < nt_aces_num; j++) {
0618             if (ntace->sid.sub_auth[ntace->sid.num_subauth - 1] ==
0619                     sid->sub_auth[sid->num_subauth - 1])
0620                 goto pass_same_sid;
0621             ntace = (struct smb_ace *)((char *)ntace +
0622                     le16_to_cpu(ntace->size));
0623         }
0624 
0625         if (S_ISDIR(fattr->cf_mode) && pace->e_tag == ACL_OTHER)
0626             flags = 0x03;
0627 
0628         ntace = (struct smb_ace *)((char *)pndace + *size);
0629         *size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, flags,
0630                 pace->e_perm, 0777);
0631         (*num_aces)++;
0632         if (pace->e_tag == ACL_USER)
0633             ntace->access_req |=
0634                 FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
0635 
0636         if (S_ISDIR(fattr->cf_mode) &&
0637             (pace->e_tag == ACL_USER || pace->e_tag == ACL_GROUP)) {
0638             ntace = (struct smb_ace *)((char *)pndace + *size);
0639             *size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED,
0640                     0x03, pace->e_perm, 0777);
0641             (*num_aces)++;
0642             if (pace->e_tag == ACL_USER)
0643                 ntace->access_req |=
0644                     FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
0645         }
0646 
0647 pass_same_sid:
0648         kfree(sid);
0649     }
0650 
0651     if (nt_aces_num)
0652         return;
0653 
0654 posix_default_acl:
0655     if (!fattr->cf_dacls)
0656         return;
0657 
0658     pace = fattr->cf_dacls->a_entries;
0659     for (i = 0; i < fattr->cf_dacls->a_count; i++, pace++) {
0660         sid = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
0661         if (!sid)
0662             break;
0663 
0664         if (pace->e_tag == ACL_USER) {
0665             uid_t uid;
0666 
0667             uid = posix_acl_uid_translate(user_ns, pace);
0668             id_to_sid(uid, SIDCREATOR_OWNER, sid);
0669         } else if (pace->e_tag == ACL_GROUP) {
0670             gid_t gid;
0671 
0672             gid = posix_acl_gid_translate(user_ns, pace);
0673             id_to_sid(gid, SIDCREATOR_GROUP, sid);
0674         } else {
0675             kfree(sid);
0676             continue;
0677         }
0678 
0679         ntace = (struct smb_ace *)((char *)pndace + *size);
0680         *size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, 0x0b,
0681                 pace->e_perm, 0777);
0682         (*num_aces)++;
0683         if (pace->e_tag == ACL_USER)
0684             ntace->access_req |=
0685                 FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
0686         kfree(sid);
0687     }
0688 }
0689 
0690 static void set_ntacl_dacl(struct user_namespace *user_ns,
0691                struct smb_acl *pndacl,
0692                struct smb_acl *nt_dacl,
0693                unsigned int aces_size,
0694                const struct smb_sid *pownersid,
0695                const struct smb_sid *pgrpsid,
0696                struct smb_fattr *fattr)
0697 {
0698     struct smb_ace *ntace, *pndace;
0699     int nt_num_aces = le32_to_cpu(nt_dacl->num_aces), num_aces = 0;
0700     unsigned short size = 0;
0701     int i;
0702 
0703     pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
0704     if (nt_num_aces) {
0705         ntace = (struct smb_ace *)((char *)nt_dacl + sizeof(struct smb_acl));
0706         for (i = 0; i < nt_num_aces; i++) {
0707             unsigned short nt_ace_size;
0708 
0709             if (offsetof(struct smb_ace, access_req) > aces_size)
0710                 break;
0711 
0712             nt_ace_size = le16_to_cpu(ntace->size);
0713             if (nt_ace_size > aces_size)
0714                 break;
0715 
0716             memcpy((char *)pndace + size, ntace, nt_ace_size);
0717             size += nt_ace_size;
0718             aces_size -= nt_ace_size;
0719             ntace = (struct smb_ace *)((char *)ntace + nt_ace_size);
0720             num_aces++;
0721         }
0722     }
0723 
0724     set_posix_acl_entries_dacl(user_ns, pndace, fattr,
0725                    &num_aces, &size, nt_num_aces);
0726     pndacl->num_aces = cpu_to_le32(num_aces);
0727     pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
0728 }
0729 
0730 static void set_mode_dacl(struct user_namespace *user_ns,
0731               struct smb_acl *pndacl, struct smb_fattr *fattr)
0732 {
0733     struct smb_ace *pace, *pndace;
0734     u32 num_aces = 0;
0735     u16 size = 0, ace_size = 0;
0736     uid_t uid;
0737     const struct smb_sid *sid;
0738 
0739     pace = pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
0740 
0741     if (fattr->cf_acls) {
0742         set_posix_acl_entries_dacl(user_ns, pndace, fattr,
0743                        &num_aces, &size, num_aces);
0744         goto out;
0745     }
0746 
0747     /* owner RID */
0748     uid = from_kuid(&init_user_ns, fattr->cf_uid);
0749     if (uid)
0750         sid = &server_conf.domain_sid;
0751     else
0752         sid = &sid_unix_users;
0753     ace_size = fill_ace_for_sid(pace, sid, ACCESS_ALLOWED, 0,
0754                     fattr->cf_mode, 0700);
0755     pace->sid.sub_auth[pace->sid.num_subauth++] = cpu_to_le32(uid);
0756     pace->size = cpu_to_le16(ace_size + 4);
0757     size += le16_to_cpu(pace->size);
0758     pace = (struct smb_ace *)((char *)pndace + size);
0759 
0760     /* Group RID */
0761     ace_size = fill_ace_for_sid(pace, &sid_unix_groups,
0762                     ACCESS_ALLOWED, 0, fattr->cf_mode, 0070);
0763     pace->sid.sub_auth[pace->sid.num_subauth++] =
0764         cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid));
0765     pace->size = cpu_to_le16(ace_size + 4);
0766     size += le16_to_cpu(pace->size);
0767     pace = (struct smb_ace *)((char *)pndace + size);
0768     num_aces = 3;
0769 
0770     if (S_ISDIR(fattr->cf_mode)) {
0771         pace = (struct smb_ace *)((char *)pndace + size);
0772 
0773         /* creator owner */
0774         size += fill_ace_for_sid(pace, &creator_owner, ACCESS_ALLOWED,
0775                      0x0b, fattr->cf_mode, 0700);
0776         pace = (struct smb_ace *)((char *)pndace + size);
0777 
0778         /* creator group */
0779         size += fill_ace_for_sid(pace, &creator_group, ACCESS_ALLOWED,
0780                      0x0b, fattr->cf_mode, 0070);
0781         pace = (struct smb_ace *)((char *)pndace + size);
0782         num_aces = 5;
0783     }
0784 
0785     /* other */
0786     size += fill_ace_for_sid(pace, &sid_everyone, ACCESS_ALLOWED, 0,
0787                  fattr->cf_mode, 0007);
0788 
0789 out:
0790     pndacl->num_aces = cpu_to_le32(num_aces);
0791     pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
0792 }
0793 
0794 static int parse_sid(struct smb_sid *psid, char *end_of_acl)
0795 {
0796     /*
0797      * validate that we do not go past end of ACL - sid must be at least 8
0798      * bytes long (assuming no sub-auths - e.g. the null SID
0799      */
0800     if (end_of_acl < (char *)psid + 8) {
0801         pr_err("ACL too small to parse SID %p\n", psid);
0802         return -EINVAL;
0803     }
0804 
0805     return 0;
0806 }
0807 
0808 /* Convert CIFS ACL to POSIX form */
0809 int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
0810            int acl_len, struct smb_fattr *fattr)
0811 {
0812     int rc = 0;
0813     struct smb_sid *owner_sid_ptr, *group_sid_ptr;
0814     struct smb_acl *dacl_ptr; /* no need for SACL ptr */
0815     char *end_of_acl = ((char *)pntsd) + acl_len;
0816     __u32 dacloffset;
0817     int pntsd_type;
0818 
0819     if (!pntsd)
0820         return -EIO;
0821 
0822     if (acl_len < sizeof(struct smb_ntsd))
0823         return -EINVAL;
0824 
0825     owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
0826             le32_to_cpu(pntsd->osidoffset));
0827     group_sid_ptr = (struct smb_sid *)((char *)pntsd +
0828             le32_to_cpu(pntsd->gsidoffset));
0829     dacloffset = le32_to_cpu(pntsd->dacloffset);
0830     dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
0831     ksmbd_debug(SMB,
0832             "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
0833             pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
0834             le32_to_cpu(pntsd->gsidoffset),
0835             le32_to_cpu(pntsd->sacloffset), dacloffset);
0836 
0837     pntsd_type = le16_to_cpu(pntsd->type);
0838     if (!(pntsd_type & DACL_PRESENT)) {
0839         ksmbd_debug(SMB, "DACL_PRESENT in DACL type is not set\n");
0840         return rc;
0841     }
0842 
0843     pntsd->type = cpu_to_le16(DACL_PRESENT);
0844 
0845     if (pntsd->osidoffset) {
0846         rc = parse_sid(owner_sid_ptr, end_of_acl);
0847         if (rc) {
0848             pr_err("%s: Error %d parsing Owner SID\n", __func__, rc);
0849             return rc;
0850         }
0851 
0852         rc = sid_to_id(user_ns, owner_sid_ptr, SIDOWNER, fattr);
0853         if (rc) {
0854             pr_err("%s: Error %d mapping Owner SID to uid\n",
0855                    __func__, rc);
0856             owner_sid_ptr = NULL;
0857         }
0858     }
0859 
0860     if (pntsd->gsidoffset) {
0861         rc = parse_sid(group_sid_ptr, end_of_acl);
0862         if (rc) {
0863             pr_err("%s: Error %d mapping Owner SID to gid\n",
0864                    __func__, rc);
0865             return rc;
0866         }
0867         rc = sid_to_id(user_ns, group_sid_ptr, SIDUNIX_GROUP, fattr);
0868         if (rc) {
0869             pr_err("%s: Error %d mapping Group SID to gid\n",
0870                    __func__, rc);
0871             group_sid_ptr = NULL;
0872         }
0873     }
0874 
0875     if ((pntsd_type & (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ)) ==
0876         (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ))
0877         pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
0878     if (pntsd_type & DACL_PROTECTED)
0879         pntsd->type |= cpu_to_le16(DACL_PROTECTED);
0880 
0881     if (dacloffset) {
0882         parse_dacl(user_ns, dacl_ptr, end_of_acl,
0883                owner_sid_ptr, group_sid_ptr, fattr);
0884     }
0885 
0886     return 0;
0887 }
0888 
0889 /* Convert permission bits from mode to equivalent CIFS ACL */
0890 int build_sec_desc(struct user_namespace *user_ns,
0891            struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
0892            int ppntsd_size, int addition_info, __u32 *secdesclen,
0893            struct smb_fattr *fattr)
0894 {
0895     int rc = 0;
0896     __u32 offset;
0897     struct smb_sid *owner_sid_ptr, *group_sid_ptr;
0898     struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr;
0899     struct smb_acl *dacl_ptr = NULL; /* no need for SACL ptr */
0900     uid_t uid;
0901     gid_t gid;
0902     unsigned int sid_type = SIDOWNER;
0903 
0904     nowner_sid_ptr = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
0905     if (!nowner_sid_ptr)
0906         return -ENOMEM;
0907 
0908     uid = from_kuid(&init_user_ns, fattr->cf_uid);
0909     if (!uid)
0910         sid_type = SIDUNIX_USER;
0911     id_to_sid(uid, sid_type, nowner_sid_ptr);
0912 
0913     ngroup_sid_ptr = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
0914     if (!ngroup_sid_ptr) {
0915         kfree(nowner_sid_ptr);
0916         return -ENOMEM;
0917     }
0918 
0919     gid = from_kgid(&init_user_ns, fattr->cf_gid);
0920     id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr);
0921 
0922     offset = sizeof(struct smb_ntsd);
0923     pntsd->sacloffset = 0;
0924     pntsd->revision = cpu_to_le16(1);
0925     pntsd->type = cpu_to_le16(SELF_RELATIVE);
0926     if (ppntsd)
0927         pntsd->type |= ppntsd->type;
0928 
0929     if (addition_info & OWNER_SECINFO) {
0930         pntsd->osidoffset = cpu_to_le32(offset);
0931         owner_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
0932         smb_copy_sid(owner_sid_ptr, nowner_sid_ptr);
0933         offset += 1 + 1 + 6 + (nowner_sid_ptr->num_subauth * 4);
0934     }
0935 
0936     if (addition_info & GROUP_SECINFO) {
0937         pntsd->gsidoffset = cpu_to_le32(offset);
0938         group_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
0939         smb_copy_sid(group_sid_ptr, ngroup_sid_ptr);
0940         offset += 1 + 1 + 6 + (ngroup_sid_ptr->num_subauth * 4);
0941     }
0942 
0943     if (addition_info & DACL_SECINFO) {
0944         pntsd->type |= cpu_to_le16(DACL_PRESENT);
0945         dacl_ptr = (struct smb_acl *)((char *)pntsd + offset);
0946         dacl_ptr->revision = cpu_to_le16(2);
0947         dacl_ptr->size = cpu_to_le16(sizeof(struct smb_acl));
0948         dacl_ptr->num_aces = 0;
0949 
0950         if (!ppntsd) {
0951             set_mode_dacl(user_ns, dacl_ptr, fattr);
0952         } else {
0953             struct smb_acl *ppdacl_ptr;
0954             unsigned int dacl_offset = le32_to_cpu(ppntsd->dacloffset);
0955             int ppdacl_size, ntacl_size = ppntsd_size - dacl_offset;
0956 
0957             if (!dacl_offset ||
0958                 (dacl_offset + sizeof(struct smb_acl) > ppntsd_size))
0959                 goto out;
0960 
0961             ppdacl_ptr = (struct smb_acl *)((char *)ppntsd + dacl_offset);
0962             ppdacl_size = le16_to_cpu(ppdacl_ptr->size);
0963             if (ppdacl_size > ntacl_size ||
0964                 ppdacl_size < sizeof(struct smb_acl))
0965                 goto out;
0966 
0967             set_ntacl_dacl(user_ns, dacl_ptr, ppdacl_ptr,
0968                        ntacl_size - sizeof(struct smb_acl),
0969                        nowner_sid_ptr, ngroup_sid_ptr,
0970                        fattr);
0971         }
0972         pntsd->dacloffset = cpu_to_le32(offset);
0973         offset += le16_to_cpu(dacl_ptr->size);
0974     }
0975 
0976 out:
0977     kfree(nowner_sid_ptr);
0978     kfree(ngroup_sid_ptr);
0979     *secdesclen = offset;
0980     return rc;
0981 }
0982 
0983 static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type,
0984             u8 flags, __le32 access_req)
0985 {
0986     ace->type = type;
0987     ace->flags = flags;
0988     ace->access_req = access_req;
0989     smb_copy_sid(&ace->sid, sid);
0990     ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 + (sid->num_subauth * 4));
0991 }
0992 
0993 int smb_inherit_dacl(struct ksmbd_conn *conn,
0994              struct path *path,
0995              unsigned int uid, unsigned int gid)
0996 {
0997     const struct smb_sid *psid, *creator = NULL;
0998     struct smb_ace *parent_aces, *aces;
0999     struct smb_acl *parent_pdacl;
1000     struct smb_ntsd *parent_pntsd = NULL;
1001     struct smb_sid owner_sid, group_sid;
1002     struct dentry *parent = path->dentry->d_parent;
1003     struct user_namespace *user_ns = mnt_user_ns(path->mnt);
1004     int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0, pdacl_size;
1005     int rc = 0, num_aces, dacloffset, pntsd_type, pntsd_size, acl_len, aces_size;
1006     char *aces_base;
1007     bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
1008 
1009     pntsd_size = ksmbd_vfs_get_sd_xattr(conn, user_ns,
1010                         parent, &parent_pntsd);
1011     if (pntsd_size <= 0)
1012         return -ENOENT;
1013     dacloffset = le32_to_cpu(parent_pntsd->dacloffset);
1014     if (!dacloffset || (dacloffset + sizeof(struct smb_acl) > pntsd_size)) {
1015         rc = -EINVAL;
1016         goto free_parent_pntsd;
1017     }
1018 
1019     parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset);
1020     acl_len = pntsd_size - dacloffset;
1021     num_aces = le32_to_cpu(parent_pdacl->num_aces);
1022     pntsd_type = le16_to_cpu(parent_pntsd->type);
1023     pdacl_size = le16_to_cpu(parent_pdacl->size);
1024 
1025     if (pdacl_size > acl_len || pdacl_size < sizeof(struct smb_acl)) {
1026         rc = -EINVAL;
1027         goto free_parent_pntsd;
1028     }
1029 
1030     aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2, GFP_KERNEL);
1031     if (!aces_base) {
1032         rc = -ENOMEM;
1033         goto free_parent_pntsd;
1034     }
1035 
1036     aces = (struct smb_ace *)aces_base;
1037     parent_aces = (struct smb_ace *)((char *)parent_pdacl +
1038             sizeof(struct smb_acl));
1039     aces_size = acl_len - sizeof(struct smb_acl);
1040 
1041     if (pntsd_type & DACL_AUTO_INHERITED)
1042         inherited_flags = INHERITED_ACE;
1043 
1044     for (i = 0; i < num_aces; i++) {
1045         int pace_size;
1046 
1047         if (offsetof(struct smb_ace, access_req) > aces_size)
1048             break;
1049 
1050         pace_size = le16_to_cpu(parent_aces->size);
1051         if (pace_size > aces_size)
1052             break;
1053 
1054         aces_size -= pace_size;
1055 
1056         flags = parent_aces->flags;
1057         if (!smb_inherit_flags(flags, is_dir))
1058             goto pass;
1059         if (is_dir) {
1060             flags &= ~(INHERIT_ONLY_ACE | INHERITED_ACE);
1061             if (!(flags & CONTAINER_INHERIT_ACE))
1062                 flags |= INHERIT_ONLY_ACE;
1063             if (flags & NO_PROPAGATE_INHERIT_ACE)
1064                 flags = 0;
1065         } else {
1066             flags = 0;
1067         }
1068 
1069         if (!compare_sids(&creator_owner, &parent_aces->sid)) {
1070             creator = &creator_owner;
1071             id_to_sid(uid, SIDOWNER, &owner_sid);
1072             psid = &owner_sid;
1073         } else if (!compare_sids(&creator_group, &parent_aces->sid)) {
1074             creator = &creator_group;
1075             id_to_sid(gid, SIDUNIX_GROUP, &group_sid);
1076             psid = &group_sid;
1077         } else {
1078             creator = NULL;
1079             psid = &parent_aces->sid;
1080         }
1081 
1082         if (is_dir && creator && flags & CONTAINER_INHERIT_ACE) {
1083             smb_set_ace(aces, psid, parent_aces->type, inherited_flags,
1084                     parent_aces->access_req);
1085             nt_size += le16_to_cpu(aces->size);
1086             ace_cnt++;
1087             aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
1088             flags |= INHERIT_ONLY_ACE;
1089             psid = creator;
1090         } else if (is_dir && !(parent_aces->flags & NO_PROPAGATE_INHERIT_ACE)) {
1091             psid = &parent_aces->sid;
1092         }
1093 
1094         smb_set_ace(aces, psid, parent_aces->type, flags | inherited_flags,
1095                 parent_aces->access_req);
1096         nt_size += le16_to_cpu(aces->size);
1097         aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
1098         ace_cnt++;
1099 pass:
1100         parent_aces = (struct smb_ace *)((char *)parent_aces + pace_size);
1101     }
1102 
1103     if (nt_size > 0) {
1104         struct smb_ntsd *pntsd;
1105         struct smb_acl *pdacl;
1106         struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL;
1107         int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
1108 
1109         if (parent_pntsd->osidoffset) {
1110             powner_sid = (struct smb_sid *)((char *)parent_pntsd +
1111                     le32_to_cpu(parent_pntsd->osidoffset));
1112             powner_sid_size = 1 + 1 + 6 + (powner_sid->num_subauth * 4);
1113         }
1114         if (parent_pntsd->gsidoffset) {
1115             pgroup_sid = (struct smb_sid *)((char *)parent_pntsd +
1116                     le32_to_cpu(parent_pntsd->gsidoffset));
1117             pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4);
1118         }
1119 
1120         pntsd = kzalloc(sizeof(struct smb_ntsd) + powner_sid_size +
1121                 pgroup_sid_size + sizeof(struct smb_acl) +
1122                 nt_size, GFP_KERNEL);
1123         if (!pntsd) {
1124             rc = -ENOMEM;
1125             goto free_aces_base;
1126         }
1127 
1128         pntsd->revision = cpu_to_le16(1);
1129         pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PRESENT);
1130         if (le16_to_cpu(parent_pntsd->type) & DACL_AUTO_INHERITED)
1131             pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
1132         pntsd_size = sizeof(struct smb_ntsd);
1133         pntsd->osidoffset = parent_pntsd->osidoffset;
1134         pntsd->gsidoffset = parent_pntsd->gsidoffset;
1135         pntsd->dacloffset = parent_pntsd->dacloffset;
1136 
1137         if (pntsd->osidoffset) {
1138             struct smb_sid *owner_sid = (struct smb_sid *)((char *)pntsd +
1139                     le32_to_cpu(pntsd->osidoffset));
1140             memcpy(owner_sid, powner_sid, powner_sid_size);
1141             pntsd_size += powner_sid_size;
1142         }
1143 
1144         if (pntsd->gsidoffset) {
1145             struct smb_sid *group_sid = (struct smb_sid *)((char *)pntsd +
1146                     le32_to_cpu(pntsd->gsidoffset));
1147             memcpy(group_sid, pgroup_sid, pgroup_sid_size);
1148             pntsd_size += pgroup_sid_size;
1149         }
1150 
1151         if (pntsd->dacloffset) {
1152             struct smb_ace *pace;
1153 
1154             pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1155             pdacl->revision = cpu_to_le16(2);
1156             pdacl->size = cpu_to_le16(sizeof(struct smb_acl) + nt_size);
1157             pdacl->num_aces = cpu_to_le32(ace_cnt);
1158             pace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1159             memcpy(pace, aces_base, nt_size);
1160             pntsd_size += sizeof(struct smb_acl) + nt_size;
1161         }
1162 
1163         ksmbd_vfs_set_sd_xattr(conn, user_ns,
1164                        path->dentry, pntsd, pntsd_size);
1165         kfree(pntsd);
1166     }
1167 
1168 free_aces_base:
1169     kfree(aces_base);
1170 free_parent_pntsd:
1171     kfree(parent_pntsd);
1172     return rc;
1173 }
1174 
1175 bool smb_inherit_flags(int flags, bool is_dir)
1176 {
1177     if (!is_dir)
1178         return (flags & OBJECT_INHERIT_ACE) != 0;
1179 
1180     if (flags & OBJECT_INHERIT_ACE && !(flags & NO_PROPAGATE_INHERIT_ACE))
1181         return true;
1182 
1183     if (flags & CONTAINER_INHERIT_ACE)
1184         return true;
1185     return false;
1186 }
1187 
1188 int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path,
1189             __le32 *pdaccess, int uid)
1190 {
1191     struct user_namespace *user_ns = mnt_user_ns(path->mnt);
1192     struct smb_ntsd *pntsd = NULL;
1193     struct smb_acl *pdacl;
1194     struct posix_acl *posix_acls;
1195     int rc = 0, pntsd_size, acl_size, aces_size, pdacl_size, dacl_offset;
1196     struct smb_sid sid;
1197     int granted = le32_to_cpu(*pdaccess & ~FILE_MAXIMAL_ACCESS_LE);
1198     struct smb_ace *ace;
1199     int i, found = 0;
1200     unsigned int access_bits = 0;
1201     struct smb_ace *others_ace = NULL;
1202     struct posix_acl_entry *pa_entry;
1203     unsigned int sid_type = SIDOWNER;
1204     unsigned short ace_size;
1205 
1206     ksmbd_debug(SMB, "check permission using windows acl\n");
1207     pntsd_size = ksmbd_vfs_get_sd_xattr(conn, user_ns,
1208                         path->dentry, &pntsd);
1209     if (pntsd_size <= 0 || !pntsd)
1210         goto err_out;
1211 
1212     dacl_offset = le32_to_cpu(pntsd->dacloffset);
1213     if (!dacl_offset ||
1214         (dacl_offset + sizeof(struct smb_acl) > pntsd_size))
1215         goto err_out;
1216 
1217     pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1218     acl_size = pntsd_size - dacl_offset;
1219     pdacl_size = le16_to_cpu(pdacl->size);
1220 
1221     if (pdacl_size > acl_size || pdacl_size < sizeof(struct smb_acl))
1222         goto err_out;
1223 
1224     if (!pdacl->num_aces) {
1225         if (!(pdacl_size - sizeof(struct smb_acl)) &&
1226             *pdaccess & ~(FILE_READ_CONTROL_LE | FILE_WRITE_DAC_LE)) {
1227             rc = -EACCES;
1228             goto err_out;
1229         }
1230         goto err_out;
1231     }
1232 
1233     if (*pdaccess & FILE_MAXIMAL_ACCESS_LE) {
1234         granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1235             DELETE;
1236 
1237         ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1238         aces_size = acl_size - sizeof(struct smb_acl);
1239         for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1240             if (offsetof(struct smb_ace, access_req) > aces_size)
1241                 break;
1242             ace_size = le16_to_cpu(ace->size);
1243             if (ace_size > aces_size)
1244                 break;
1245             aces_size -= ace_size;
1246             granted |= le32_to_cpu(ace->access_req);
1247             ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1248         }
1249 
1250         if (!pdacl->num_aces)
1251             granted = GENERIC_ALL_FLAGS;
1252     }
1253 
1254     if (!uid)
1255         sid_type = SIDUNIX_USER;
1256     id_to_sid(uid, sid_type, &sid);
1257 
1258     ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1259     aces_size = acl_size - sizeof(struct smb_acl);
1260     for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1261         if (offsetof(struct smb_ace, access_req) > aces_size)
1262             break;
1263         ace_size = le16_to_cpu(ace->size);
1264         if (ace_size > aces_size)
1265             break;
1266         aces_size -= ace_size;
1267 
1268         if (!compare_sids(&sid, &ace->sid) ||
1269             !compare_sids(&sid_unix_NFS_mode, &ace->sid)) {
1270             found = 1;
1271             break;
1272         }
1273         if (!compare_sids(&sid_everyone, &ace->sid))
1274             others_ace = ace;
1275 
1276         ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1277     }
1278 
1279     if (*pdaccess & FILE_MAXIMAL_ACCESS_LE && found) {
1280         granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1281             DELETE;
1282 
1283         granted |= le32_to_cpu(ace->access_req);
1284 
1285         if (!pdacl->num_aces)
1286             granted = GENERIC_ALL_FLAGS;
1287     }
1288 
1289     if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
1290         posix_acls = get_acl(d_inode(path->dentry), ACL_TYPE_ACCESS);
1291         if (posix_acls && !found) {
1292             unsigned int id = -1;
1293 
1294             pa_entry = posix_acls->a_entries;
1295             for (i = 0; i < posix_acls->a_count; i++, pa_entry++) {
1296                 if (pa_entry->e_tag == ACL_USER)
1297                     id = posix_acl_uid_translate(user_ns, pa_entry);
1298                 else if (pa_entry->e_tag == ACL_GROUP)
1299                     id = posix_acl_gid_translate(user_ns, pa_entry);
1300                 else
1301                     continue;
1302 
1303                 if (id == uid) {
1304                     mode_to_access_flags(pa_entry->e_perm,
1305                                  0777,
1306                                  &access_bits);
1307                     if (!access_bits)
1308                         access_bits =
1309                             SET_MINIMUM_RIGHTS;
1310                     posix_acl_release(posix_acls);
1311                     goto check_access_bits;
1312                 }
1313             }
1314         }
1315         if (posix_acls)
1316             posix_acl_release(posix_acls);
1317     }
1318 
1319     if (!found) {
1320         if (others_ace) {
1321             ace = others_ace;
1322         } else {
1323             ksmbd_debug(SMB, "Can't find corresponding sid\n");
1324             rc = -EACCES;
1325             goto err_out;
1326         }
1327     }
1328 
1329     switch (ace->type) {
1330     case ACCESS_ALLOWED_ACE_TYPE:
1331         access_bits = le32_to_cpu(ace->access_req);
1332         break;
1333     case ACCESS_DENIED_ACE_TYPE:
1334     case ACCESS_DENIED_CALLBACK_ACE_TYPE:
1335         access_bits = le32_to_cpu(~ace->access_req);
1336         break;
1337     }
1338 
1339 check_access_bits:
1340     if (granted &
1341         ~(access_bits | FILE_READ_ATTRIBUTES | READ_CONTROL | WRITE_DAC | DELETE)) {
1342         ksmbd_debug(SMB, "Access denied with winACL, granted : %x, access_req : %x\n",
1343                 granted, le32_to_cpu(ace->access_req));
1344         rc = -EACCES;
1345         goto err_out;
1346     }
1347 
1348     *pdaccess = cpu_to_le32(granted);
1349 err_out:
1350     kfree(pntsd);
1351     return rc;
1352 }
1353 
1354 int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
1355          struct path *path, struct smb_ntsd *pntsd, int ntsd_len,
1356          bool type_check)
1357 {
1358     int rc;
1359     struct smb_fattr fattr = {{0}};
1360     struct inode *inode = d_inode(path->dentry);
1361     struct user_namespace *user_ns = mnt_user_ns(path->mnt);
1362     struct iattr newattrs;
1363 
1364     fattr.cf_uid = INVALID_UID;
1365     fattr.cf_gid = INVALID_GID;
1366     fattr.cf_mode = inode->i_mode;
1367 
1368     rc = parse_sec_desc(user_ns, pntsd, ntsd_len, &fattr);
1369     if (rc)
1370         goto out;
1371 
1372     newattrs.ia_valid = ATTR_CTIME;
1373     if (!uid_eq(fattr.cf_uid, INVALID_UID)) {
1374         newattrs.ia_valid |= ATTR_UID;
1375         newattrs.ia_uid = fattr.cf_uid;
1376     }
1377     if (!gid_eq(fattr.cf_gid, INVALID_GID)) {
1378         newattrs.ia_valid |= ATTR_GID;
1379         newattrs.ia_gid = fattr.cf_gid;
1380     }
1381     newattrs.ia_valid |= ATTR_MODE;
1382     newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
1383 
1384     ksmbd_vfs_remove_acl_xattrs(user_ns, path->dentry);
1385     /* Update posix acls */
1386     if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) {
1387         rc = set_posix_acl(user_ns, inode,
1388                    ACL_TYPE_ACCESS, fattr.cf_acls);
1389         if (rc < 0)
1390             ksmbd_debug(SMB,
1391                     "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
1392                     rc);
1393         if (S_ISDIR(inode->i_mode) && fattr.cf_dacls) {
1394             rc = set_posix_acl(user_ns, inode,
1395                        ACL_TYPE_DEFAULT, fattr.cf_dacls);
1396             if (rc)
1397                 ksmbd_debug(SMB,
1398                         "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
1399                         rc);
1400         }
1401     }
1402 
1403     inode_lock(inode);
1404     rc = notify_change(user_ns, path->dentry, &newattrs, NULL);
1405     inode_unlock(inode);
1406     if (rc)
1407         goto out;
1408 
1409     /* Check it only calling from SD BUFFER context */
1410     if (type_check && !(le16_to_cpu(pntsd->type) & DACL_PRESENT))
1411         goto out;
1412 
1413     if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
1414         /* Update WinACL in xattr */
1415         ksmbd_vfs_remove_sd_xattrs(user_ns, path->dentry);
1416         ksmbd_vfs_set_sd_xattr(conn, user_ns,
1417                        path->dentry, pntsd, ntsd_len);
1418     }
1419 
1420 out:
1421     posix_acl_release(fattr.cf_acls);
1422     posix_acl_release(fattr.cf_dacls);
1423     mark_inode_dirty(inode);
1424     return rc;
1425 }
1426 
1427 void ksmbd_init_domain(u32 *sub_auth)
1428 {
1429     int i;
1430 
1431     memcpy(&server_conf.domain_sid, &domain, sizeof(struct smb_sid));
1432     for (i = 0; i < 3; ++i)
1433         server_conf.domain_sid.sub_auth[i + 1] = cpu_to_le32(sub_auth[i]);
1434 }