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 */
compare_sids(const struct smb_sid * ctsid,const struct smb_sid * cwsid)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
smb_copy_sid(struct smb_sid * dst,const struct smb_sid * src)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 */
access_flags_to_mode(struct smb_fattr * fattr,__le32 ace_flags,int type)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 */
mode_to_access_flags(umode_t mode,umode_t bits_to_use,__u32 * pace_flags)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
fill_ace_for_sid(struct smb_ace * pntace,const struct smb_sid * psid,int type,int flags,umode_t mode,umode_t bits)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
id_to_sid(unsigned int cid,uint sidtype,struct smb_sid * ssid)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
sid_to_id(struct mnt_idmap * idmap,struct smb_sid * psid,uint sidtype,struct smb_fattr * fattr)257 static int sid_to_id(struct mnt_idmap *idmap,
258 struct smb_sid *psid, uint sidtype,
259 struct smb_fattr *fattr)
260 {
261 const struct smb_sid *sid_prefix;
262 int rc = -EINVAL;
263
264 /*
265 * If we have too many subauthorities, then something is really wrong.
266 * Just return an error.
267 */
268 if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
269 pr_err("%s: %u subauthorities is too many!\n",
270 __func__, psid->num_subauth);
271 return -EIO;
272 }
273
274 if (psid->num_subauth == 0) {
275 pr_err("%s: zero subauthorities!\n", __func__);
276 return -EIO;
277 }
278
279 if (sidtype == SIDOWNER) {
280 kuid_t uid;
281 uid_t id;
282
283 /* Only the server domain RID has a local uid representation. */
284 sid_prefix = &server_conf.domain_sid;
285 if (psid->num_subauth != sid_prefix->num_subauth + 1 ||
286 compare_sids(psid, sid_prefix))
287 return -EINVAL;
288
289 id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
290 uid = KUIDT_INIT(id);
291 uid = from_vfsuid(idmap, &init_user_ns, VFSUIDT_INIT(uid));
292 if (uid_valid(uid)) {
293 fattr->cf_uid = uid;
294 rc = 0;
295 }
296 } else {
297 kgid_t gid;
298 gid_t id;
299
300 /* Local gids are represented by S-1-22-2-<gid>. */
301 sid_prefix = &sid_unix_groups;
302 if (psid->num_subauth != sid_prefix->num_subauth + 1 ||
303 compare_sids(psid, sid_prefix))
304 return -EINVAL;
305
306 id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
307 gid = KGIDT_INIT(id);
308 gid = from_vfsgid(idmap, &init_user_ns, VFSGIDT_INIT(gid));
309 if (gid_valid(gid)) {
310 fattr->cf_gid = gid;
311 rc = 0;
312 }
313 }
314
315 return rc;
316 }
317
posix_state_to_acl(struct posix_acl_state * state,struct posix_acl_entry * pace)318 void posix_state_to_acl(struct posix_acl_state *state,
319 struct posix_acl_entry *pace)
320 {
321 int i;
322
323 pace->e_tag = ACL_USER_OBJ;
324 pace->e_perm = state->owner.allow;
325 for (i = 0; i < state->users->n; i++) {
326 pace++;
327 pace->e_tag = ACL_USER;
328 pace->e_uid = state->users->aces[i].uid;
329 pace->e_perm = state->users->aces[i].perms.allow;
330 }
331
332 pace++;
333 pace->e_tag = ACL_GROUP_OBJ;
334 pace->e_perm = state->group.allow;
335
336 for (i = 0; i < state->groups->n; i++) {
337 pace++;
338 pace->e_tag = ACL_GROUP;
339 pace->e_gid = state->groups->aces[i].gid;
340 pace->e_perm = state->groups->aces[i].perms.allow;
341 }
342
343 if (state->users->n || state->groups->n) {
344 pace++;
345 pace->e_tag = ACL_MASK;
346 pace->e_perm = state->mask.allow;
347 }
348
349 pace++;
350 pace->e_tag = ACL_OTHER;
351 pace->e_perm = state->other.allow;
352 }
353
init_acl_state(struct posix_acl_state * state,u16 cnt)354 int init_acl_state(struct posix_acl_state *state, u16 cnt)
355 {
356 int alloc;
357
358 memset(state, 0, sizeof(struct posix_acl_state));
359 /*
360 * In the worst case, each individual acl could be for a distinct
361 * named user or group, but we don't know which, so we allocate
362 * enough space for either:
363 */
364 alloc = sizeof(struct posix_ace_state_array)
365 + cnt * sizeof(struct posix_user_ace_state);
366 state->users = kzalloc(alloc, KSMBD_DEFAULT_GFP);
367 if (!state->users)
368 return -ENOMEM;
369 state->groups = kzalloc(alloc, KSMBD_DEFAULT_GFP);
370 if (!state->groups) {
371 kfree(state->users);
372 return -ENOMEM;
373 }
374 return 0;
375 }
376
free_acl_state(struct posix_acl_state * state)377 void free_acl_state(struct posix_acl_state *state)
378 {
379 kfree(state->users);
380 kfree(state->groups);
381 }
382
parse_dacl(struct mnt_idmap * idmap,struct smb_acl * pdacl,char * end_of_acl,struct smb_sid * pownersid,struct smb_sid * pgrpsid,struct smb_fattr * fattr)383 static void parse_dacl(struct mnt_idmap *idmap,
384 struct smb_acl *pdacl, char *end_of_acl,
385 struct smb_sid *pownersid, struct smb_sid *pgrpsid,
386 struct smb_fattr *fattr)
387 {
388 int i, ret;
389 u16 num_aces = 0;
390 u16 dacl_size;
391 unsigned int acl_size;
392 char *acl_base;
393 struct smb_ace **ppace;
394 struct posix_acl_entry *cf_pace, *cf_pdace;
395 struct posix_acl_state acl_state, default_acl_state;
396 umode_t mode = 0, acl_mode;
397 bool owner_found = false, group_found = false, others_found = false;
398
399 if (!pdacl)
400 return;
401
402 /* validate that we do not go past end of acl */
403 if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl) ||
404 end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
405 pr_err("ACL too small to parse DACL\n");
406 return;
407 }
408
409 ksmbd_debug(SMB, "DACL revision %d size %d num aces %d\n",
410 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
411 le16_to_cpu(pdacl->num_aces));
412
413 acl_base = (char *)pdacl;
414 acl_size = sizeof(struct smb_acl);
415
416 num_aces = le16_to_cpu(pdacl->num_aces);
417 if (num_aces <= 0)
418 return;
419
420 dacl_size = le16_to_cpu(pdacl->size);
421 if (dacl_size < sizeof(struct smb_acl))
422 return;
423
424 if (num_aces > (dacl_size - sizeof(struct smb_acl)) /
425 (offsetof(struct smb_ace, sid) +
426 offsetof(struct smb_sid, sub_auth) + sizeof(__le16)))
427 return;
428
429 ret = init_acl_state(&acl_state, num_aces);
430 if (ret)
431 return;
432 ret = init_acl_state(&default_acl_state, num_aces);
433 if (ret) {
434 free_acl_state(&acl_state);
435 return;
436 }
437
438 ppace = kmalloc_objs(struct smb_ace *, num_aces, KSMBD_DEFAULT_GFP);
439 if (!ppace) {
440 free_acl_state(&default_acl_state);
441 free_acl_state(&acl_state);
442 return;
443 }
444
445 /*
446 * reset rwx permissions for user/group/other.
447 * Also, if num_aces is 0 i.e. DACL has no ACEs,
448 * user/group/other have no permissions
449 */
450 for (i = 0; i < num_aces; ++i) {
451 if (end_of_acl - acl_base < acl_size)
452 break;
453
454 ppace[i] = (struct smb_ace *)(acl_base + acl_size);
455 acl_base = (char *)ppace[i];
456 acl_size = offsetof(struct smb_ace, sid) +
457 offsetof(struct smb_sid, sub_auth);
458
459 if (end_of_acl - acl_base < acl_size ||
460 ppace[i]->sid.num_subauth == 0 ||
461 ppace[i]->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
462 (end_of_acl - acl_base <
463 acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) ||
464 (le16_to_cpu(ppace[i]->size) <
465 acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth))
466 break;
467
468 acl_size = le16_to_cpu(ppace[i]->size);
469 ppace[i]->access_req =
470 smb_map_generic_desired_access(ppace[i]->access_req);
471
472 if (ppace[i]->sid.num_subauth >= 3 &&
473 !(compare_sids(&ppace[i]->sid, &sid_unix_NFS_mode))) {
474 fattr->cf_mode =
475 le32_to_cpu(ppace[i]->sid.sub_auth[2]);
476 break;
477 } else if (!compare_sids(&ppace[i]->sid, pownersid)) {
478 acl_mode = access_flags_to_mode(fattr,
479 ppace[i]->access_req,
480 ppace[i]->type);
481 acl_mode &= 0700;
482
483 if (!owner_found) {
484 mode &= ~(0700);
485 mode |= acl_mode;
486 }
487 owner_found = true;
488 } else if (!compare_sids(&ppace[i]->sid, pgrpsid) ||
489 ppace[i]->sid.sub_auth[ppace[i]->sid.num_subauth - 1] ==
490 DOMAIN_USER_RID_LE) {
491 acl_mode = access_flags_to_mode(fattr,
492 ppace[i]->access_req,
493 ppace[i]->type);
494 acl_mode &= 0070;
495 if (!group_found) {
496 mode &= ~(0070);
497 mode |= acl_mode;
498 }
499 group_found = true;
500 } else if (!compare_sids(&ppace[i]->sid, &sid_everyone)) {
501 acl_mode = access_flags_to_mode(fattr,
502 ppace[i]->access_req,
503 ppace[i]->type);
504 acl_mode &= 0007;
505 if (!others_found) {
506 mode &= ~(0007);
507 mode |= acl_mode;
508 }
509 others_found = true;
510 } else if (!compare_sids(&ppace[i]->sid, &creator_owner)) {
511 continue;
512 } else if (!compare_sids(&ppace[i]->sid, &creator_group)) {
513 continue;
514 } else if (!compare_sids(&ppace[i]->sid, &sid_authusers)) {
515 continue;
516 } else {
517 struct smb_fattr temp_fattr;
518
519 acl_mode = access_flags_to_mode(fattr, ppace[i]->access_req,
520 ppace[i]->type);
521 temp_fattr.cf_uid = INVALID_UID;
522 ret = sid_to_id(idmap, &ppace[i]->sid, SIDOWNER, &temp_fattr);
523 if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) {
524 pr_err("%s: Error %d mapping Owner SID to uid\n",
525 __func__, ret);
526 continue;
527 }
528
529 acl_state.owner.allow = ((acl_mode & 0700) >> 6) | 0004;
530 acl_state.users->aces[acl_state.users->n].uid =
531 temp_fattr.cf_uid;
532 acl_state.users->aces[acl_state.users->n++].perms.allow =
533 ((acl_mode & 0700) >> 6) | 0004;
534 default_acl_state.owner.allow = ((acl_mode & 0700) >> 6) | 0004;
535 default_acl_state.users->aces[default_acl_state.users->n].uid =
536 temp_fattr.cf_uid;
537 default_acl_state.users->aces[default_acl_state.users->n++].perms.allow =
538 ((acl_mode & 0700) >> 6) | 0004;
539 }
540 }
541 kfree(ppace);
542
543 if (owner_found) {
544 /* The owner must be set to at least read-only. */
545 acl_state.owner.allow = ((mode & 0700) >> 6) | 0004;
546 acl_state.users->aces[acl_state.users->n].uid = fattr->cf_uid;
547 acl_state.users->aces[acl_state.users->n++].perms.allow =
548 ((mode & 0700) >> 6) | 0004;
549 default_acl_state.owner.allow = ((mode & 0700) >> 6) | 0004;
550 default_acl_state.users->aces[default_acl_state.users->n].uid =
551 fattr->cf_uid;
552 default_acl_state.users->aces[default_acl_state.users->n++].perms.allow =
553 ((mode & 0700) >> 6) | 0004;
554 }
555
556 if (group_found) {
557 acl_state.group.allow = (mode & 0070) >> 3;
558 acl_state.groups->aces[acl_state.groups->n].gid =
559 fattr->cf_gid;
560 acl_state.groups->aces[acl_state.groups->n++].perms.allow =
561 (mode & 0070) >> 3;
562 default_acl_state.group.allow = (mode & 0070) >> 3;
563 default_acl_state.groups->aces[default_acl_state.groups->n].gid =
564 fattr->cf_gid;
565 default_acl_state.groups->aces[default_acl_state.groups->n++].perms.allow =
566 (mode & 0070) >> 3;
567 }
568
569 if (others_found) {
570 fattr->cf_mode &= ~(0007);
571 fattr->cf_mode |= mode & 0007;
572
573 acl_state.other.allow = mode & 0007;
574 default_acl_state.other.allow = mode & 0007;
575 }
576
577 if (acl_state.users->n || acl_state.groups->n) {
578 acl_state.mask.allow = 0x07;
579
580 if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
581 fattr->cf_acls =
582 posix_acl_alloc(acl_state.users->n +
583 acl_state.groups->n + 4, KSMBD_DEFAULT_GFP);
584 if (fattr->cf_acls) {
585 cf_pace = fattr->cf_acls->a_entries;
586 posix_state_to_acl(&acl_state, cf_pace);
587 }
588 }
589 }
590
591 if (default_acl_state.users->n || default_acl_state.groups->n) {
592 default_acl_state.mask.allow = 0x07;
593
594 if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
595 fattr->cf_dacls =
596 posix_acl_alloc(default_acl_state.users->n +
597 default_acl_state.groups->n + 4, KSMBD_DEFAULT_GFP);
598 if (fattr->cf_dacls) {
599 cf_pdace = fattr->cf_dacls->a_entries;
600 posix_state_to_acl(&default_acl_state, cf_pdace);
601 }
602 }
603 }
604 free_acl_state(&acl_state);
605 free_acl_state(&default_acl_state);
606 }
607
set_posix_acl_entries_dacl(struct mnt_idmap * idmap,struct smb_ace * pndace,struct smb_fattr * fattr,u16 * num_aces,u16 * size,u16 existing_nt_aces,bool had_nt_aces)608 static void set_posix_acl_entries_dacl(struct mnt_idmap *idmap,
609 struct smb_ace *pndace,
610 struct smb_fattr *fattr, u16 *num_aces,
611 u16 *size, u16 existing_nt_aces,
612 bool had_nt_aces)
613 {
614 struct posix_acl_entry *pace;
615 struct smb_sid *sid;
616 struct smb_ace *ntace;
617 int i, j;
618 u16 ace_sz;
619
620 if (!fattr->cf_acls)
621 goto posix_default_acl;
622
623 pace = fattr->cf_acls->a_entries;
624 for (i = 0; i < fattr->cf_acls->a_count; i++, pace++) {
625 int flags = 0;
626
627 sid = kmalloc_obj(struct smb_sid, KSMBD_DEFAULT_GFP);
628 if (!sid)
629 break;
630
631 if (pace->e_tag == ACL_USER) {
632 uid_t uid;
633 unsigned int sid_type = SIDOWNER;
634
635 uid = posix_acl_uid_translate(idmap, pace);
636 if (!uid)
637 sid_type = SIDUNIX_USER;
638 id_to_sid(uid, sid_type, sid);
639 } else if (pace->e_tag == ACL_GROUP) {
640 gid_t gid;
641
642 gid = posix_acl_gid_translate(idmap, pace);
643 id_to_sid(gid, SIDUNIX_GROUP, sid);
644 } else if (pace->e_tag == ACL_OTHER && !had_nt_aces) {
645 smb_copy_sid(sid, &sid_everyone);
646 } else {
647 kfree(sid);
648 continue;
649 }
650 ntace = pndace;
651 for (j = 0; j < existing_nt_aces; j++) {
652 if (ntace->sid.sub_auth[ntace->sid.num_subauth - 1] ==
653 sid->sub_auth[sid->num_subauth - 1])
654 goto pass_same_sid;
655 ntace = (struct smb_ace *)((char *)ntace +
656 le16_to_cpu(ntace->size));
657 }
658
659 if (S_ISDIR(fattr->cf_mode) && pace->e_tag == ACL_OTHER)
660 flags = 0x03;
661
662 ntace = (struct smb_ace *)((char *)pndace + *size);
663 ace_sz = fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, flags,
664 pace->e_perm, 0777);
665 if (check_add_overflow(*size, ace_sz, size)) {
666 *size -= ace_sz;
667 kfree(sid);
668 break;
669 }
670 (*num_aces)++;
671 if (pace->e_tag == ACL_USER)
672 ntace->access_req |=
673 FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
674
675 if (S_ISDIR(fattr->cf_mode) &&
676 (pace->e_tag == ACL_USER || pace->e_tag == ACL_GROUP)) {
677 ntace = (struct smb_ace *)((char *)pndace + *size);
678 ace_sz = fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED,
679 0x03, pace->e_perm, 0777);
680 if (check_add_overflow(*size, ace_sz, size)) {
681 *size -= ace_sz;
682 kfree(sid);
683 break;
684 }
685 (*num_aces)++;
686 if (pace->e_tag == ACL_USER)
687 ntace->access_req |=
688 FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
689 }
690
691 pass_same_sid:
692 kfree(sid);
693 }
694
695 if (had_nt_aces)
696 return;
697
698 posix_default_acl:
699 if (!fattr->cf_dacls)
700 return;
701
702 pace = fattr->cf_dacls->a_entries;
703 for (i = 0; i < fattr->cf_dacls->a_count; i++, pace++) {
704 sid = kmalloc_obj(struct smb_sid, KSMBD_DEFAULT_GFP);
705 if (!sid)
706 break;
707
708 if (pace->e_tag == ACL_USER) {
709 uid_t uid;
710
711 uid = posix_acl_uid_translate(idmap, pace);
712 id_to_sid(uid, SIDCREATOR_OWNER, sid);
713 } else if (pace->e_tag == ACL_GROUP) {
714 gid_t gid;
715
716 gid = posix_acl_gid_translate(idmap, pace);
717 id_to_sid(gid, SIDCREATOR_GROUP, sid);
718 } else {
719 kfree(sid);
720 continue;
721 }
722
723 ntace = (struct smb_ace *)((char *)pndace + *size);
724 ace_sz = fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, 0x0b,
725 pace->e_perm, 0777);
726 if (check_add_overflow(*size, ace_sz, size)) {
727 *size -= ace_sz;
728 kfree(sid);
729 break;
730 }
731 (*num_aces)++;
732 if (pace->e_tag == ACL_USER)
733 ntace->access_req |=
734 FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
735 kfree(sid);
736 }
737 }
738
set_ntacl_dacl(struct mnt_idmap * idmap,struct smb_acl * pndacl,struct smb_acl * nt_dacl,unsigned int aces_size,const struct smb_sid * pownersid,const struct smb_sid * pgrpsid,struct smb_fattr * fattr)739 static void set_ntacl_dacl(struct mnt_idmap *idmap,
740 struct smb_acl *pndacl,
741 struct smb_acl *nt_dacl,
742 unsigned int aces_size,
743 const struct smb_sid *pownersid,
744 const struct smb_sid *pgrpsid,
745 struct smb_fattr *fattr)
746 {
747 struct smb_ace *ntace, *pndace;
748 u16 nt_num_aces = le16_to_cpu(nt_dacl->num_aces), num_aces = 0;
749 u16 copied_nt_aces;
750 unsigned short size = 0;
751 int i;
752
753 pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
754 if (nt_num_aces) {
755 ntace = (struct smb_ace *)((char *)nt_dacl + sizeof(struct smb_acl));
756 for (i = 0; i < nt_num_aces; i++) {
757 unsigned short nt_ace_size;
758
759 if (aces_size < offsetof(struct smb_ace, sid) +
760 CIFS_SID_BASE_SIZE)
761 break;
762
763 nt_ace_size = le16_to_cpu(ntace->size);
764 if (nt_ace_size > aces_size ||
765 nt_ace_size < offsetof(struct smb_ace, sid) +
766 CIFS_SID_BASE_SIZE)
767 break;
768
769 if (ntace->sid.num_subauth == 0 ||
770 ntace->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
771 nt_ace_size < offsetof(struct smb_ace, sid) +
772 CIFS_SID_BASE_SIZE +
773 sizeof(__le32) *
774 ntace->sid.num_subauth)
775 goto next_ace;
776
777 memcpy((char *)pndace + size, ntace, nt_ace_size);
778 if (check_add_overflow(size, nt_ace_size, &size)) {
779 size -= nt_ace_size;
780 break;
781 }
782 num_aces++;
783
784 next_ace:
785 aces_size -= nt_ace_size;
786 ntace = (struct smb_ace *)((char *)ntace + nt_ace_size);
787 }
788 }
789
790 copied_nt_aces = num_aces;
791 set_posix_acl_entries_dacl(idmap, pndace, fattr,
792 &num_aces, &size, copied_nt_aces,
793 nt_num_aces != 0);
794 pndacl->num_aces = cpu_to_le16(num_aces);
795 pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
796 }
797
set_mode_dacl(struct mnt_idmap * idmap,struct smb_acl * pndacl,struct smb_fattr * fattr)798 static void set_mode_dacl(struct mnt_idmap *idmap,
799 struct smb_acl *pndacl, struct smb_fattr *fattr)
800 {
801 struct smb_ace *pace, *pndace;
802 u16 num_aces = 0;
803 u16 size = 0, ace_size = 0;
804 uid_t uid;
805 const struct smb_sid *sid;
806
807 pace = pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
808
809 if (fattr->cf_acls) {
810 set_posix_acl_entries_dacl(idmap, pndace, fattr,
811 &num_aces, &size, num_aces, false);
812 goto out;
813 }
814
815 /* owner RID */
816 uid = from_kuid(&init_user_ns, fattr->cf_uid);
817 if (uid)
818 sid = &server_conf.domain_sid;
819 else
820 sid = &sid_unix_users;
821 ace_size = fill_ace_for_sid(pace, sid, ACCESS_ALLOWED, 0,
822 fattr->cf_mode, 0700);
823 pace->sid.sub_auth[pace->sid.num_subauth++] = cpu_to_le32(uid);
824 pace->size = cpu_to_le16(ace_size + 4);
825 size += le16_to_cpu(pace->size);
826 pace = (struct smb_ace *)((char *)pndace + size);
827
828 /* Group RID */
829 ace_size = fill_ace_for_sid(pace, &sid_unix_groups,
830 ACCESS_ALLOWED, 0, fattr->cf_mode, 0070);
831 pace->sid.sub_auth[pace->sid.num_subauth++] =
832 cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid));
833 pace->size = cpu_to_le16(ace_size + 4);
834 size += le16_to_cpu(pace->size);
835 pace = (struct smb_ace *)((char *)pndace + size);
836 num_aces = 3;
837
838 if (S_ISDIR(fattr->cf_mode)) {
839 pace = (struct smb_ace *)((char *)pndace + size);
840
841 /* creator owner */
842 size += fill_ace_for_sid(pace, &creator_owner, ACCESS_ALLOWED,
843 0x0b, fattr->cf_mode, 0700);
844 pace = (struct smb_ace *)((char *)pndace + size);
845
846 /* creator group */
847 size += fill_ace_for_sid(pace, &creator_group, ACCESS_ALLOWED,
848 0x0b, fattr->cf_mode, 0070);
849 pace = (struct smb_ace *)((char *)pndace + size);
850 num_aces = 5;
851 }
852
853 /* other */
854 size += fill_ace_for_sid(pace, &sid_everyone, ACCESS_ALLOWED, 0,
855 fattr->cf_mode, 0007);
856
857 out:
858 pndacl->num_aces = cpu_to_le16(num_aces);
859 pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
860 }
861
parse_sid(struct smb_sid * psid,char * end_of_acl)862 static int parse_sid(struct smb_sid *psid, char *end_of_acl)
863 {
864 /*
865 * validate that we do not go past end of ACL - sid must be at least 8
866 * bytes long (assuming no sub-auths - e.g. the null SID
867 */
868 if (end_of_acl < (char *)psid + 8) {
869 pr_err("ACL too small to parse SID %p\n", psid);
870 return -EINVAL;
871 }
872
873 if (!psid->num_subauth)
874 return 0;
875
876 if (psid->num_subauth > SID_MAX_SUB_AUTHORITIES ||
877 end_of_acl < (char *)psid + 8 + sizeof(__le32) * psid->num_subauth)
878 return -EINVAL;
879
880 return 0;
881 }
882
883 /* Convert CIFS ACL to POSIX form */
parse_sec_desc(struct mnt_idmap * idmap,struct smb_ntsd * pntsd,int acl_len,struct smb_fattr * fattr)884 int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
885 int acl_len, struct smb_fattr *fattr)
886 {
887 int rc = 0;
888 struct smb_sid *owner_sid_ptr, *group_sid_ptr;
889 struct smb_acl *dacl_ptr; /* no need for SACL ptr */
890 char *end_of_acl = ((char *)pntsd) + acl_len;
891 __u32 dacloffset;
892 int pntsd_type;
893
894 if (!pntsd)
895 return -EIO;
896
897 if (acl_len < sizeof(struct smb_ntsd))
898 return -EINVAL;
899
900 owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
901 le32_to_cpu(pntsd->osidoffset));
902 group_sid_ptr = (struct smb_sid *)((char *)pntsd +
903 le32_to_cpu(pntsd->gsidoffset));
904 dacloffset = le32_to_cpu(pntsd->dacloffset);
905 dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
906 ksmbd_debug(SMB,
907 "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
908 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
909 le32_to_cpu(pntsd->gsidoffset),
910 le32_to_cpu(pntsd->sacloffset), dacloffset);
911
912 pntsd_type = le16_to_cpu(pntsd->type);
913 if (!(pntsd_type & DACL_PRESENT)) {
914 ksmbd_debug(SMB, "DACL_PRESENT in DACL type is not set\n");
915 return rc;
916 }
917
918 pntsd->type = cpu_to_le16(DACL_PRESENT);
919
920 if (pntsd->osidoffset) {
921 if (le32_to_cpu(pntsd->osidoffset) < sizeof(struct smb_ntsd))
922 return -EINVAL;
923
924 rc = parse_sid(owner_sid_ptr, end_of_acl);
925 if (rc) {
926 pr_err("%s: Error %d parsing Owner SID\n", __func__, rc);
927 return rc;
928 }
929
930 rc = sid_to_id(idmap, owner_sid_ptr, SIDOWNER, fattr);
931 if (rc) {
932 ksmbd_debug(SMB, "Owner SID has no Unix uid mapping\n");
933 owner_sid_ptr = NULL;
934 rc = 0;
935 }
936 }
937
938 if (pntsd->gsidoffset) {
939 if (le32_to_cpu(pntsd->gsidoffset) < sizeof(struct smb_ntsd))
940 return -EINVAL;
941
942 rc = parse_sid(group_sid_ptr, end_of_acl);
943 if (rc) {
944 pr_err("%s: Error %d mapping Owner SID to gid\n",
945 __func__, rc);
946 return rc;
947 }
948 rc = sid_to_id(idmap, group_sid_ptr, SIDUNIX_GROUP, fattr);
949 if (rc) {
950 ksmbd_debug(SMB, "Group SID has no Unix gid mapping\n");
951 group_sid_ptr = NULL;
952 rc = 0;
953 }
954 }
955
956 if ((pntsd_type & (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ)) ==
957 (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ))
958 pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
959 if (pntsd_type & DACL_PROTECTED)
960 pntsd->type |= cpu_to_le16(DACL_PROTECTED);
961
962 if (dacloffset) {
963 if (dacloffset < sizeof(struct smb_ntsd))
964 return -EINVAL;
965
966 parse_dacl(idmap, dacl_ptr, end_of_acl,
967 owner_sid_ptr, group_sid_ptr, fattr);
968 }
969
970 return 0;
971 }
972
smb_acl_sec_desc_scratch_len(struct smb_fattr * fattr,struct smb_ntsd * ppntsd,int ppntsd_size,int addition_info)973 size_t smb_acl_sec_desc_scratch_len(struct smb_fattr *fattr,
974 struct smb_ntsd *ppntsd, int ppntsd_size, int addition_info)
975 {
976 size_t len = sizeof(struct smb_ntsd);
977 size_t tmp;
978
979 if (addition_info & OWNER_SECINFO)
980 len += sizeof(struct smb_sid);
981 if (addition_info & GROUP_SECINFO)
982 len += sizeof(struct smb_sid);
983 if (!(addition_info & DACL_SECINFO))
984 return len;
985
986 len += sizeof(struct smb_acl);
987 if (ppntsd && ppntsd_size > 0) {
988 unsigned int dacl_offset = le32_to_cpu(ppntsd->dacloffset);
989
990 if (dacl_offset < ppntsd_size &&
991 check_add_overflow(len, ppntsd_size - dacl_offset, &len))
992 return 0;
993 }
994
995 if (fattr->cf_acls) {
996 if (check_mul_overflow((size_t)fattr->cf_acls->a_count,
997 2 * sizeof(struct smb_ace), &tmp) ||
998 check_add_overflow(len, tmp, &len))
999 return 0;
1000 } else {
1001 /* default/minimum DACL */
1002 if (check_add_overflow(len, 5 * sizeof(struct smb_ace), &len))
1003 return 0;
1004 }
1005
1006 if (fattr->cf_dacls) {
1007 if (check_mul_overflow((size_t)fattr->cf_dacls->a_count,
1008 sizeof(struct smb_ace), &tmp) ||
1009 check_add_overflow(len, tmp, &len))
1010 return 0;
1011 }
1012
1013 return len;
1014 }
1015
1016 /* Convert permission bits from mode to equivalent CIFS ACL */
build_sec_desc(struct mnt_idmap * idmap,struct smb_ntsd * pntsd,struct smb_ntsd * ppntsd,int ppntsd_size,int addition_info,__u32 * secdesclen,struct smb_fattr * fattr)1017 int build_sec_desc(struct mnt_idmap *idmap,
1018 struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
1019 int ppntsd_size, int addition_info, __u32 *secdesclen,
1020 struct smb_fattr *fattr)
1021 {
1022 int rc = 0;
1023 __u32 offset;
1024 struct smb_sid *owner_sid_ptr, *group_sid_ptr;
1025 struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr;
1026 struct smb_acl *dacl_ptr = NULL; /* no need for SACL ptr */
1027 uid_t uid;
1028 gid_t gid;
1029 unsigned int sid_type = SIDOWNER;
1030
1031 nowner_sid_ptr = kmalloc_obj(struct smb_sid, KSMBD_DEFAULT_GFP);
1032 if (!nowner_sid_ptr)
1033 return -ENOMEM;
1034
1035 uid = from_kuid(&init_user_ns, fattr->cf_uid);
1036 if (!uid)
1037 sid_type = SIDUNIX_USER;
1038 id_to_sid(uid, sid_type, nowner_sid_ptr);
1039
1040 ngroup_sid_ptr = kmalloc_obj(struct smb_sid, KSMBD_DEFAULT_GFP);
1041 if (!ngroup_sid_ptr) {
1042 kfree(nowner_sid_ptr);
1043 return -ENOMEM;
1044 }
1045
1046 gid = from_kgid(&init_user_ns, fattr->cf_gid);
1047 id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr);
1048
1049 offset = sizeof(struct smb_ntsd);
1050 pntsd->sacloffset = 0;
1051 pntsd->revision = cpu_to_le16(1);
1052 pntsd->type = cpu_to_le16(SELF_RELATIVE);
1053 if (ppntsd)
1054 pntsd->type |= ppntsd->type;
1055
1056 if (addition_info & OWNER_SECINFO) {
1057 pntsd->osidoffset = cpu_to_le32(offset);
1058 owner_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
1059 smb_copy_sid(owner_sid_ptr, nowner_sid_ptr);
1060 offset += 1 + 1 + 6 + (nowner_sid_ptr->num_subauth * 4);
1061 }
1062
1063 if (addition_info & GROUP_SECINFO) {
1064 pntsd->gsidoffset = cpu_to_le32(offset);
1065 group_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
1066 smb_copy_sid(group_sid_ptr, ngroup_sid_ptr);
1067 offset += 1 + 1 + 6 + (ngroup_sid_ptr->num_subauth * 4);
1068 }
1069
1070 if (addition_info & DACL_SECINFO) {
1071 pntsd->type |= cpu_to_le16(DACL_PRESENT);
1072 dacl_ptr = (struct smb_acl *)((char *)pntsd + offset);
1073 dacl_ptr->revision = cpu_to_le16(2);
1074 dacl_ptr->size = cpu_to_le16(sizeof(struct smb_acl));
1075 dacl_ptr->num_aces = 0;
1076
1077 if (!ppntsd) {
1078 set_mode_dacl(idmap, dacl_ptr, fattr);
1079 } else {
1080 struct smb_acl *ppdacl_ptr;
1081 unsigned int dacl_offset = le32_to_cpu(ppntsd->dacloffset);
1082 int ppdacl_size, ntacl_size = ppntsd_size - dacl_offset;
1083
1084 if (!dacl_offset ||
1085 (dacl_offset + sizeof(struct smb_acl) > ppntsd_size))
1086 goto out;
1087
1088 ppdacl_ptr = (struct smb_acl *)((char *)ppntsd + dacl_offset);
1089 ppdacl_size = le16_to_cpu(ppdacl_ptr->size);
1090 if (ppdacl_size > ntacl_size ||
1091 ppdacl_size < sizeof(struct smb_acl))
1092 goto out;
1093
1094 set_ntacl_dacl(idmap, dacl_ptr, ppdacl_ptr,
1095 ntacl_size - sizeof(struct smb_acl),
1096 nowner_sid_ptr, ngroup_sid_ptr,
1097 fattr);
1098 }
1099 pntsd->dacloffset = cpu_to_le32(offset);
1100 offset += le16_to_cpu(dacl_ptr->size);
1101 }
1102
1103 out:
1104 kfree(nowner_sid_ptr);
1105 kfree(ngroup_sid_ptr);
1106 *secdesclen = offset;
1107 return rc;
1108 }
1109
smb_set_ace(struct smb_ace * ace,const struct smb_sid * sid,u8 type,u8 flags,__le32 access_req)1110 static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type,
1111 u8 flags, __le32 access_req)
1112 {
1113 ace->type = type;
1114 ace->flags = flags;
1115 ace->access_req = access_req;
1116 smb_copy_sid(&ace->sid, sid);
1117 ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 +
1118 (ace->sid.num_subauth * 4));
1119 }
1120
smb_append_inherited_ace(struct smb_ace ** ace,int * nt_size,u16 * ace_cnt,const struct smb_sid * sid,u8 type,u8 flags,__le32 access_req)1121 static int smb_append_inherited_ace(struct smb_ace **ace, int *nt_size,
1122 u16 *ace_cnt, const struct smb_sid *sid,
1123 u8 type, u8 flags, __le32 access_req)
1124 {
1125 int ace_size;
1126
1127 smb_set_ace(*ace, sid, type, flags, access_req);
1128 ace_size = le16_to_cpu((*ace)->size);
1129 /* pdacl->size is __le16 and includes struct smb_acl. */
1130 if (check_add_overflow(*nt_size, ace_size, nt_size) ||
1131 *nt_size > U16_MAX - (int)sizeof(struct smb_acl))
1132 return -EINVAL;
1133
1134 (*ace_cnt)++;
1135 *ace = (struct smb_ace *)((char *)*ace + ace_size);
1136 return 0;
1137 }
1138
smb_validate_ntsd_sid(struct smb_ntsd * pntsd,size_t pntsd_size,unsigned int sid_offset,struct smb_sid ** sid,size_t * sid_size)1139 static int smb_validate_ntsd_sid(struct smb_ntsd *pntsd, size_t pntsd_size,
1140 unsigned int sid_offset, struct smb_sid **sid,
1141 size_t *sid_size)
1142 {
1143 size_t sid_end;
1144
1145 *sid = NULL;
1146 *sid_size = 0;
1147
1148 if (!sid_offset)
1149 return 0;
1150
1151 if (sid_offset < sizeof(struct smb_ntsd) ||
1152 check_add_overflow(sid_offset, (size_t)CIFS_SID_BASE_SIZE,
1153 &sid_end) ||
1154 sid_end > pntsd_size)
1155 return -EINVAL;
1156
1157 *sid = (struct smb_sid *)((char *)pntsd + sid_offset);
1158 if ((*sid)->num_subauth > SID_MAX_SUB_AUTHORITIES)
1159 return -EINVAL;
1160
1161 if (check_add_overflow((size_t)CIFS_SID_BASE_SIZE,
1162 sizeof(__le32) * (size_t)(*sid)->num_subauth,
1163 &sid_end))
1164 return -EINVAL;
1165
1166 if (sid_offset > pntsd_size || sid_end > pntsd_size - sid_offset)
1167 return -EINVAL;
1168
1169 *sid_size = sid_end;
1170 return 0;
1171 }
1172
smb_inherit_dacl(struct ksmbd_conn * conn,const struct path * path,unsigned int uid,unsigned int gid)1173 int smb_inherit_dacl(struct ksmbd_conn *conn,
1174 const struct path *path,
1175 unsigned int uid, unsigned int gid)
1176 {
1177 const struct smb_sid *psid, *creator = NULL;
1178 struct smb_ace *parent_aces, *aces;
1179 struct smb_acl *parent_pdacl;
1180 struct smb_ntsd *parent_pntsd = NULL;
1181 struct smb_sid owner_sid, group_sid;
1182 struct dentry *parent = path->dentry->d_parent;
1183 struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1184 int inherited_flags = 0, flags = 0, i, nt_size = 0, pdacl_size;
1185 int rc = 0, pntsd_type, ppntsd_size, acl_len, aces_size;
1186 unsigned int dacloffset;
1187 size_t dacl_struct_end;
1188 u16 num_aces, ace_cnt = 0;
1189 char *aces_base;
1190 bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
1191
1192 ppntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
1193 parent, &parent_pntsd);
1194 if (ppntsd_size <= 0)
1195 return -ENOENT;
1196
1197 dacloffset = le32_to_cpu(parent_pntsd->dacloffset);
1198 if (!dacloffset ||
1199 check_add_overflow(dacloffset, sizeof(struct smb_acl), &dacl_struct_end) ||
1200 dacl_struct_end > (size_t)ppntsd_size) {
1201 rc = -EINVAL;
1202 goto free_parent_pntsd;
1203 }
1204
1205 parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset);
1206 acl_len = ppntsd_size - dacloffset;
1207 num_aces = le16_to_cpu(parent_pdacl->num_aces);
1208 pntsd_type = le16_to_cpu(parent_pntsd->type);
1209 pdacl_size = le16_to_cpu(parent_pdacl->size);
1210
1211 if (pdacl_size > acl_len || pdacl_size < sizeof(struct smb_acl)) {
1212 rc = -EINVAL;
1213 goto free_parent_pntsd;
1214 }
1215
1216 aces_size = pdacl_size - sizeof(struct smb_acl);
1217
1218 /*
1219 * Validate num_aces against the DACL payload before allocating.
1220 * Each ACE must be at least as large as its fixed-size header
1221 * (up to the SID base), so num_aces cannot exceed the payload
1222 * divided by the minimum ACE size. This mirrors the existing
1223 * check in parse_dacl().
1224 */
1225 if (num_aces > aces_size / (offsetof(struct smb_ace, sid) +
1226 offsetof(struct smb_sid, sub_auth) +
1227 sizeof(__le16))) {
1228 rc = -EINVAL;
1229 goto free_parent_pntsd;
1230 }
1231
1232 aces_base = kmalloc_array(num_aces * 2, sizeof(struct smb_ace),
1233 KSMBD_DEFAULT_GFP);
1234 if (!aces_base) {
1235 rc = -ENOMEM;
1236 goto free_parent_pntsd;
1237 }
1238
1239 aces = (struct smb_ace *)aces_base;
1240 parent_aces = (struct smb_ace *)((char *)parent_pdacl +
1241 sizeof(struct smb_acl));
1242
1243 if (pntsd_type & DACL_AUTO_INHERITED)
1244 inherited_flags = INHERITED_ACE;
1245
1246 for (i = 0; i < num_aces; i++) {
1247 int pace_size;
1248
1249 if (aces_size < offsetof(struct smb_ace, sid) +
1250 CIFS_SID_BASE_SIZE)
1251 break;
1252
1253 pace_size = le16_to_cpu(parent_aces->size);
1254 if (pace_size > aces_size ||
1255 pace_size < offsetof(struct smb_ace, sid) +
1256 CIFS_SID_BASE_SIZE)
1257 break;
1258
1259 if (parent_aces->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
1260 pace_size < offsetof(struct smb_ace, sid) +
1261 CIFS_SID_BASE_SIZE +
1262 sizeof(__le32) * parent_aces->sid.num_subauth)
1263 break;
1264
1265 aces_size -= pace_size;
1266
1267 flags = parent_aces->flags;
1268 if (!smb_inherit_flags(flags, is_dir))
1269 goto pass;
1270 if (is_dir) {
1271 flags &= ~(INHERIT_ONLY_ACE | INHERITED_ACE);
1272 if (!(flags & CONTAINER_INHERIT_ACE))
1273 flags |= INHERIT_ONLY_ACE;
1274 if (flags & NO_PROPAGATE_INHERIT_ACE)
1275 flags = 0;
1276 } else {
1277 flags = 0;
1278 }
1279
1280 if (!compare_sids(&creator_owner, &parent_aces->sid)) {
1281 creator = &creator_owner;
1282 id_to_sid(uid, SIDOWNER, &owner_sid);
1283 psid = &owner_sid;
1284 } else if (!compare_sids(&creator_group, &parent_aces->sid)) {
1285 creator = &creator_group;
1286 id_to_sid(gid, SIDUNIX_GROUP, &group_sid);
1287 psid = &group_sid;
1288 } else {
1289 creator = NULL;
1290 psid = &parent_aces->sid;
1291 }
1292
1293 if (is_dir && creator && flags & CONTAINER_INHERIT_ACE) {
1294 rc = smb_append_inherited_ace(&aces, &nt_size, &ace_cnt,
1295 psid, parent_aces->type,
1296 inherited_flags,
1297 parent_aces->access_req);
1298 if (rc)
1299 goto free_aces_base;
1300 flags |= INHERIT_ONLY_ACE;
1301 psid = creator;
1302 } else if (is_dir && !(parent_aces->flags & NO_PROPAGATE_INHERIT_ACE)) {
1303 psid = &parent_aces->sid;
1304 }
1305
1306 rc = smb_append_inherited_ace(&aces, &nt_size, &ace_cnt, psid,
1307 parent_aces->type,
1308 flags | inherited_flags,
1309 parent_aces->access_req);
1310 if (rc)
1311 goto free_aces_base;
1312 pass:
1313 parent_aces = (struct smb_ace *)((char *)parent_aces + pace_size);
1314 }
1315
1316 if (nt_size > 0) {
1317 struct smb_ntsd *pntsd;
1318 struct smb_acl *pdacl;
1319 struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL;
1320 size_t powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
1321 size_t pntsd_alloc_size;
1322
1323 rc = smb_validate_ntsd_sid(parent_pntsd, ppntsd_size,
1324 le32_to_cpu(parent_pntsd->osidoffset),
1325 &powner_sid, &powner_sid_size);
1326 if (rc)
1327 goto free_aces_base;
1328 rc = smb_validate_ntsd_sid(parent_pntsd, ppntsd_size,
1329 le32_to_cpu(parent_pntsd->gsidoffset),
1330 &pgroup_sid, &pgroup_sid_size);
1331 if (rc)
1332 goto free_aces_base;
1333
1334 if (check_add_overflow(sizeof(struct smb_ntsd),
1335 (size_t)powner_sid_size,
1336 &pntsd_alloc_size) ||
1337 check_add_overflow(pntsd_alloc_size,
1338 (size_t)pgroup_sid_size,
1339 &pntsd_alloc_size) ||
1340 check_add_overflow(pntsd_alloc_size, sizeof(struct smb_acl),
1341 &pntsd_alloc_size) ||
1342 check_add_overflow(pntsd_alloc_size, (size_t)nt_size,
1343 &pntsd_alloc_size)) {
1344 rc = -EINVAL;
1345 goto free_aces_base;
1346 }
1347
1348 pntsd = kzalloc(pntsd_alloc_size, KSMBD_DEFAULT_GFP);
1349 if (!pntsd) {
1350 rc = -ENOMEM;
1351 goto free_aces_base;
1352 }
1353
1354 pntsd->revision = cpu_to_le16(1);
1355 pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PRESENT);
1356 if (le16_to_cpu(parent_pntsd->type) & DACL_AUTO_INHERITED)
1357 pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
1358 pntsd_size = sizeof(struct smb_ntsd);
1359 pntsd->osidoffset = parent_pntsd->osidoffset;
1360 pntsd->gsidoffset = parent_pntsd->gsidoffset;
1361 pntsd->dacloffset = parent_pntsd->dacloffset;
1362
1363 if ((u64)le32_to_cpu(pntsd->osidoffset) + powner_sid_size >
1364 pntsd_alloc_size) {
1365 rc = -EINVAL;
1366 kfree(pntsd);
1367 goto free_aces_base;
1368 }
1369
1370 if ((u64)le32_to_cpu(pntsd->gsidoffset) + pgroup_sid_size >
1371 pntsd_alloc_size) {
1372 rc = -EINVAL;
1373 kfree(pntsd);
1374 goto free_aces_base;
1375 }
1376
1377 if ((u64)le32_to_cpu(pntsd->dacloffset) + sizeof(struct smb_acl) + nt_size >
1378 pntsd_alloc_size) {
1379 rc = -EINVAL;
1380 kfree(pntsd);
1381 goto free_aces_base;
1382 }
1383
1384 if (pntsd->osidoffset) {
1385 struct smb_sid *owner_sid = (struct smb_sid *)((char *)pntsd +
1386 le32_to_cpu(pntsd->osidoffset));
1387 memcpy(owner_sid, powner_sid, powner_sid_size);
1388 pntsd_size += powner_sid_size;
1389 }
1390
1391 if (pntsd->gsidoffset) {
1392 struct smb_sid *group_sid = (struct smb_sid *)((char *)pntsd +
1393 le32_to_cpu(pntsd->gsidoffset));
1394 memcpy(group_sid, pgroup_sid, pgroup_sid_size);
1395 pntsd_size += pgroup_sid_size;
1396 }
1397
1398 if (pntsd->dacloffset) {
1399 struct smb_ace *pace;
1400
1401 pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1402 pdacl->revision = cpu_to_le16(2);
1403 pdacl->size = cpu_to_le16(sizeof(struct smb_acl) + nt_size);
1404 pdacl->num_aces = cpu_to_le16(ace_cnt);
1405 pace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1406 memcpy(pace, aces_base, nt_size);
1407 pntsd_size += sizeof(struct smb_acl) + nt_size;
1408 }
1409
1410 ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, pntsd_size, false);
1411 kfree(pntsd);
1412 }
1413
1414 free_aces_base:
1415 kfree(aces_base);
1416 free_parent_pntsd:
1417 kfree(parent_pntsd);
1418 return rc;
1419 }
1420
smb_inherit_flags(int flags,bool is_dir)1421 bool smb_inherit_flags(int flags, bool is_dir)
1422 {
1423 if (!is_dir)
1424 return (flags & OBJECT_INHERIT_ACE) != 0;
1425
1426 if (flags & OBJECT_INHERIT_ACE && !(flags & NO_PROPAGATE_INHERIT_ACE))
1427 return true;
1428
1429 if (flags & CONTAINER_INHERIT_ACE)
1430 return true;
1431 return false;
1432 }
1433
smb_check_perm_dacl(struct ksmbd_conn * conn,const struct path * path,__le32 * pdaccess,int uid)1434 int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
1435 __le32 *pdaccess, int uid)
1436 {
1437 struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1438 struct smb_ntsd *pntsd = NULL;
1439 struct smb_acl *pdacl;
1440 struct posix_acl *posix_acls;
1441 int rc = 0, pntsd_size, acl_size, aces_size, pdacl_size;
1442 unsigned int dacl_offset;
1443 size_t dacl_struct_end;
1444 struct smb_sid sid;
1445 int granted = le32_to_cpu(*pdaccess & ~FILE_MAXIMAL_ACCESS_LE);
1446 struct smb_ace *ace;
1447 int i, found = 0;
1448 unsigned int access_bits = 0;
1449 struct smb_ace *others_ace = NULL;
1450 struct posix_acl_entry *pa_entry;
1451 unsigned int sid_type = SIDOWNER;
1452 unsigned short ace_size;
1453
1454 ksmbd_debug(SMB, "check permission using windows acl\n");
1455 pntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
1456 path->dentry, &pntsd);
1457 if (pntsd_size <= 0 || !pntsd)
1458 goto err_out;
1459
1460 dacl_offset = le32_to_cpu(pntsd->dacloffset);
1461 if (!dacl_offset ||
1462 check_add_overflow(dacl_offset, sizeof(struct smb_acl), &dacl_struct_end) ||
1463 dacl_struct_end > (size_t)pntsd_size)
1464 goto err_out;
1465
1466 pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1467 acl_size = pntsd_size - dacl_offset;
1468 pdacl_size = le16_to_cpu(pdacl->size);
1469
1470 if (pdacl_size > acl_size || pdacl_size < sizeof(struct smb_acl))
1471 goto err_out;
1472
1473 if (!pdacl->num_aces) {
1474 if (!(pdacl_size - sizeof(struct smb_acl)) &&
1475 *pdaccess & ~(FILE_READ_CONTROL_LE | FILE_WRITE_DAC_LE)) {
1476 rc = -EACCES;
1477 goto err_out;
1478 }
1479 goto err_out;
1480 }
1481
1482 if (*pdaccess & FILE_MAXIMAL_ACCESS_LE) {
1483 granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1484 DELETE;
1485
1486 ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1487 aces_size = acl_size - sizeof(struct smb_acl);
1488 for (i = 0; i < le16_to_cpu(pdacl->num_aces); i++) {
1489 if (aces_size < offsetof(struct smb_ace, sid) +
1490 CIFS_SID_BASE_SIZE)
1491 break;
1492 ace_size = le16_to_cpu(ace->size);
1493 if (ace_size > aces_size ||
1494 ace_size < offsetof(struct smb_ace, sid) +
1495 CIFS_SID_BASE_SIZE)
1496 break;
1497 aces_size -= ace_size;
1498 granted |= le32_to_cpu(ace->access_req);
1499 ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1500 }
1501 }
1502
1503 if (!uid)
1504 sid_type = SIDUNIX_USER;
1505 id_to_sid(uid, sid_type, &sid);
1506
1507 ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1508 aces_size = acl_size - sizeof(struct smb_acl);
1509 for (i = 0; i < le16_to_cpu(pdacl->num_aces); i++) {
1510 if (aces_size < offsetof(struct smb_ace, sid) +
1511 CIFS_SID_BASE_SIZE)
1512 break;
1513 ace_size = le16_to_cpu(ace->size);
1514 if (ace_size > aces_size ||
1515 ace_size < offsetof(struct smb_ace, sid) +
1516 CIFS_SID_BASE_SIZE)
1517 break;
1518 aces_size -= ace_size;
1519
1520 if (ace->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
1521 ace_size < offsetof(struct smb_ace, sid) + CIFS_SID_BASE_SIZE +
1522 sizeof(__le32) * ace->sid.num_subauth)
1523 break;
1524
1525 if (!compare_sids(&sid, &ace->sid) ||
1526 !compare_sids(&sid_unix_NFS_mode, &ace->sid)) {
1527 found = 1;
1528 break;
1529 }
1530 if (!compare_sids(&sid_everyone, &ace->sid))
1531 others_ace = ace;
1532
1533 ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1534 }
1535
1536 if (*pdaccess & FILE_MAXIMAL_ACCESS_LE && found) {
1537 granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1538 DELETE;
1539
1540 granted |= le32_to_cpu(ace->access_req);
1541
1542 if (!pdacl->num_aces)
1543 granted = GENERIC_ALL_FLAGS;
1544 }
1545
1546 if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
1547 posix_acls = get_inode_acl(d_inode(path->dentry), ACL_TYPE_ACCESS);
1548 if (!IS_ERR_OR_NULL(posix_acls) && !found) {
1549 unsigned int id = -1;
1550
1551 pa_entry = posix_acls->a_entries;
1552 for (i = 0; i < posix_acls->a_count; i++, pa_entry++) {
1553 if (pa_entry->e_tag == ACL_USER)
1554 id = posix_acl_uid_translate(idmap, pa_entry);
1555 else if (pa_entry->e_tag == ACL_GROUP)
1556 id = posix_acl_gid_translate(idmap, pa_entry);
1557 else
1558 continue;
1559
1560 if (id == uid) {
1561 mode_to_access_flags(pa_entry->e_perm,
1562 0777,
1563 &access_bits);
1564 if (!access_bits)
1565 access_bits =
1566 SET_MINIMUM_RIGHTS;
1567 posix_acl_release(posix_acls);
1568 goto check_access_bits;
1569 }
1570 }
1571 }
1572 if (!IS_ERR_OR_NULL(posix_acls))
1573 posix_acl_release(posix_acls);
1574 }
1575
1576 if (!found) {
1577 if (others_ace) {
1578 ace = others_ace;
1579 } else {
1580 ksmbd_debug(SMB, "Can't find corresponding sid\n");
1581 rc = -EACCES;
1582 goto err_out;
1583 }
1584 }
1585
1586 switch (ace->type) {
1587 case ACCESS_ALLOWED_ACE_TYPE:
1588 access_bits = le32_to_cpu(ace->access_req);
1589 break;
1590 case ACCESS_DENIED_ACE_TYPE:
1591 case ACCESS_DENIED_CALLBACK_ACE_TYPE:
1592 access_bits = le32_to_cpu(~ace->access_req);
1593 break;
1594 }
1595
1596 check_access_bits:
1597 if (granted &
1598 ~(access_bits | FILE_READ_ATTRIBUTES | READ_CONTROL | WRITE_DAC | DELETE)) {
1599 ksmbd_debug(SMB, "Access denied with winACL, granted : %x, access_req : %x\n",
1600 granted, le32_to_cpu(ace->access_req));
1601 rc = -EACCES;
1602 goto err_out;
1603 }
1604
1605 *pdaccess = cpu_to_le32(granted);
1606 err_out:
1607 kfree(pntsd);
1608 return rc;
1609 }
1610
set_info_sec(struct ksmbd_conn * conn,struct ksmbd_tree_connect * tcon,const struct path * path,struct smb_ntsd * pntsd,int ntsd_len,bool type_check,bool get_write)1611 int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
1612 const struct path *path, struct smb_ntsd *pntsd, int ntsd_len,
1613 bool type_check, bool get_write)
1614 {
1615 int rc;
1616 struct smb_fattr fattr = {{0}};
1617 struct inode *inode = d_inode(path->dentry);
1618 struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1619 struct iattr newattrs;
1620
1621 fattr.cf_uid = INVALID_UID;
1622 fattr.cf_gid = INVALID_GID;
1623 fattr.cf_mode = inode->i_mode;
1624
1625 rc = parse_sec_desc(idmap, pntsd, ntsd_len, &fattr);
1626 if (rc)
1627 goto out;
1628
1629 newattrs.ia_valid = ATTR_CTIME;
1630 if (!uid_eq(fattr.cf_uid, INVALID_UID)) {
1631 newattrs.ia_valid |= ATTR_UID;
1632 newattrs.ia_uid = fattr.cf_uid;
1633 }
1634 if (!gid_eq(fattr.cf_gid, INVALID_GID)) {
1635 newattrs.ia_valid |= ATTR_GID;
1636 newattrs.ia_gid = fattr.cf_gid;
1637 }
1638 newattrs.ia_valid |= ATTR_MODE;
1639 newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
1640
1641 ksmbd_vfs_remove_acl_xattrs(idmap, path);
1642 /* Update posix acls */
1643 if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) {
1644 rc = set_posix_acl(idmap, path->dentry,
1645 ACL_TYPE_ACCESS, fattr.cf_acls);
1646 if (rc < 0)
1647 ksmbd_debug(SMB,
1648 "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
1649 rc);
1650 if (S_ISDIR(inode->i_mode) && fattr.cf_dacls) {
1651 rc = set_posix_acl(idmap, path->dentry,
1652 ACL_TYPE_DEFAULT, fattr.cf_dacls);
1653 if (rc)
1654 ksmbd_debug(SMB,
1655 "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
1656 rc);
1657 }
1658 }
1659
1660 inode_lock(inode);
1661 rc = notify_change(idmap, path->dentry, &newattrs, NULL);
1662 inode_unlock(inode);
1663 if (rc)
1664 goto out;
1665
1666 /* Check it only calling from SD BUFFER context */
1667 if (type_check && !(le16_to_cpu(pntsd->type) & DACL_PRESENT))
1668 goto out;
1669
1670 if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
1671 /* Update WinACL in xattr */
1672 ksmbd_vfs_remove_sd_xattrs(idmap, path);
1673 ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, ntsd_len,
1674 get_write);
1675 }
1676
1677 out:
1678 posix_acl_release(fattr.cf_acls);
1679 posix_acl_release(fattr.cf_dacls);
1680 return rc;
1681 }
1682
ksmbd_init_domain(u32 * sub_auth)1683 void ksmbd_init_domain(u32 *sub_auth)
1684 {
1685 int i;
1686
1687 memcpy(&server_conf.domain_sid, &domain, sizeof(struct smb_sid));
1688 for (i = 0; i < 3; ++i)
1689 server_conf.domain_sid.sub_auth[i + 1] = cpu_to_le32(sub_auth[i]);
1690 }
1691