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

TOMOYO Linux Cross Reference
Linux/fs/smb/server/smbacl.c

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

  1 // SPDX-License-Identifier: LGPL-2.1+
  2 /*
  3  *   Copyright (C) International Business Machines  Corp., 2007,2008
  4  *   Author(s): Steve French (sfrench@us.ibm.com)
  5  *   Copyright (C) 2020 Samsung Electronics Co., Ltd.
  6  *   Author(s): Namjae Jeon <linkinjeon@kernel.org>
  7  */
  8 
  9 #include <linux/fs.h>
 10 #include <linux/slab.h>
 11 #include <linux/string.h>
 12 #include <linux/mnt_idmapping.h>
 13 
 14 #include "smbacl.h"
 15 #include "smb_common.h"
 16 #include "server.h"
 17 #include "misc.h"
 18 #include "mgmt/share_config.h"
 19 
 20 static const struct smb_sid domain = {1, 4, {0, 0, 0, 0, 0, 5},
 21         {cpu_to_le32(21), cpu_to_le32(1), cpu_to_le32(2), cpu_to_le32(3),
 22         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
 23 
 24 /* security id for everyone/world system group */
 25 static const struct smb_sid creator_owner = {
 26         1, 1, {0, 0, 0, 0, 0, 3}, {0} };
 27 /* security id for everyone/world system group */
 28 static const struct smb_sid creator_group = {
 29         1, 1, {0, 0, 0, 0, 0, 3}, {cpu_to_le32(1)} };
 30 
 31 /* security id for everyone/world system group */
 32 static const struct smb_sid sid_everyone = {
 33         1, 1, {0, 0, 0, 0, 0, 1}, {0} };
 34 /* security id for Authenticated Users system group */
 35 static const struct smb_sid sid_authusers = {
 36         1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
 37 
 38 /* S-1-22-1 Unmapped Unix users */
 39 static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
 40                 {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
 41 
 42 /* S-1-22-2 Unmapped Unix groups */
 43 static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
 44                 {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
 45 
 46 /*
 47  * See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
 48  */
 49 
 50 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
 51 
 52 /* S-1-5-88-1 Unix uid */
 53 static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
 54         {cpu_to_le32(88),
 55          cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
 56 
 57 /* S-1-5-88-2 Unix gid */
 58 static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
 59         {cpu_to_le32(88),
 60          cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
 61 
 62 /* S-1-5-88-3 Unix mode */
 63 static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
 64         {cpu_to_le32(88),
 65          cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
 66 
 67 /*
 68  * if the two SIDs (roughly equivalent to a UUID for a user or group) are
 69  * the same returns zero, if they do not match returns non-zero.
 70  */
 71 int compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
 72 {
 73         int i;
 74         int num_subauth, num_sat, num_saw;
 75 
 76         if (!ctsid || !cwsid)
 77                 return 1;
 78 
 79         /* compare the revision */
 80         if (ctsid->revision != cwsid->revision) {
 81                 if (ctsid->revision > cwsid->revision)
 82                         return 1;
 83                 else
 84                         return -1;
 85         }
 86 
 87         /* compare all of the six auth values */
 88         for (i = 0; i < NUM_AUTHS; ++i) {
 89                 if (ctsid->authority[i] != cwsid->authority[i]) {
 90                         if (ctsid->authority[i] > cwsid->authority[i])
 91                                 return 1;
 92                         else
 93                                 return -1;
 94                 }
 95         }
 96 
 97         /* compare all of the subauth values if any */
 98         num_sat = ctsid->num_subauth;
 99         num_saw = cwsid->num_subauth;
100         num_subauth = min(num_sat, num_saw);
101         if (num_subauth) {
102                 for (i = 0; i < num_subauth; ++i) {
103                         if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
104                                 if (le32_to_cpu(ctsid->sub_auth[i]) >
105                                     le32_to_cpu(cwsid->sub_auth[i]))
106                                         return 1;
107                                 else
108                                         return -1;
109                         }
110                 }
111         }
112 
113         return 0; /* sids compare/match */
114 }
115 
116 static void smb_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
117 {
118         int i;
119 
120         dst->revision = src->revision;
121         dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
122         for (i = 0; i < NUM_AUTHS; ++i)
123                 dst->authority[i] = src->authority[i];
124         for (i = 0; i < dst->num_subauth; ++i)
125                 dst->sub_auth[i] = src->sub_auth[i];
126 }
127 
128 /*
129  * change posix mode to reflect permissions
130  * pmode is the existing mode (we only want to overwrite part of this
131  * bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
132  */
133 static umode_t access_flags_to_mode(struct smb_fattr *fattr, __le32 ace_flags,
134                                     int type)
135 {
136         __u32 flags = le32_to_cpu(ace_flags);
137         umode_t mode = 0;
138 
139         if (flags & GENERIC_ALL) {
140                 mode = 0777;
141                 ksmbd_debug(SMB, "all perms\n");
142                 return mode;
143         }
144 
145         if ((flags & GENERIC_READ) || (flags & FILE_READ_RIGHTS))
146                 mode = 0444;
147         if ((flags & GENERIC_WRITE) || (flags & FILE_WRITE_RIGHTS)) {
148                 mode |= 0222;
149                 if (S_ISDIR(fattr->cf_mode))
150                         mode |= 0111;
151         }
152         if ((flags & GENERIC_EXECUTE) || (flags & FILE_EXEC_RIGHTS))
153                 mode |= 0111;
154 
155         if (type == ACCESS_DENIED_ACE_TYPE || type == ACCESS_DENIED_OBJECT_ACE_TYPE)
156                 mode = ~mode;
157 
158         ksmbd_debug(SMB, "access flags 0x%x mode now %04o\n", flags, mode);
159 
160         return mode;
161 }
162 
163 /*
164  * Generate access flags to reflect permissions mode is the existing mode.
165  * This function is called for every ACE in the DACL whose SID matches
166  * with either owner or group or everyone.
167  */
168 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
169                                  __u32 *pace_flags)
170 {
171         /* reset access mask */
172         *pace_flags = 0x0;
173 
174         /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
175         mode &= bits_to_use;
176 
177         /*
178          * check for R/W/X UGO since we do not know whose flags
179          * is this but we have cleared all the bits sans RWX for
180          * either user or group or other as per bits_to_use
181          */
182         if (mode & 0444)
183                 *pace_flags |= SET_FILE_READ_RIGHTS;
184         if (mode & 0222)
185                 *pace_flags |= FILE_WRITE_RIGHTS;
186         if (mode & 0111)
187                 *pace_flags |= SET_FILE_EXEC_RIGHTS;
188 
189         ksmbd_debug(SMB, "mode: %o, access flags now 0x%x\n",
190                     mode, *pace_flags);
191 }
192 
193 static __u16 fill_ace_for_sid(struct smb_ace *pntace,
194                               const struct smb_sid *psid, int type, int flags,
195                               umode_t mode, umode_t bits)
196 {
197         int i;
198         __u16 size = 0;
199         __u32 access_req = 0;
200 
201         pntace->type = type;
202         pntace->flags = flags;
203         mode_to_access_flags(mode, bits, &access_req);
204         if (!access_req)
205                 access_req = SET_MINIMUM_RIGHTS;
206         pntace->access_req = cpu_to_le32(access_req);
207 
208         pntace->sid.revision = psid->revision;
209         pntace->sid.num_subauth = psid->num_subauth;
210         for (i = 0; i < NUM_AUTHS; i++)
211                 pntace->sid.authority[i] = psid->authority[i];
212         for (i = 0; i < psid->num_subauth; i++)
213                 pntace->sid.sub_auth[i] = psid->sub_auth[i];
214 
215         size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
216         pntace->size = cpu_to_le16(size);
217 
218         return size;
219 }
220 
221 void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
222 {
223         switch (sidtype) {
224         case SIDOWNER:
225                 smb_copy_sid(ssid, &server_conf.domain_sid);
226                 break;
227         case SIDUNIX_USER:
228                 smb_copy_sid(ssid, &sid_unix_users);
229                 break;
230         case SIDUNIX_GROUP:
231                 smb_copy_sid(ssid, &sid_unix_groups);
232                 break;
233         case SIDCREATOR_OWNER:
234                 smb_copy_sid(ssid, &creator_owner);
235                 return;
236         case SIDCREATOR_GROUP:
237                 smb_copy_sid(ssid, &creator_group);
238                 return;
239         case SIDNFS_USER:
240                 smb_copy_sid(ssid, &sid_unix_NFS_users);
241                 break;
242         case SIDNFS_GROUP:
243                 smb_copy_sid(ssid, &sid_unix_NFS_groups);
244                 break;
245         case SIDNFS_MODE:
246                 smb_copy_sid(ssid, &sid_unix_NFS_mode);
247                 break;
248         default:
249                 return;
250         }
251 
252         /* RID */
253         ssid->sub_auth[ssid->num_subauth] = cpu_to_le32(cid);
254         ssid->num_subauth++;
255 }
256 
257 static int sid_to_id(struct mnt_idmap *idmap,
258                      struct smb_sid *psid, uint sidtype,
259                      struct smb_fattr *fattr)
260 {
261         int rc = -EINVAL;
262 
263         /*
264          * If we have too many subauthorities, then something is really wrong.
265          * Just return an error.
266          */
267         if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
268                 pr_err("%s: %u subauthorities is too many!\n",
269                        __func__, psid->num_subauth);
270                 return -EIO;
271         }
272 
273         if (sidtype == SIDOWNER) {
274                 kuid_t uid;
275                 uid_t id;
276 
277                 id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
278                 uid = KUIDT_INIT(id);
279                 uid = from_vfsuid(idmap, &init_user_ns, VFSUIDT_INIT(uid));
280                 if (uid_valid(uid)) {
281                         fattr->cf_uid = uid;
282                         rc = 0;
283                 }
284         } else {
285                 kgid_t gid;
286                 gid_t id;
287 
288                 id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
289                 gid = KGIDT_INIT(id);
290                 gid = from_vfsgid(idmap, &init_user_ns, VFSGIDT_INIT(gid));
291                 if (gid_valid(gid)) {
292                         fattr->cf_gid = gid;
293                         rc = 0;
294                 }
295         }
296 
297         return rc;
298 }
299 
300 void posix_state_to_acl(struct posix_acl_state *state,
301                         struct posix_acl_entry *pace)
302 {
303         int i;
304 
305         pace->e_tag = ACL_USER_OBJ;
306         pace->e_perm = state->owner.allow;
307         for (i = 0; i < state->users->n; i++) {
308                 pace++;
309                 pace->e_tag = ACL_USER;
310                 pace->e_uid = state->users->aces[i].uid;
311                 pace->e_perm = state->users->aces[i].perms.allow;
312         }
313 
314         pace++;
315         pace->e_tag = ACL_GROUP_OBJ;
316         pace->e_perm = state->group.allow;
317 
318         for (i = 0; i < state->groups->n; i++) {
319                 pace++;
320                 pace->e_tag = ACL_GROUP;
321                 pace->e_gid = state->groups->aces[i].gid;
322                 pace->e_perm = state->groups->aces[i].perms.allow;
323         }
324 
325         if (state->users->n || state->groups->n) {
326                 pace++;
327                 pace->e_tag = ACL_MASK;
328                 pace->e_perm = state->mask.allow;
329         }
330 
331         pace++;
332         pace->e_tag = ACL_OTHER;
333         pace->e_perm = state->other.allow;
334 }
335 
336 int init_acl_state(struct posix_acl_state *state, int cnt)
337 {
338         int alloc;
339 
340         memset(state, 0, sizeof(struct posix_acl_state));
341         /*
342          * In the worst case, each individual acl could be for a distinct
343          * named user or group, but we don't know which, so we allocate
344          * enough space for either:
345          */
346         alloc = sizeof(struct posix_ace_state_array)
347                 + cnt * sizeof(struct posix_user_ace_state);
348         state->users = kzalloc(alloc, GFP_KERNEL);
349         if (!state->users)
350                 return -ENOMEM;
351         state->groups = kzalloc(alloc, GFP_KERNEL);
352         if (!state->groups) {
353                 kfree(state->users);
354                 return -ENOMEM;
355         }
356         return 0;
357 }
358 
359 void free_acl_state(struct posix_acl_state *state)
360 {
361         kfree(state->users);
362         kfree(state->groups);
363 }
364 
365 static void parse_dacl(struct mnt_idmap *idmap,
366                        struct smb_acl *pdacl, char *end_of_acl,
367                        struct smb_sid *pownersid, struct smb_sid *pgrpsid,
368                        struct smb_fattr *fattr)
369 {
370         int i, ret;
371         int num_aces = 0;
372         unsigned int acl_size;
373         char *acl_base;
374         struct smb_ace **ppace;
375         struct posix_acl_entry *cf_pace, *cf_pdace;
376         struct posix_acl_state acl_state, default_acl_state;
377         umode_t mode = 0, acl_mode;
378         bool owner_found = false, group_found = false, others_found = false;
379 
380         if (!pdacl)
381                 return;
382 
383         /* validate that we do not go past end of acl */
384         if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl) ||
385             end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
386                 pr_err("ACL too small to parse DACL\n");
387                 return;
388         }
389 
390         ksmbd_debug(SMB, "DACL revision %d size %d num aces %d\n",
391                     le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
392                     le32_to_cpu(pdacl->num_aces));
393 
394         acl_base = (char *)pdacl;
395         acl_size = sizeof(struct smb_acl);
396 
397         num_aces = le32_to_cpu(pdacl->num_aces);
398         if (num_aces <= 0)
399                 return;
400 
401         if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
402                 return;
403 
404         ret = init_acl_state(&acl_state, num_aces);
405         if (ret)
406                 return;
407         ret = init_acl_state(&default_acl_state, num_aces);
408         if (ret) {
409                 free_acl_state(&acl_state);
410                 return;
411         }
412 
413         ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), GFP_KERNEL);
414         if (!ppace) {
415                 free_acl_state(&default_acl_state);
416                 free_acl_state(&acl_state);
417                 return;
418         }
419 
420         /*
421          * reset rwx permissions for user/group/other.
422          * Also, if num_aces is 0 i.e. DACL has no ACEs,
423          * user/group/other have no permissions
424          */
425         for (i = 0; i < num_aces; ++i) {
426                 if (end_of_acl - acl_base < acl_size)
427                         break;
428 
429                 ppace[i] = (struct smb_ace *)(acl_base + acl_size);
430                 acl_base = (char *)ppace[i];
431                 acl_size = offsetof(struct smb_ace, sid) +
432                         offsetof(struct smb_sid, sub_auth);
433 
434                 if (end_of_acl - acl_base < acl_size ||
435                     ppace[i]->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
436                     (end_of_acl - acl_base <
437                      acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) ||
438                     (le16_to_cpu(ppace[i]->size) <
439                      acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth))
440                         break;
441 
442                 acl_size = le16_to_cpu(ppace[i]->size);
443                 ppace[i]->access_req =
444                         smb_map_generic_desired_access(ppace[i]->access_req);
445 
446                 if (!(compare_sids(&ppace[i]->sid, &sid_unix_NFS_mode))) {
447                         fattr->cf_mode =
448                                 le32_to_cpu(ppace[i]->sid.sub_auth[2]);
449                         break;
450                 } else if (!compare_sids(&ppace[i]->sid, pownersid)) {
451                         acl_mode = access_flags_to_mode(fattr,
452                                                         ppace[i]->access_req,
453                                                         ppace[i]->type);
454                         acl_mode &= 0700;
455 
456                         if (!owner_found) {
457                                 mode &= ~(0700);
458                                 mode |= acl_mode;
459                         }
460                         owner_found = true;
461                 } else if (!compare_sids(&ppace[i]->sid, pgrpsid) ||
462                            ppace[i]->sid.sub_auth[ppace[i]->sid.num_subauth - 1] ==
463                             DOMAIN_USER_RID_LE) {
464                         acl_mode = access_flags_to_mode(fattr,
465                                                         ppace[i]->access_req,
466                                                         ppace[i]->type);
467                         acl_mode &= 0070;
468                         if (!group_found) {
469                                 mode &= ~(0070);
470                                 mode |= acl_mode;
471                         }
472                         group_found = true;
473                 } else if (!compare_sids(&ppace[i]->sid, &sid_everyone)) {
474                         acl_mode = access_flags_to_mode(fattr,
475                                                         ppace[i]->access_req,
476                                                         ppace[i]->type);
477                         acl_mode &= 0007;
478                         if (!others_found) {
479                                 mode &= ~(0007);
480                                 mode |= acl_mode;
481                         }
482                         others_found = true;
483                 } else if (!compare_sids(&ppace[i]->sid, &creator_owner)) {
484                         continue;
485                 } else if (!compare_sids(&ppace[i]->sid, &creator_group)) {
486                         continue;
487                 } else if (!compare_sids(&ppace[i]->sid, &sid_authusers)) {
488                         continue;
489                 } else {
490                         struct smb_fattr temp_fattr;
491 
492                         acl_mode = access_flags_to_mode(fattr, ppace[i]->access_req,
493                                                         ppace[i]->type);
494                         temp_fattr.cf_uid = INVALID_UID;
495                         ret = sid_to_id(idmap, &ppace[i]->sid, SIDOWNER, &temp_fattr);
496                         if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) {
497                                 pr_err("%s: Error %d mapping Owner SID to uid\n",
498                                        __func__, ret);
499                                 continue;
500                         }
501 
502                         acl_state.owner.allow = ((acl_mode & 0700) >> 6) | 0004;
503                         acl_state.users->aces[acl_state.users->n].uid =
504                                 temp_fattr.cf_uid;
505                         acl_state.users->aces[acl_state.users->n++].perms.allow =
506                                 ((acl_mode & 0700) >> 6) | 0004;
507                         default_acl_state.owner.allow = ((acl_mode & 0700) >> 6) | 0004;
508                         default_acl_state.users->aces[default_acl_state.users->n].uid =
509                                 temp_fattr.cf_uid;
510                         default_acl_state.users->aces[default_acl_state.users->n++].perms.allow =
511                                 ((acl_mode & 0700) >> 6) | 0004;
512                 }
513         }
514         kfree(ppace);
515 
516         if (owner_found) {
517                 /* The owner must be set to at least read-only. */
518                 acl_state.owner.allow = ((mode & 0700) >> 6) | 0004;
519                 acl_state.users->aces[acl_state.users->n].uid = fattr->cf_uid;
520                 acl_state.users->aces[acl_state.users->n++].perms.allow =
521                         ((mode & 0700) >> 6) | 0004;
522                 default_acl_state.owner.allow = ((mode & 0700) >> 6) | 0004;
523                 default_acl_state.users->aces[default_acl_state.users->n].uid =
524                         fattr->cf_uid;
525                 default_acl_state.users->aces[default_acl_state.users->n++].perms.allow =
526                         ((mode & 0700) >> 6) | 0004;
527         }
528 
529         if (group_found) {
530                 acl_state.group.allow = (mode & 0070) >> 3;
531                 acl_state.groups->aces[acl_state.groups->n].gid =
532                         fattr->cf_gid;
533                 acl_state.groups->aces[acl_state.groups->n++].perms.allow =
534                         (mode & 0070) >> 3;
535                 default_acl_state.group.allow = (mode & 0070) >> 3;
536                 default_acl_state.groups->aces[default_acl_state.groups->n].gid =
537                         fattr->cf_gid;
538                 default_acl_state.groups->aces[default_acl_state.groups->n++].perms.allow =
539                         (mode & 0070) >> 3;
540         }
541 
542         if (others_found) {
543                 fattr->cf_mode &= ~(0007);
544                 fattr->cf_mode |= mode & 0007;
545 
546                 acl_state.other.allow = mode & 0007;
547                 default_acl_state.other.allow = mode & 0007;
548         }
549 
550         if (acl_state.users->n || acl_state.groups->n) {
551                 acl_state.mask.allow = 0x07;
552 
553                 if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
554                         fattr->cf_acls =
555                                 posix_acl_alloc(acl_state.users->n +
556                                         acl_state.groups->n + 4, GFP_KERNEL);
557                         if (fattr->cf_acls) {
558                                 cf_pace = fattr->cf_acls->a_entries;
559                                 posix_state_to_acl(&acl_state, cf_pace);
560                         }
561                 }
562         }
563 
564         if (default_acl_state.users->n || default_acl_state.groups->n) {
565                 default_acl_state.mask.allow = 0x07;
566 
567                 if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
568                         fattr->cf_dacls =
569                                 posix_acl_alloc(default_acl_state.users->n +
570                                 default_acl_state.groups->n + 4, GFP_KERNEL);
571                         if (fattr->cf_dacls) {
572                                 cf_pdace = fattr->cf_dacls->a_entries;
573                                 posix_state_to_acl(&default_acl_state, cf_pdace);
574                         }
575                 }
576         }
577         free_acl_state(&acl_state);
578         free_acl_state(&default_acl_state);
579 }
580 
581 static void set_posix_acl_entries_dacl(struct mnt_idmap *idmap,
582                                        struct smb_ace *pndace,
583                                        struct smb_fattr *fattr, u32 *num_aces,
584                                        u16 *size, u32 nt_aces_num)
585 {
586         struct posix_acl_entry *pace;
587         struct smb_sid *sid;
588         struct smb_ace *ntace;
589         int i, j;
590 
591         if (!fattr->cf_acls)
592                 goto posix_default_acl;
593 
594         pace = fattr->cf_acls->a_entries;
595         for (i = 0; i < fattr->cf_acls->a_count; i++, pace++) {
596                 int flags = 0;
597 
598                 sid = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
599                 if (!sid)
600                         break;
601 
602                 if (pace->e_tag == ACL_USER) {
603                         uid_t uid;
604                         unsigned int sid_type = SIDOWNER;
605 
606                         uid = posix_acl_uid_translate(idmap, pace);
607                         if (!uid)
608                                 sid_type = SIDUNIX_USER;
609                         id_to_sid(uid, sid_type, sid);
610                 } else if (pace->e_tag == ACL_GROUP) {
611                         gid_t gid;
612 
613                         gid = posix_acl_gid_translate(idmap, pace);
614                         id_to_sid(gid, SIDUNIX_GROUP, sid);
615                 } else if (pace->e_tag == ACL_OTHER && !nt_aces_num) {
616                         smb_copy_sid(sid, &sid_everyone);
617                 } else {
618                         kfree(sid);
619                         continue;
620                 }
621                 ntace = pndace;
622                 for (j = 0; j < nt_aces_num; j++) {
623                         if (ntace->sid.sub_auth[ntace->sid.num_subauth - 1] ==
624                                         sid->sub_auth[sid->num_subauth - 1])
625                                 goto pass_same_sid;
626                         ntace = (struct smb_ace *)((char *)ntace +
627                                         le16_to_cpu(ntace->size));
628                 }
629 
630                 if (S_ISDIR(fattr->cf_mode) && pace->e_tag == ACL_OTHER)
631                         flags = 0x03;
632 
633                 ntace = (struct smb_ace *)((char *)pndace + *size);
634                 *size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, flags,
635                                 pace->e_perm, 0777);
636                 (*num_aces)++;
637                 if (pace->e_tag == ACL_USER)
638                         ntace->access_req |=
639                                 FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
640 
641                 if (S_ISDIR(fattr->cf_mode) &&
642                     (pace->e_tag == ACL_USER || pace->e_tag == ACL_GROUP)) {
643                         ntace = (struct smb_ace *)((char *)pndace + *size);
644                         *size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED,
645                                         0x03, pace->e_perm, 0777);
646                         (*num_aces)++;
647                         if (pace->e_tag == ACL_USER)
648                                 ntace->access_req |=
649                                         FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
650                 }
651 
652 pass_same_sid:
653                 kfree(sid);
654         }
655 
656         if (nt_aces_num)
657                 return;
658 
659 posix_default_acl:
660         if (!fattr->cf_dacls)
661                 return;
662 
663         pace = fattr->cf_dacls->a_entries;
664         for (i = 0; i < fattr->cf_dacls->a_count; i++, pace++) {
665                 sid = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
666                 if (!sid)
667                         break;
668 
669                 if (pace->e_tag == ACL_USER) {
670                         uid_t uid;
671 
672                         uid = posix_acl_uid_translate(idmap, pace);
673                         id_to_sid(uid, SIDCREATOR_OWNER, sid);
674                 } else if (pace->e_tag == ACL_GROUP) {
675                         gid_t gid;
676 
677                         gid = posix_acl_gid_translate(idmap, pace);
678                         id_to_sid(gid, SIDCREATOR_GROUP, sid);
679                 } else {
680                         kfree(sid);
681                         continue;
682                 }
683 
684                 ntace = (struct smb_ace *)((char *)pndace + *size);
685                 *size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, 0x0b,
686                                 pace->e_perm, 0777);
687                 (*num_aces)++;
688                 if (pace->e_tag == ACL_USER)
689                         ntace->access_req |=
690                                 FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
691                 kfree(sid);
692         }
693 }
694 
695 static void set_ntacl_dacl(struct mnt_idmap *idmap,
696                            struct smb_acl *pndacl,
697                            struct smb_acl *nt_dacl,
698                            unsigned int aces_size,
699                            const struct smb_sid *pownersid,
700                            const struct smb_sid *pgrpsid,
701                            struct smb_fattr *fattr)
702 {
703         struct smb_ace *ntace, *pndace;
704         int nt_num_aces = le32_to_cpu(nt_dacl->num_aces), num_aces = 0;
705         unsigned short size = 0;
706         int i;
707 
708         pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
709         if (nt_num_aces) {
710                 ntace = (struct smb_ace *)((char *)nt_dacl + sizeof(struct smb_acl));
711                 for (i = 0; i < nt_num_aces; i++) {
712                         unsigned short nt_ace_size;
713 
714                         if (offsetof(struct smb_ace, access_req) > aces_size)
715                                 break;
716 
717                         nt_ace_size = le16_to_cpu(ntace->size);
718                         if (nt_ace_size > aces_size)
719                                 break;
720 
721                         memcpy((char *)pndace + size, ntace, nt_ace_size);
722                         size += nt_ace_size;
723                         aces_size -= nt_ace_size;
724                         ntace = (struct smb_ace *)((char *)ntace + nt_ace_size);
725                         num_aces++;
726                 }
727         }
728 
729         set_posix_acl_entries_dacl(idmap, pndace, fattr,
730                                    &num_aces, &size, nt_num_aces);
731         pndacl->num_aces = cpu_to_le32(num_aces);
732         pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
733 }
734 
735 static void set_mode_dacl(struct mnt_idmap *idmap,
736                           struct smb_acl *pndacl, struct smb_fattr *fattr)
737 {
738         struct smb_ace *pace, *pndace;
739         u32 num_aces = 0;
740         u16 size = 0, ace_size = 0;
741         uid_t uid;
742         const struct smb_sid *sid;
743 
744         pace = pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
745 
746         if (fattr->cf_acls) {
747                 set_posix_acl_entries_dacl(idmap, pndace, fattr,
748                                            &num_aces, &size, num_aces);
749                 goto out;
750         }
751 
752         /* owner RID */
753         uid = from_kuid(&init_user_ns, fattr->cf_uid);
754         if (uid)
755                 sid = &server_conf.domain_sid;
756         else
757                 sid = &sid_unix_users;
758         ace_size = fill_ace_for_sid(pace, sid, ACCESS_ALLOWED, 0,
759                                     fattr->cf_mode, 0700);
760         pace->sid.sub_auth[pace->sid.num_subauth++] = cpu_to_le32(uid);
761         pace->size = cpu_to_le16(ace_size + 4);
762         size += le16_to_cpu(pace->size);
763         pace = (struct smb_ace *)((char *)pndace + size);
764 
765         /* Group RID */
766         ace_size = fill_ace_for_sid(pace, &sid_unix_groups,
767                                     ACCESS_ALLOWED, 0, fattr->cf_mode, 0070);
768         pace->sid.sub_auth[pace->sid.num_subauth++] =
769                 cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid));
770         pace->size = cpu_to_le16(ace_size + 4);
771         size += le16_to_cpu(pace->size);
772         pace = (struct smb_ace *)((char *)pndace + size);
773         num_aces = 3;
774 
775         if (S_ISDIR(fattr->cf_mode)) {
776                 pace = (struct smb_ace *)((char *)pndace + size);
777 
778                 /* creator owner */
779                 size += fill_ace_for_sid(pace, &creator_owner, ACCESS_ALLOWED,
780                                          0x0b, fattr->cf_mode, 0700);
781                 pace = (struct smb_ace *)((char *)pndace + size);
782 
783                 /* creator group */
784                 size += fill_ace_for_sid(pace, &creator_group, ACCESS_ALLOWED,
785                                          0x0b, fattr->cf_mode, 0070);
786                 pace = (struct smb_ace *)((char *)pndace + size);
787                 num_aces = 5;
788         }
789 
790         /* other */
791         size += fill_ace_for_sid(pace, &sid_everyone, ACCESS_ALLOWED, 0,
792                                  fattr->cf_mode, 0007);
793 
794 out:
795         pndacl->num_aces = cpu_to_le32(num_aces);
796         pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
797 }
798 
799 static int parse_sid(struct smb_sid *psid, char *end_of_acl)
800 {
801         /*
802          * validate that we do not go past end of ACL - sid must be at least 8
803          * bytes long (assuming no sub-auths - e.g. the null SID
804          */
805         if (end_of_acl < (char *)psid + 8) {
806                 pr_err("ACL too small to parse SID %p\n", psid);
807                 return -EINVAL;
808         }
809 
810         return 0;
811 }
812 
813 /* Convert CIFS ACL to POSIX form */
814 int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
815                    int acl_len, struct smb_fattr *fattr)
816 {
817         int rc = 0;
818         struct smb_sid *owner_sid_ptr, *group_sid_ptr;
819         struct smb_acl *dacl_ptr; /* no need for SACL ptr */
820         char *end_of_acl = ((char *)pntsd) + acl_len;
821         __u32 dacloffset;
822         int pntsd_type;
823 
824         if (!pntsd)
825                 return -EIO;
826 
827         if (acl_len < sizeof(struct smb_ntsd))
828                 return -EINVAL;
829 
830         owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
831                         le32_to_cpu(pntsd->osidoffset));
832         group_sid_ptr = (struct smb_sid *)((char *)pntsd +
833                         le32_to_cpu(pntsd->gsidoffset));
834         dacloffset = le32_to_cpu(pntsd->dacloffset);
835         dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
836         ksmbd_debug(SMB,
837                     "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
838                     pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
839                     le32_to_cpu(pntsd->gsidoffset),
840                     le32_to_cpu(pntsd->sacloffset), dacloffset);
841 
842         pntsd_type = le16_to_cpu(pntsd->type);
843         if (!(pntsd_type & DACL_PRESENT)) {
844                 ksmbd_debug(SMB, "DACL_PRESENT in DACL type is not set\n");
845                 return rc;
846         }
847 
848         pntsd->type = cpu_to_le16(DACL_PRESENT);
849 
850         if (pntsd->osidoffset) {
851                 rc = parse_sid(owner_sid_ptr, end_of_acl);
852                 if (rc) {
853                         pr_err("%s: Error %d parsing Owner SID\n", __func__, rc);
854                         return rc;
855                 }
856 
857                 rc = sid_to_id(idmap, owner_sid_ptr, SIDOWNER, fattr);
858                 if (rc) {
859                         pr_err("%s: Error %d mapping Owner SID to uid\n",
860                                __func__, rc);
861                         owner_sid_ptr = NULL;
862                 }
863         }
864 
865         if (pntsd->gsidoffset) {
866                 rc = parse_sid(group_sid_ptr, end_of_acl);
867                 if (rc) {
868                         pr_err("%s: Error %d mapping Owner SID to gid\n",
869                                __func__, rc);
870                         return rc;
871                 }
872                 rc = sid_to_id(idmap, group_sid_ptr, SIDUNIX_GROUP, fattr);
873                 if (rc) {
874                         pr_err("%s: Error %d mapping Group SID to gid\n",
875                                __func__, rc);
876                         group_sid_ptr = NULL;
877                 }
878         }
879 
880         if ((pntsd_type & (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ)) ==
881             (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ))
882                 pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
883         if (pntsd_type & DACL_PROTECTED)
884                 pntsd->type |= cpu_to_le16(DACL_PROTECTED);
885 
886         if (dacloffset) {
887                 parse_dacl(idmap, dacl_ptr, end_of_acl,
888                            owner_sid_ptr, group_sid_ptr, fattr);
889         }
890 
891         return 0;
892 }
893 
894 /* Convert permission bits from mode to equivalent CIFS ACL */
895 int build_sec_desc(struct mnt_idmap *idmap,
896                    struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
897                    int ppntsd_size, int addition_info, __u32 *secdesclen,
898                    struct smb_fattr *fattr)
899 {
900         int rc = 0;
901         __u32 offset;
902         struct smb_sid *owner_sid_ptr, *group_sid_ptr;
903         struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr;
904         struct smb_acl *dacl_ptr = NULL; /* no need for SACL ptr */
905         uid_t uid;
906         gid_t gid;
907         unsigned int sid_type = SIDOWNER;
908 
909         nowner_sid_ptr = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
910         if (!nowner_sid_ptr)
911                 return -ENOMEM;
912 
913         uid = from_kuid(&init_user_ns, fattr->cf_uid);
914         if (!uid)
915                 sid_type = SIDUNIX_USER;
916         id_to_sid(uid, sid_type, nowner_sid_ptr);
917 
918         ngroup_sid_ptr = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
919         if (!ngroup_sid_ptr) {
920                 kfree(nowner_sid_ptr);
921                 return -ENOMEM;
922         }
923 
924         gid = from_kgid(&init_user_ns, fattr->cf_gid);
925         id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr);
926 
927         offset = sizeof(struct smb_ntsd);
928         pntsd->sacloffset = 0;
929         pntsd->revision = cpu_to_le16(1);
930         pntsd->type = cpu_to_le16(SELF_RELATIVE);
931         if (ppntsd)
932                 pntsd->type |= ppntsd->type;
933 
934         if (addition_info & OWNER_SECINFO) {
935                 pntsd->osidoffset = cpu_to_le32(offset);
936                 owner_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
937                 smb_copy_sid(owner_sid_ptr, nowner_sid_ptr);
938                 offset += 1 + 1 + 6 + (nowner_sid_ptr->num_subauth * 4);
939         }
940 
941         if (addition_info & GROUP_SECINFO) {
942                 pntsd->gsidoffset = cpu_to_le32(offset);
943                 group_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
944                 smb_copy_sid(group_sid_ptr, ngroup_sid_ptr);
945                 offset += 1 + 1 + 6 + (ngroup_sid_ptr->num_subauth * 4);
946         }
947 
948         if (addition_info & DACL_SECINFO) {
949                 pntsd->type |= cpu_to_le16(DACL_PRESENT);
950                 dacl_ptr = (struct smb_acl *)((char *)pntsd + offset);
951                 dacl_ptr->revision = cpu_to_le16(2);
952                 dacl_ptr->size = cpu_to_le16(sizeof(struct smb_acl));
953                 dacl_ptr->num_aces = 0;
954 
955                 if (!ppntsd) {
956                         set_mode_dacl(idmap, dacl_ptr, fattr);
957                 } else {
958                         struct smb_acl *ppdacl_ptr;
959                         unsigned int dacl_offset = le32_to_cpu(ppntsd->dacloffset);
960                         int ppdacl_size, ntacl_size = ppntsd_size - dacl_offset;
961 
962                         if (!dacl_offset ||
963                             (dacl_offset + sizeof(struct smb_acl) > ppntsd_size))
964                                 goto out;
965 
966                         ppdacl_ptr = (struct smb_acl *)((char *)ppntsd + dacl_offset);
967                         ppdacl_size = le16_to_cpu(ppdacl_ptr->size);
968                         if (ppdacl_size > ntacl_size ||
969                             ppdacl_size < sizeof(struct smb_acl))
970                                 goto out;
971 
972                         set_ntacl_dacl(idmap, dacl_ptr, ppdacl_ptr,
973                                        ntacl_size - sizeof(struct smb_acl),
974                                        nowner_sid_ptr, ngroup_sid_ptr,
975                                        fattr);
976                 }
977                 pntsd->dacloffset = cpu_to_le32(offset);
978                 offset += le16_to_cpu(dacl_ptr->size);
979         }
980 
981 out:
982         kfree(nowner_sid_ptr);
983         kfree(ngroup_sid_ptr);
984         *secdesclen = offset;
985         return rc;
986 }
987 
988 static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type,
989                         u8 flags, __le32 access_req)
990 {
991         ace->type = type;
992         ace->flags = flags;
993         ace->access_req = access_req;
994         smb_copy_sid(&ace->sid, sid);
995         ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 + (sid->num_subauth * 4));
996 }
997 
998 int smb_inherit_dacl(struct ksmbd_conn *conn,
999                      const struct path *path,
1000                      unsigned int uid, unsigned int gid)
1001 {
1002         const struct smb_sid *psid, *creator = NULL;
1003         struct smb_ace *parent_aces, *aces;
1004         struct smb_acl *parent_pdacl;
1005         struct smb_ntsd *parent_pntsd = NULL;
1006         struct smb_sid owner_sid, group_sid;
1007         struct dentry *parent = path->dentry->d_parent;
1008         struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1009         int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0, pdacl_size;
1010         int rc = 0, num_aces, dacloffset, pntsd_type, pntsd_size, acl_len, aces_size;
1011         char *aces_base;
1012         bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
1013 
1014         pntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
1015                                             parent, &parent_pntsd);
1016         if (pntsd_size <= 0)
1017                 return -ENOENT;
1018         dacloffset = le32_to_cpu(parent_pntsd->dacloffset);
1019         if (!dacloffset || (dacloffset + sizeof(struct smb_acl) > pntsd_size)) {
1020                 rc = -EINVAL;
1021                 goto free_parent_pntsd;
1022         }
1023 
1024         parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset);
1025         acl_len = pntsd_size - dacloffset;
1026         num_aces = le32_to_cpu(parent_pdacl->num_aces);
1027         pntsd_type = le16_to_cpu(parent_pntsd->type);
1028         pdacl_size = le16_to_cpu(parent_pdacl->size);
1029 
1030         if (pdacl_size > acl_len || pdacl_size < sizeof(struct smb_acl)) {
1031                 rc = -EINVAL;
1032                 goto free_parent_pntsd;
1033         }
1034 
1035         aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2, GFP_KERNEL);
1036         if (!aces_base) {
1037                 rc = -ENOMEM;
1038                 goto free_parent_pntsd;
1039         }
1040 
1041         aces = (struct smb_ace *)aces_base;
1042         parent_aces = (struct smb_ace *)((char *)parent_pdacl +
1043                         sizeof(struct smb_acl));
1044         aces_size = acl_len - sizeof(struct smb_acl);
1045 
1046         if (pntsd_type & DACL_AUTO_INHERITED)
1047                 inherited_flags = INHERITED_ACE;
1048 
1049         for (i = 0; i < num_aces; i++) {
1050                 int pace_size;
1051 
1052                 if (offsetof(struct smb_ace, access_req) > aces_size)
1053                         break;
1054 
1055                 pace_size = le16_to_cpu(parent_aces->size);
1056                 if (pace_size > aces_size)
1057                         break;
1058 
1059                 aces_size -= pace_size;
1060 
1061                 flags = parent_aces->flags;
1062                 if (!smb_inherit_flags(flags, is_dir))
1063                         goto pass;
1064                 if (is_dir) {
1065                         flags &= ~(INHERIT_ONLY_ACE | INHERITED_ACE);
1066                         if (!(flags & CONTAINER_INHERIT_ACE))
1067                                 flags |= INHERIT_ONLY_ACE;
1068                         if (flags & NO_PROPAGATE_INHERIT_ACE)
1069                                 flags = 0;
1070                 } else {
1071                         flags = 0;
1072                 }
1073 
1074                 if (!compare_sids(&creator_owner, &parent_aces->sid)) {
1075                         creator = &creator_owner;
1076                         id_to_sid(uid, SIDOWNER, &owner_sid);
1077                         psid = &owner_sid;
1078                 } else if (!compare_sids(&creator_group, &parent_aces->sid)) {
1079                         creator = &creator_group;
1080                         id_to_sid(gid, SIDUNIX_GROUP, &group_sid);
1081                         psid = &group_sid;
1082                 } else {
1083                         creator = NULL;
1084                         psid = &parent_aces->sid;
1085                 }
1086 
1087                 if (is_dir && creator && flags & CONTAINER_INHERIT_ACE) {
1088                         smb_set_ace(aces, psid, parent_aces->type, inherited_flags,
1089                                     parent_aces->access_req);
1090                         nt_size += le16_to_cpu(aces->size);
1091                         ace_cnt++;
1092                         aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
1093                         flags |= INHERIT_ONLY_ACE;
1094                         psid = creator;
1095                 } else if (is_dir && !(parent_aces->flags & NO_PROPAGATE_INHERIT_ACE)) {
1096                         psid = &parent_aces->sid;
1097                 }
1098 
1099                 smb_set_ace(aces, psid, parent_aces->type, flags | inherited_flags,
1100                             parent_aces->access_req);
1101                 nt_size += le16_to_cpu(aces->size);
1102                 aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
1103                 ace_cnt++;
1104 pass:
1105                 parent_aces = (struct smb_ace *)((char *)parent_aces + pace_size);
1106         }
1107 
1108         if (nt_size > 0) {
1109                 struct smb_ntsd *pntsd;
1110                 struct smb_acl *pdacl;
1111                 struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL;
1112                 int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
1113                 int pntsd_alloc_size;
1114 
1115                 if (parent_pntsd->osidoffset) {
1116                         powner_sid = (struct smb_sid *)((char *)parent_pntsd +
1117                                         le32_to_cpu(parent_pntsd->osidoffset));
1118                         powner_sid_size = 1 + 1 + 6 + (powner_sid->num_subauth * 4);
1119                 }
1120                 if (parent_pntsd->gsidoffset) {
1121                         pgroup_sid = (struct smb_sid *)((char *)parent_pntsd +
1122                                         le32_to_cpu(parent_pntsd->gsidoffset));
1123                         pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4);
1124                 }
1125 
1126                 pntsd_alloc_size = sizeof(struct smb_ntsd) + powner_sid_size +
1127                         pgroup_sid_size + sizeof(struct smb_acl) + nt_size;
1128 
1129                 pntsd = kzalloc(pntsd_alloc_size, GFP_KERNEL);
1130                 if (!pntsd) {
1131                         rc = -ENOMEM;
1132                         goto free_aces_base;
1133                 }
1134 
1135                 pntsd->revision = cpu_to_le16(1);
1136                 pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PRESENT);
1137                 if (le16_to_cpu(parent_pntsd->type) & DACL_AUTO_INHERITED)
1138                         pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
1139                 pntsd_size = sizeof(struct smb_ntsd);
1140                 pntsd->osidoffset = parent_pntsd->osidoffset;
1141                 pntsd->gsidoffset = parent_pntsd->gsidoffset;
1142                 pntsd->dacloffset = parent_pntsd->dacloffset;
1143 
1144                 if ((u64)le32_to_cpu(pntsd->osidoffset) + powner_sid_size >
1145                     pntsd_alloc_size) {
1146                         rc = -EINVAL;
1147                         kfree(pntsd);
1148                         goto free_aces_base;
1149                 }
1150 
1151                 if ((u64)le32_to_cpu(pntsd->gsidoffset) + pgroup_sid_size >
1152                     pntsd_alloc_size) {
1153                         rc = -EINVAL;
1154                         kfree(pntsd);
1155                         goto free_aces_base;
1156                 }
1157 
1158                 if ((u64)le32_to_cpu(pntsd->dacloffset) + sizeof(struct smb_acl) + nt_size >
1159                     pntsd_alloc_size) {
1160                         rc = -EINVAL;
1161                         kfree(pntsd);
1162                         goto free_aces_base;
1163                 }
1164 
1165                 if (pntsd->osidoffset) {
1166                         struct smb_sid *owner_sid = (struct smb_sid *)((char *)pntsd +
1167                                         le32_to_cpu(pntsd->osidoffset));
1168                         memcpy(owner_sid, powner_sid, powner_sid_size);
1169                         pntsd_size += powner_sid_size;
1170                 }
1171 
1172                 if (pntsd->gsidoffset) {
1173                         struct smb_sid *group_sid = (struct smb_sid *)((char *)pntsd +
1174                                         le32_to_cpu(pntsd->gsidoffset));
1175                         memcpy(group_sid, pgroup_sid, pgroup_sid_size);
1176                         pntsd_size += pgroup_sid_size;
1177                 }
1178 
1179                 if (pntsd->dacloffset) {
1180                         struct smb_ace *pace;
1181 
1182                         pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1183                         pdacl->revision = cpu_to_le16(2);
1184                         pdacl->size = cpu_to_le16(sizeof(struct smb_acl) + nt_size);
1185                         pdacl->num_aces = cpu_to_le32(ace_cnt);
1186                         pace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1187                         memcpy(pace, aces_base, nt_size);
1188                         pntsd_size += sizeof(struct smb_acl) + nt_size;
1189                 }
1190 
1191                 ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, pntsd_size, false);
1192                 kfree(pntsd);
1193         }
1194 
1195 free_aces_base:
1196         kfree(aces_base);
1197 free_parent_pntsd:
1198         kfree(parent_pntsd);
1199         return rc;
1200 }
1201 
1202 bool smb_inherit_flags(int flags, bool is_dir)
1203 {
1204         if (!is_dir)
1205                 return (flags & OBJECT_INHERIT_ACE) != 0;
1206 
1207         if (flags & OBJECT_INHERIT_ACE && !(flags & NO_PROPAGATE_INHERIT_ACE))
1208                 return true;
1209 
1210         if (flags & CONTAINER_INHERIT_ACE)
1211                 return true;
1212         return false;
1213 }
1214 
1215 int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
1216                         __le32 *pdaccess, int uid)
1217 {
1218         struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1219         struct smb_ntsd *pntsd = NULL;
1220         struct smb_acl *pdacl;
1221         struct posix_acl *posix_acls;
1222         int rc = 0, pntsd_size, acl_size, aces_size, pdacl_size, dacl_offset;
1223         struct smb_sid sid;
1224         int granted = le32_to_cpu(*pdaccess & ~FILE_MAXIMAL_ACCESS_LE);
1225         struct smb_ace *ace;
1226         int i, found = 0;
1227         unsigned int access_bits = 0;
1228         struct smb_ace *others_ace = NULL;
1229         struct posix_acl_entry *pa_entry;
1230         unsigned int sid_type = SIDOWNER;
1231         unsigned short ace_size;
1232 
1233         ksmbd_debug(SMB, "check permission using windows acl\n");
1234         pntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
1235                                             path->dentry, &pntsd);
1236         if (pntsd_size <= 0 || !pntsd)
1237                 goto err_out;
1238 
1239         dacl_offset = le32_to_cpu(pntsd->dacloffset);
1240         if (!dacl_offset ||
1241             (dacl_offset + sizeof(struct smb_acl) > pntsd_size))
1242                 goto err_out;
1243 
1244         pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1245         acl_size = pntsd_size - dacl_offset;
1246         pdacl_size = le16_to_cpu(pdacl->size);
1247 
1248         if (pdacl_size > acl_size || pdacl_size < sizeof(struct smb_acl))
1249                 goto err_out;
1250 
1251         if (!pdacl->num_aces) {
1252                 if (!(pdacl_size - sizeof(struct smb_acl)) &&
1253                     *pdaccess & ~(FILE_READ_CONTROL_LE | FILE_WRITE_DAC_LE)) {
1254                         rc = -EACCES;
1255                         goto err_out;
1256                 }
1257                 goto err_out;
1258         }
1259 
1260         if (*pdaccess & FILE_MAXIMAL_ACCESS_LE) {
1261                 granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1262                         DELETE;
1263 
1264                 ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1265                 aces_size = acl_size - sizeof(struct smb_acl);
1266                 for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1267                         if (offsetof(struct smb_ace, access_req) > aces_size)
1268                                 break;
1269                         ace_size = le16_to_cpu(ace->size);
1270                         if (ace_size > aces_size)
1271                                 break;
1272                         aces_size -= ace_size;
1273                         granted |= le32_to_cpu(ace->access_req);
1274                         ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1275                 }
1276 
1277                 if (!pdacl->num_aces)
1278                         granted = GENERIC_ALL_FLAGS;
1279         }
1280 
1281         if (!uid)
1282                 sid_type = SIDUNIX_USER;
1283         id_to_sid(uid, sid_type, &sid);
1284 
1285         ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1286         aces_size = acl_size - sizeof(struct smb_acl);
1287         for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1288                 if (offsetof(struct smb_ace, access_req) > aces_size)
1289                         break;
1290                 ace_size = le16_to_cpu(ace->size);
1291                 if (ace_size > aces_size)
1292                         break;
1293                 aces_size -= ace_size;
1294 
1295                 if (!compare_sids(&sid, &ace->sid) ||
1296                     !compare_sids(&sid_unix_NFS_mode, &ace->sid)) {
1297                         found = 1;
1298                         break;
1299                 }
1300                 if (!compare_sids(&sid_everyone, &ace->sid))
1301                         others_ace = ace;
1302 
1303                 ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1304         }
1305 
1306         if (*pdaccess & FILE_MAXIMAL_ACCESS_LE && found) {
1307                 granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1308                         DELETE;
1309 
1310                 granted |= le32_to_cpu(ace->access_req);
1311 
1312                 if (!pdacl->num_aces)
1313                         granted = GENERIC_ALL_FLAGS;
1314         }
1315 
1316         if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
1317                 posix_acls = get_inode_acl(d_inode(path->dentry), ACL_TYPE_ACCESS);
1318                 if (!IS_ERR_OR_NULL(posix_acls) && !found) {
1319                         unsigned int id = -1;
1320 
1321                         pa_entry = posix_acls->a_entries;
1322                         for (i = 0; i < posix_acls->a_count; i++, pa_entry++) {
1323                                 if (pa_entry->e_tag == ACL_USER)
1324                                         id = posix_acl_uid_translate(idmap, pa_entry);
1325                                 else if (pa_entry->e_tag == ACL_GROUP)
1326                                         id = posix_acl_gid_translate(idmap, pa_entry);
1327                                 else
1328                                         continue;
1329 
1330                                 if (id == uid) {
1331                                         mode_to_access_flags(pa_entry->e_perm,
1332                                                              0777,
1333                                                              &access_bits);
1334                                         if (!access_bits)
1335                                                 access_bits =
1336                                                         SET_MINIMUM_RIGHTS;
1337                                         posix_acl_release(posix_acls);
1338                                         goto check_access_bits;
1339                                 }
1340                         }
1341                 }
1342                 if (!IS_ERR_OR_NULL(posix_acls))
1343                         posix_acl_release(posix_acls);
1344         }
1345 
1346         if (!found) {
1347                 if (others_ace) {
1348                         ace = others_ace;
1349                 } else {
1350                         ksmbd_debug(SMB, "Can't find corresponding sid\n");
1351                         rc = -EACCES;
1352                         goto err_out;
1353                 }
1354         }
1355 
1356         switch (ace->type) {
1357         case ACCESS_ALLOWED_ACE_TYPE:
1358                 access_bits = le32_to_cpu(ace->access_req);
1359                 break;
1360         case ACCESS_DENIED_ACE_TYPE:
1361         case ACCESS_DENIED_CALLBACK_ACE_TYPE:
1362                 access_bits = le32_to_cpu(~ace->access_req);
1363                 break;
1364         }
1365 
1366 check_access_bits:
1367         if (granted &
1368             ~(access_bits | FILE_READ_ATTRIBUTES | READ_CONTROL | WRITE_DAC | DELETE)) {
1369                 ksmbd_debug(SMB, "Access denied with winACL, granted : %x, access_req : %x\n",
1370                             granted, le32_to_cpu(ace->access_req));
1371                 rc = -EACCES;
1372                 goto err_out;
1373         }
1374 
1375         *pdaccess = cpu_to_le32(granted);
1376 err_out:
1377         kfree(pntsd);
1378         return rc;
1379 }
1380 
1381 int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
1382                  const struct path *path, struct smb_ntsd *pntsd, int ntsd_len,
1383                  bool type_check, bool get_write)
1384 {
1385         int rc;
1386         struct smb_fattr fattr = {{0}};
1387         struct inode *inode = d_inode(path->dentry);
1388         struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1389         struct iattr newattrs;
1390 
1391         fattr.cf_uid = INVALID_UID;
1392         fattr.cf_gid = INVALID_GID;
1393         fattr.cf_mode = inode->i_mode;
1394 
1395         rc = parse_sec_desc(idmap, pntsd, ntsd_len, &fattr);
1396         if (rc)
1397                 goto out;
1398 
1399         newattrs.ia_valid = ATTR_CTIME;
1400         if (!uid_eq(fattr.cf_uid, INVALID_UID)) {
1401                 newattrs.ia_valid |= ATTR_UID;
1402                 newattrs.ia_uid = fattr.cf_uid;
1403         }
1404         if (!gid_eq(fattr.cf_gid, INVALID_GID)) {
1405                 newattrs.ia_valid |= ATTR_GID;
1406                 newattrs.ia_gid = fattr.cf_gid;
1407         }
1408         newattrs.ia_valid |= ATTR_MODE;
1409         newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
1410 
1411         ksmbd_vfs_remove_acl_xattrs(idmap, path);
1412         /* Update posix acls */
1413         if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) {
1414                 rc = set_posix_acl(idmap, path->dentry,
1415                                    ACL_TYPE_ACCESS, fattr.cf_acls);
1416                 if (rc < 0)
1417                         ksmbd_debug(SMB,
1418                                     "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
1419                                     rc);
1420                 if (S_ISDIR(inode->i_mode) && fattr.cf_dacls) {
1421                         rc = set_posix_acl(idmap, path->dentry,
1422                                            ACL_TYPE_DEFAULT, fattr.cf_dacls);
1423                         if (rc)
1424                                 ksmbd_debug(SMB,
1425                                             "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
1426                                             rc);
1427                 }
1428         }
1429 
1430         inode_lock(inode);
1431         rc = notify_change(idmap, path->dentry, &newattrs, NULL);
1432         inode_unlock(inode);
1433         if (rc)
1434                 goto out;
1435 
1436         /* Check it only calling from SD BUFFER context */
1437         if (type_check && !(le16_to_cpu(pntsd->type) & DACL_PRESENT))
1438                 goto out;
1439 
1440         if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
1441                 /* Update WinACL in xattr */
1442                 ksmbd_vfs_remove_sd_xattrs(idmap, path);
1443                 ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, ntsd_len,
1444                                 get_write);
1445         }
1446 
1447 out:
1448         posix_acl_release(fattr.cf_acls);
1449         posix_acl_release(fattr.cf_dacls);
1450         return rc;
1451 }
1452 
1453 void ksmbd_init_domain(u32 *sub_auth)
1454 {
1455         int i;
1456 
1457         memcpy(&server_conf.domain_sid, &domain, sizeof(struct smb_sid));
1458         for (i = 0; i < 3; ++i)
1459                 server_conf.domain_sid.sub_auth[i + 1] = cpu_to_le32(sub_auth[i]);
1460 }
1461 

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

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

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

sflogo.php