1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <linux/fs.h>
25#include <linux/slab.h>
26#include <linux/string.h>
27#include <linux/keyctl.h>
28#include <linux/key-type.h>
29#include <keys/user-type.h>
30#include "cifspdu.h"
31#include "cifsglob.h"
32#include "cifsacl.h"
33#include "cifsproto.h"
34#include "cifs_debug.h"
35#include "fs_context.h"
36
37
38static const struct cifs_sid sid_everyone = {
39 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
40
41static const struct cifs_sid sid_authusers = {
42 1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
43
44
45static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
46 {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
47
48
49static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
50 {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
51
52
53
54
55
56
57
58
59static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
60 {cpu_to_le32(88),
61 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
62
63
64static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
65 {cpu_to_le32(88),
66 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
67
68
69static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
70 {cpu_to_le32(88),
71 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
72
73static const struct cred *root_cred;
74
75static int
76cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
77{
78 char *payload;
79
80
81
82
83
84
85
86
87
88 if (prep->datalen <= sizeof(key->payload)) {
89 key->payload.data[0] = NULL;
90 memcpy(&key->payload, prep->data, prep->datalen);
91 } else {
92 payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
93 if (!payload)
94 return -ENOMEM;
95 key->payload.data[0] = payload;
96 }
97
98 key->datalen = prep->datalen;
99 return 0;
100}
101
102static inline void
103cifs_idmap_key_destroy(struct key *key)
104{
105 if (key->datalen > sizeof(key->payload))
106 kfree(key->payload.data[0]);
107}
108
109static struct key_type cifs_idmap_key_type = {
110 .name = "cifs.idmap",
111 .instantiate = cifs_idmap_key_instantiate,
112 .destroy = cifs_idmap_key_destroy,
113 .describe = user_describe,
114};
115
116static char *
117sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
118{
119 int i, len;
120 unsigned int saval;
121 char *sidstr, *strptr;
122 unsigned long long id_auth_val;
123
124
125 sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
126 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
127 GFP_KERNEL);
128 if (!sidstr)
129 return sidstr;
130
131 strptr = sidstr;
132 len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
133 sidptr->revision);
134 strptr += len;
135
136
137 id_auth_val = (unsigned long long)sidptr->authority[5];
138 id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
139 id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
140 id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
141 id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
142 id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
143
144
145
146
147
148 if (id_auth_val <= UINT_MAX)
149 len = sprintf(strptr, "-%llu", id_auth_val);
150 else
151 len = sprintf(strptr, "-0x%llx", id_auth_val);
152
153 strptr += len;
154
155 for (i = 0; i < sidptr->num_subauth; ++i) {
156 saval = le32_to_cpu(sidptr->sub_auth[i]);
157 len = sprintf(strptr, "-%u", saval);
158 strptr += len;
159 }
160
161 return sidstr;
162}
163
164
165
166
167
168static int
169compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
170{
171 int i;
172 int num_subauth, num_sat, num_saw;
173
174 if ((!ctsid) || (!cwsid))
175 return 1;
176
177
178 if (ctsid->revision != cwsid->revision) {
179 if (ctsid->revision > cwsid->revision)
180 return 1;
181 else
182 return -1;
183 }
184
185
186 for (i = 0; i < NUM_AUTHS; ++i) {
187 if (ctsid->authority[i] != cwsid->authority[i]) {
188 if (ctsid->authority[i] > cwsid->authority[i])
189 return 1;
190 else
191 return -1;
192 }
193 }
194
195
196 num_sat = ctsid->num_subauth;
197 num_saw = cwsid->num_subauth;
198 num_subauth = num_sat < num_saw ? num_sat : num_saw;
199 if (num_subauth) {
200 for (i = 0; i < num_subauth; ++i) {
201 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
202 if (le32_to_cpu(ctsid->sub_auth[i]) >
203 le32_to_cpu(cwsid->sub_auth[i]))
204 return 1;
205 else
206 return -1;
207 }
208 }
209 }
210
211 return 0;
212}
213
214static bool
215is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
216{
217 int i;
218 int num_subauth;
219 const struct cifs_sid *pwell_known_sid;
220
221 if (!psid || (puid == NULL))
222 return false;
223
224 num_subauth = psid->num_subauth;
225
226
227 if (num_subauth == 2) {
228 if (is_group)
229 pwell_known_sid = &sid_unix_groups;
230 else
231 pwell_known_sid = &sid_unix_users;
232 } else if (num_subauth == 3) {
233 if (is_group)
234 pwell_known_sid = &sid_unix_NFS_groups;
235 else
236 pwell_known_sid = &sid_unix_NFS_users;
237 } else
238 return false;
239
240
241 if (psid->revision != pwell_known_sid->revision)
242 return false;
243
244
245 for (i = 0; i < NUM_AUTHS; ++i) {
246 if (psid->authority[i] != pwell_known_sid->authority[i]) {
247 cifs_dbg(FYI, "auth %d did not match\n", i);
248 return false;
249 }
250 }
251
252 if (num_subauth == 2) {
253 if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
254 return false;
255
256 *puid = le32_to_cpu(psid->sub_auth[1]);
257 } else {
258 *puid = le32_to_cpu(psid->sub_auth[0]);
259 if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
260 (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
261 return false;
262
263 *puid = le32_to_cpu(psid->sub_auth[2]);
264 }
265
266 cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
267 return true;
268}
269
270static __u16
271cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
272{
273 int i;
274 __u16 size = 1 + 1 + 6;
275
276 dst->revision = src->revision;
277 dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
278 for (i = 0; i < NUM_AUTHS; ++i)
279 dst->authority[i] = src->authority[i];
280 for (i = 0; i < dst->num_subauth; ++i)
281 dst->sub_auth[i] = src->sub_auth[i];
282 size += (dst->num_subauth * 4);
283
284 return size;
285}
286
287static int
288id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
289{
290 int rc;
291 struct key *sidkey;
292 struct cifs_sid *ksid;
293 unsigned int ksid_size;
294 char desc[3 + 10 + 1];
295 const struct cred *saved_cred;
296
297 rc = snprintf(desc, sizeof(desc), "%ci:%u",
298 sidtype == SIDOWNER ? 'o' : 'g', cid);
299 if (rc >= sizeof(desc))
300 return -EINVAL;
301
302 rc = 0;
303 saved_cred = override_creds(root_cred);
304 sidkey = request_key(&cifs_idmap_key_type, desc, "");
305 if (IS_ERR(sidkey)) {
306 rc = -EINVAL;
307 cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
308 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
309 goto out_revert_creds;
310 } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
311 rc = -EIO;
312 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
313 __func__, sidkey->datalen);
314 goto invalidate_key;
315 }
316
317
318
319
320
321
322 ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
323 (struct cifs_sid *)&sidkey->payload :
324 (struct cifs_sid *)sidkey->payload.data[0];
325
326 ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
327 if (ksid_size > sidkey->datalen) {
328 rc = -EIO;
329 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
330 __func__, sidkey->datalen, ksid_size);
331 goto invalidate_key;
332 }
333
334 cifs_copy_sid(ssid, ksid);
335out_key_put:
336 key_put(sidkey);
337out_revert_creds:
338 revert_creds(saved_cred);
339 return rc;
340
341invalidate_key:
342 key_invalidate(sidkey);
343 goto out_key_put;
344}
345
346int
347sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
348 struct cifs_fattr *fattr, uint sidtype)
349{
350 int rc = 0;
351 struct key *sidkey;
352 char *sidstr;
353 const struct cred *saved_cred;
354 kuid_t fuid = cifs_sb->ctx->linux_uid;
355 kgid_t fgid = cifs_sb->ctx->linux_gid;
356
357
358
359
360
361 if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
362 cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
363 __func__, psid->num_subauth);
364 return -EIO;
365 }
366
367 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
368 (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
369 uint32_t unix_id;
370 bool is_group;
371
372 if (sidtype != SIDOWNER)
373 is_group = true;
374 else
375 is_group = false;
376
377 if (is_well_known_sid(psid, &unix_id, is_group) == false)
378 goto try_upcall_to_get_id;
379
380 if (is_group) {
381 kgid_t gid;
382 gid_t id;
383
384 id = (gid_t)unix_id;
385 gid = make_kgid(&init_user_ns, id);
386 if (gid_valid(gid)) {
387 fgid = gid;
388 goto got_valid_id;
389 }
390 } else {
391 kuid_t uid;
392 uid_t id;
393
394 id = (uid_t)unix_id;
395 uid = make_kuid(&init_user_ns, id);
396 if (uid_valid(uid)) {
397 fuid = uid;
398 goto got_valid_id;
399 }
400 }
401
402 }
403
404try_upcall_to_get_id:
405 sidstr = sid_to_key_str(psid, sidtype);
406 if (!sidstr)
407 return -ENOMEM;
408
409 saved_cred = override_creds(root_cred);
410 sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
411 if (IS_ERR(sidkey)) {
412 rc = -EINVAL;
413 cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
414 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
415 goto out_revert_creds;
416 }
417
418
419
420
421
422
423 BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
424 if (sidkey->datalen != sizeof(uid_t)) {
425 rc = -EIO;
426 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
427 __func__, sidkey->datalen);
428 key_invalidate(sidkey);
429 goto out_key_put;
430 }
431
432 if (sidtype == SIDOWNER) {
433 kuid_t uid;
434 uid_t id;
435 memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
436 uid = make_kuid(&init_user_ns, id);
437 if (uid_valid(uid))
438 fuid = uid;
439 } else {
440 kgid_t gid;
441 gid_t id;
442 memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
443 gid = make_kgid(&init_user_ns, id);
444 if (gid_valid(gid))
445 fgid = gid;
446 }
447
448out_key_put:
449 key_put(sidkey);
450out_revert_creds:
451 revert_creds(saved_cred);
452 kfree(sidstr);
453
454
455
456
457
458got_valid_id:
459 rc = 0;
460 if (sidtype == SIDOWNER)
461 fattr->cf_uid = fuid;
462 else
463 fattr->cf_gid = fgid;
464 return rc;
465}
466
467int
468init_cifs_idmap(void)
469{
470 struct cred *cred;
471 struct key *keyring;
472 int ret;
473
474 cifs_dbg(FYI, "Registering the %s key type\n",
475 cifs_idmap_key_type.name);
476
477
478
479
480
481
482
483 cred = prepare_kernel_cred(NULL);
484 if (!cred)
485 return -ENOMEM;
486
487 keyring = keyring_alloc(".cifs_idmap",
488 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
489 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
490 KEY_USR_VIEW | KEY_USR_READ,
491 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
492 if (IS_ERR(keyring)) {
493 ret = PTR_ERR(keyring);
494 goto failed_put_cred;
495 }
496
497 ret = register_key_type(&cifs_idmap_key_type);
498 if (ret < 0)
499 goto failed_put_key;
500
501
502
503 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
504 cred->thread_keyring = keyring;
505 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
506 root_cred = cred;
507
508 cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
509 return 0;
510
511failed_put_key:
512 key_put(keyring);
513failed_put_cred:
514 put_cred(cred);
515 return ret;
516}
517
518void
519exit_cifs_idmap(void)
520{
521 key_revoke(root_cred->thread_keyring);
522 unregister_key_type(&cifs_idmap_key_type);
523 put_cred(root_cred);
524 cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
525}
526
527
528static __u32 copy_sec_desc(const struct cifs_ntsd *pntsd,
529 struct cifs_ntsd *pnntsd,
530 __u32 sidsoffset,
531 struct cifs_sid *pownersid,
532 struct cifs_sid *pgrpsid)
533{
534 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
535 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
536
537
538 pnntsd->revision = pntsd->revision;
539 pnntsd->type = pntsd->type;
540 pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
541 pnntsd->sacloffset = 0;
542 pnntsd->osidoffset = cpu_to_le32(sidsoffset);
543 pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
544
545
546 if (pownersid)
547 owner_sid_ptr = pownersid;
548 else
549 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
550 le32_to_cpu(pntsd->osidoffset));
551 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
552 cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
553
554
555 if (pgrpsid)
556 group_sid_ptr = pgrpsid;
557 else
558 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
559 le32_to_cpu(pntsd->gsidoffset));
560 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
561 sizeof(struct cifs_sid));
562 cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
563
564 return sidsoffset + (2 * sizeof(struct cifs_sid));
565}
566
567
568
569
570
571
572
573static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
574 umode_t *pdenied, umode_t mask)
575{
576 __u32 flags = le32_to_cpu(ace_flags);
577
578
579
580
581
582
583
584
585 if (type == ACCESS_DENIED) {
586 if (flags & GENERIC_ALL &&
587 !(*pmode & mask & 0777))
588 *pdenied |= mask & 0777;
589
590 if (((flags & GENERIC_WRITE) ||
591 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
592 !(*pmode & mask & 0222))
593 *pdenied |= mask & 0222;
594
595 if (((flags & GENERIC_READ) ||
596 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
597 !(*pmode & mask & 0444))
598 *pdenied |= mask & 0444;
599
600 if (((flags & GENERIC_EXECUTE) ||
601 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
602 !(*pmode & mask & 0111))
603 *pdenied |= mask & 0111;
604
605 return;
606 } else if (type != ACCESS_ALLOWED) {
607 cifs_dbg(VFS, "unknown access control type %d\n", type);
608 return;
609 }
610
611
612 if ((flags & GENERIC_ALL) &&
613 !(*pdenied & mask & 0777)) {
614 *pmode |= mask & 0777;
615 cifs_dbg(NOISY, "all perms\n");
616 return;
617 }
618
619 if (((flags & GENERIC_WRITE) ||
620 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
621 !(*pdenied & mask & 0222))
622 *pmode |= mask & 0222;
623
624 if (((flags & GENERIC_READ) ||
625 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
626 !(*pdenied & mask & 0444))
627 *pmode |= mask & 0444;
628
629 if (((flags & GENERIC_EXECUTE) ||
630 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
631 !(*pdenied & mask & 0111))
632 *pmode |= mask & 0111;
633
634
635 if (flags & FILE_DELETE_CHILD) {
636 if (mask == ACL_OWNER_MASK) {
637 if (!(*pdenied & 01000))
638 *pmode |= 01000;
639 } else if (!(*pdenied & 01000)) {
640 *pmode &= ~01000;
641 *pdenied |= 01000;
642 }
643 }
644
645 cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
646 return;
647}
648
649
650
651
652
653
654
655static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
656 __u32 *pace_flags)
657{
658
659 *pace_flags = 0x0;
660
661
662 mode &= bits_to_use;
663
664
665
666
667 if (mode & S_IRUGO)
668 *pace_flags |= SET_FILE_READ_RIGHTS;
669 if (mode & S_IWUGO)
670 *pace_flags |= SET_FILE_WRITE_RIGHTS;
671 if (mode & S_IXUGO)
672 *pace_flags |= SET_FILE_EXEC_RIGHTS;
673
674 cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
675 mode, *pace_flags);
676 return;
677}
678
679static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct cifs_sid *psid)
680{
681 __u16 size = 1 + 1 + 2 + 4;
682
683 dst->type = src->type;
684 dst->flags = src->flags;
685 dst->access_req = src->access_req;
686
687
688 if (psid)
689 size += cifs_copy_sid(&dst->sid, psid);
690 else
691 size += cifs_copy_sid(&dst->sid, &src->sid);
692
693 dst->size = cpu_to_le16(size);
694
695 return size;
696}
697
698static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
699 const struct cifs_sid *psid, __u64 nmode,
700 umode_t bits, __u8 access_type,
701 bool allow_delete_child)
702{
703 int i;
704 __u16 size = 0;
705 __u32 access_req = 0;
706
707 pntace->type = access_type;
708 pntace->flags = 0x0;
709 mode_to_access_flags(nmode, bits, &access_req);
710
711 if (access_type == ACCESS_ALLOWED && allow_delete_child)
712 access_req |= FILE_DELETE_CHILD;
713
714 if (access_type == ACCESS_ALLOWED && !access_req)
715 access_req = SET_MINIMUM_RIGHTS;
716 else if (access_type == ACCESS_DENIED)
717 access_req &= ~SET_MINIMUM_RIGHTS;
718
719 pntace->access_req = cpu_to_le32(access_req);
720
721 pntace->sid.revision = psid->revision;
722 pntace->sid.num_subauth = psid->num_subauth;
723 for (i = 0; i < NUM_AUTHS; i++)
724 pntace->sid.authority[i] = psid->authority[i];
725 for (i = 0; i < psid->num_subauth; i++)
726 pntace->sid.sub_auth[i] = psid->sub_auth[i];
727
728 size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
729 pntace->size = cpu_to_le16(size);
730
731 return size;
732}
733
734
735#ifdef CONFIG_CIFS_DEBUG2
736static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
737{
738 int num_subauth;
739
740
741
742 if (le16_to_cpu(pace->size) < 16) {
743 cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
744 return;
745 }
746
747 if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
748 cifs_dbg(VFS, "ACL too small to parse ACE\n");
749 return;
750 }
751
752 num_subauth = pace->sid.num_subauth;
753 if (num_subauth) {
754 int i;
755 cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
756 pace->sid.revision, pace->sid.num_subauth, pace->type,
757 pace->flags, le16_to_cpu(pace->size));
758 for (i = 0; i < num_subauth; ++i) {
759 cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
760 i, le32_to_cpu(pace->sid.sub_auth[i]));
761 }
762
763
764
765 }
766
767 return;
768}
769#endif
770
771static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
772 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
773 struct cifs_fattr *fattr, bool mode_from_special_sid)
774{
775 int i;
776 int num_aces = 0;
777 int acl_size;
778 char *acl_base;
779 struct cifs_ace **ppace;
780
781
782
783 if (!pdacl) {
784
785
786 fattr->cf_mode |= 0777;
787 return;
788 }
789
790
791 if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
792 cifs_dbg(VFS, "ACL too small to parse DACL\n");
793 return;
794 }
795
796 cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
797 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
798 le32_to_cpu(pdacl->num_aces));
799
800
801
802
803 fattr->cf_mode &= ~(0777);
804
805 acl_base = (char *)pdacl;
806 acl_size = sizeof(struct cifs_acl);
807
808 num_aces = le32_to_cpu(pdacl->num_aces);
809 if (num_aces > 0) {
810 umode_t denied_mode = 0;
811
812 if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
813 return;
814 ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
815 GFP_KERNEL);
816 if (!ppace)
817 return;
818
819 for (i = 0; i < num_aces; ++i) {
820 ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
821#ifdef CONFIG_CIFS_DEBUG2
822 dump_ace(ppace[i], end_of_acl);
823#endif
824 if (mode_from_special_sid &&
825 (compare_sids(&(ppace[i]->sid),
826 &sid_unix_NFS_mode) == 0)) {
827
828
829
830
831
832 fattr->cf_mode &= ~07777;
833 fattr->cf_mode |=
834 le32_to_cpu(ppace[i]->sid.sub_auth[2]);
835 break;
836 } else {
837 if (compare_sids(&(ppace[i]->sid), pownersid) == 0) {
838 access_flags_to_mode(ppace[i]->access_req,
839 ppace[i]->type,
840 &fattr->cf_mode,
841 &denied_mode,
842 ACL_OWNER_MASK);
843 } else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) {
844 access_flags_to_mode(ppace[i]->access_req,
845 ppace[i]->type,
846 &fattr->cf_mode,
847 &denied_mode,
848 ACL_GROUP_MASK);
849 } else if ((compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) ||
850 (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)) {
851 access_flags_to_mode(ppace[i]->access_req,
852 ppace[i]->type,
853 &fattr->cf_mode,
854 &denied_mode,
855 ACL_EVERYONE_MASK);
856 }
857 }
858
859
860
861
862
863
864 acl_base = (char *)ppace[i];
865 acl_size = le16_to_cpu(ppace[i]->size);
866 }
867
868 kfree(ppace);
869 }
870
871 return;
872}
873
874unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
875{
876 int i;
877 unsigned int ace_size = 20;
878
879 pntace->type = ACCESS_ALLOWED_ACE_TYPE;
880 pntace->flags = 0x0;
881 pntace->access_req = cpu_to_le32(GENERIC_ALL);
882 pntace->sid.num_subauth = 1;
883 pntace->sid.revision = 1;
884 for (i = 0; i < NUM_AUTHS; i++)
885 pntace->sid.authority[i] = sid_authusers.authority[i];
886
887 pntace->sid.sub_auth[0] = sid_authusers.sub_auth[0];
888
889
890 pntace->size = cpu_to_le16(ace_size);
891 return ace_size;
892}
893
894
895
896
897
898unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
899{
900 int i;
901 unsigned int ace_size = 28;
902
903 pntace->type = ACCESS_DENIED_ACE_TYPE;
904 pntace->flags = 0x0;
905 pntace->access_req = 0;
906 pntace->sid.num_subauth = 3;
907 pntace->sid.revision = 1;
908 for (i = 0; i < NUM_AUTHS; i++)
909 pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
910
911 pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
912 pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
913 pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
914
915
916 pntace->size = cpu_to_le16(ace_size);
917 return ace_size;
918}
919
920unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
921{
922 int i;
923 unsigned int ace_size = 28;
924
925 pntace->type = ACCESS_ALLOWED_ACE_TYPE;
926 pntace->flags = 0x0;
927 pntace->access_req = cpu_to_le32(GENERIC_ALL);
928 pntace->sid.num_subauth = 3;
929 pntace->sid.revision = 1;
930 for (i = 0; i < NUM_AUTHS; i++)
931 pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
932
933 pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
934 pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
935 pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
936
937
938 pntace->size = cpu_to_le16(ace_size);
939 return ace_size;
940}
941
942static void populate_new_aces(char *nacl_base,
943 struct cifs_sid *pownersid,
944 struct cifs_sid *pgrpsid,
945 __u64 *pnmode, u32 *pnum_aces, u16 *pnsize,
946 bool modefromsid)
947{
948 __u64 nmode;
949 u32 num_aces = 0;
950 u16 nsize = 0;
951 __u64 user_mode;
952 __u64 group_mode;
953 __u64 other_mode;
954 __u64 deny_user_mode = 0;
955 __u64 deny_group_mode = 0;
956 bool sticky_set = false;
957 struct cifs_ace *pnntace = NULL;
958
959 nmode = *pnmode;
960 num_aces = *pnum_aces;
961 nsize = *pnsize;
962
963 if (modefromsid) {
964 pnntace = (struct cifs_ace *) (nacl_base + nsize);
965 nsize += setup_special_mode_ACE(pnntace, nmode);
966 num_aces++;
967 goto set_size;
968 }
969
970
971
972
973
974
975
976
977 if (!memcmp(pownersid, pgrpsid, sizeof(struct cifs_sid))) {
978
979
980
981
982 user_mode = nmode & (nmode << 3) & 0700;
983 group_mode = nmode & (nmode >> 3) & 0070;
984 } else {
985 user_mode = nmode & 0700;
986 group_mode = nmode & 0070;
987 }
988
989 other_mode = nmode & 0007;
990
991
992 deny_user_mode = ~(user_mode) & ((group_mode << 3) | (other_mode << 6)) & 0700;
993 deny_group_mode = ~(group_mode) & (other_mode << 3) & 0070;
994
995 *pnmode = user_mode | group_mode | other_mode | (nmode & ~0777);
996
997
998 if (nmode & 01000)
999 sticky_set = true;
1000
1001 if (deny_user_mode) {
1002 pnntace = (struct cifs_ace *) (nacl_base + nsize);
1003 nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode,
1004 0700, ACCESS_DENIED, false);
1005 num_aces++;
1006 }
1007
1008
1009 if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) {
1010 pnntace = (struct cifs_ace *) (nacl_base + nsize);
1011 nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1012 0070, ACCESS_DENIED, false);
1013 num_aces++;
1014 }
1015
1016 pnntace = (struct cifs_ace *) (nacl_base + nsize);
1017 nsize += fill_ace_for_sid(pnntace, pownersid, user_mode,
1018 0700, ACCESS_ALLOWED, true);
1019 num_aces++;
1020
1021
1022 if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) {
1023 pnntace = (struct cifs_ace *) (nacl_base + nsize);
1024 nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1025 0070, ACCESS_DENIED, false);
1026 num_aces++;
1027 }
1028
1029 pnntace = (struct cifs_ace *) (nacl_base + nsize);
1030 nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode,
1031 0070, ACCESS_ALLOWED, !sticky_set);
1032 num_aces++;
1033
1034 pnntace = (struct cifs_ace *) (nacl_base + nsize);
1035 nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode,
1036 0007, ACCESS_ALLOWED, !sticky_set);
1037 num_aces++;
1038
1039set_size:
1040 *pnum_aces = num_aces;
1041 *pnsize = nsize;
1042}
1043
1044static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
1045 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
1046 struct cifs_sid *pnownersid, struct cifs_sid *pngrpsid)
1047{
1048 int i;
1049 u16 size = 0;
1050 struct cifs_ace *pntace = NULL;
1051 char *acl_base = NULL;
1052 u32 src_num_aces = 0;
1053 u16 nsize = 0;
1054 struct cifs_ace *pnntace = NULL;
1055 char *nacl_base = NULL;
1056 u16 ace_size = 0;
1057
1058 acl_base = (char *)pdacl;
1059 size = sizeof(struct cifs_acl);
1060 src_num_aces = le32_to_cpu(pdacl->num_aces);
1061
1062 nacl_base = (char *)pndacl;
1063 nsize = sizeof(struct cifs_acl);
1064
1065
1066 for (i = 0; i < src_num_aces; ++i) {
1067 pntace = (struct cifs_ace *) (acl_base + size);
1068 pnntace = (struct cifs_ace *) (nacl_base + nsize);
1069
1070 if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0)
1071 ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
1072 else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0)
1073 ace_size = cifs_copy_ace(pnntace, pntace, pngrpsid);
1074 else
1075 ace_size = cifs_copy_ace(pnntace, pntace, NULL);
1076
1077 size += le16_to_cpu(pntace->size);
1078 nsize += ace_size;
1079 }
1080
1081 return nsize;
1082}
1083
1084static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
1085 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
1086 __u64 *pnmode, bool mode_from_sid)
1087{
1088 int i;
1089 u16 size = 0;
1090 struct cifs_ace *pntace = NULL;
1091 char *acl_base = NULL;
1092 u32 src_num_aces = 0;
1093 u16 nsize = 0;
1094 struct cifs_ace *pnntace = NULL;
1095 char *nacl_base = NULL;
1096 u32 num_aces = 0;
1097 bool new_aces_set = false;
1098
1099
1100 nacl_base = (char *)pndacl;
1101 nsize = sizeof(struct cifs_acl);
1102
1103
1104 if (!pdacl) {
1105 populate_new_aces(nacl_base,
1106 pownersid, pgrpsid,
1107 pnmode, &num_aces, &nsize,
1108 mode_from_sid);
1109 goto finalize_dacl;
1110 }
1111
1112 acl_base = (char *)pdacl;
1113 size = sizeof(struct cifs_acl);
1114 src_num_aces = le32_to_cpu(pdacl->num_aces);
1115
1116
1117 for (i = 0; i < src_num_aces; ++i) {
1118 pntace = (struct cifs_ace *) (acl_base + size);
1119
1120 if (!new_aces_set && (pntace->flags & INHERITED_ACE)) {
1121
1122 populate_new_aces(nacl_base,
1123 pownersid, pgrpsid,
1124 pnmode, &num_aces, &nsize,
1125 mode_from_sid);
1126
1127 new_aces_set = true;
1128 }
1129
1130
1131 if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
1132 (compare_sids(&pntace->sid, pownersid) == 0) ||
1133 (compare_sids(&pntace->sid, pgrpsid) == 0) ||
1134 (compare_sids(&pntace->sid, &sid_everyone) == 0) ||
1135 (compare_sids(&pntace->sid, &sid_authusers) == 0))) {
1136 goto next_ace;
1137 }
1138
1139
1140 pnntace = (struct cifs_ace *) (nacl_base + nsize);
1141
1142 nsize += cifs_copy_ace(pnntace, pntace, NULL);
1143 num_aces++;
1144
1145next_ace:
1146 size += le16_to_cpu(pntace->size);
1147 }
1148
1149
1150 if (!new_aces_set) {
1151 populate_new_aces(nacl_base,
1152 pownersid, pgrpsid,
1153 pnmode, &num_aces, &nsize,
1154 mode_from_sid);
1155
1156 new_aces_set = true;
1157 }
1158
1159finalize_dacl:
1160 pndacl->num_aces = cpu_to_le32(num_aces);
1161 pndacl->size = cpu_to_le16(nsize);
1162
1163 return 0;
1164}
1165
1166static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
1167{
1168
1169
1170
1171
1172 if (end_of_acl < (char *)psid + 8) {
1173 cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
1174 return -EINVAL;
1175 }
1176
1177#ifdef CONFIG_CIFS_DEBUG2
1178 if (psid->num_subauth) {
1179 int i;
1180 cifs_dbg(FYI, "SID revision %d num_auth %d\n",
1181 psid->revision, psid->num_subauth);
1182
1183 for (i = 0; i < psid->num_subauth; i++) {
1184 cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
1185 i, le32_to_cpu(psid->sub_auth[i]));
1186 }
1187
1188
1189
1190 cifs_dbg(FYI, "RID 0x%x\n",
1191 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1192 }
1193#endif
1194
1195 return 0;
1196}
1197
1198
1199
1200static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1201 struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
1202 bool get_mode_from_special_sid)
1203{
1204 int rc = 0;
1205 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1206 struct cifs_acl *dacl_ptr;
1207 char *end_of_acl = ((char *)pntsd) + acl_len;
1208 __u32 dacloffset;
1209
1210 if (pntsd == NULL)
1211 return -EIO;
1212
1213 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1214 le32_to_cpu(pntsd->osidoffset));
1215 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1216 le32_to_cpu(pntsd->gsidoffset));
1217 dacloffset = le32_to_cpu(pntsd->dacloffset);
1218 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1219 cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1220 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1221 le32_to_cpu(pntsd->gsidoffset),
1222 le32_to_cpu(pntsd->sacloffset), dacloffset);
1223
1224 rc = parse_sid(owner_sid_ptr, end_of_acl);
1225 if (rc) {
1226 cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1227 return rc;
1228 }
1229 rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1230 if (rc) {
1231 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1232 __func__, rc);
1233 return rc;
1234 }
1235
1236 rc = parse_sid(group_sid_ptr, end_of_acl);
1237 if (rc) {
1238 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
1239 __func__, rc);
1240 return rc;
1241 }
1242 rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1243 if (rc) {
1244 cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1245 __func__, rc);
1246 return rc;
1247 }
1248
1249 if (dacloffset)
1250 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1251 group_sid_ptr, fattr, get_mode_from_special_sid);
1252 else
1253 cifs_dbg(FYI, "no ACL\n");
1254
1255 return rc;
1256}
1257
1258
1259static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1260 __u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
1261 bool mode_from_sid, bool id_from_sid, int *aclflag)
1262{
1263 int rc = 0;
1264 __u32 dacloffset;
1265 __u32 ndacloffset;
1266 __u32 sidsoffset;
1267 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1268 struct cifs_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
1269 struct cifs_acl *dacl_ptr = NULL;
1270 struct cifs_acl *ndacl_ptr = NULL;
1271 char *end_of_acl = ((char *)pntsd) + secdesclen;
1272 u16 size = 0;
1273
1274 dacloffset = le32_to_cpu(pntsd->dacloffset);
1275 if (dacloffset) {
1276 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1277 if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) {
1278 cifs_dbg(VFS, "Server returned illegal ACL size\n");
1279 return -EINVAL;
1280 }
1281 }
1282
1283 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1284 le32_to_cpu(pntsd->osidoffset));
1285 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1286 le32_to_cpu(pntsd->gsidoffset));
1287
1288 if (pnmode && *pnmode != NO_CHANGE_64) {
1289 ndacloffset = sizeof(struct cifs_ntsd);
1290 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1291 ndacl_ptr->revision =
1292 dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1293
1294 ndacl_ptr->size = cpu_to_le16(0);
1295 ndacl_ptr->num_aces = cpu_to_le32(0);
1296
1297 rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1298 pnmode, mode_from_sid);
1299
1300 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1301
1302 *pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1303 NULL, NULL);
1304
1305 *aclflag |= CIFS_ACL_DACL;
1306 } else {
1307 ndacloffset = sizeof(struct cifs_ntsd);
1308 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1309 ndacl_ptr->revision =
1310 dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1311 ndacl_ptr->num_aces = dacl_ptr->num_aces;
1312
1313 if (uid_valid(uid)) {
1314 uid_t id;
1315 nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1316 GFP_KERNEL);
1317 if (!nowner_sid_ptr) {
1318 rc = -ENOMEM;
1319 goto chown_chgrp_exit;
1320 }
1321 id = from_kuid(&init_user_ns, uid);
1322 if (id_from_sid) {
1323 struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1324
1325 osid->Revision = 1;
1326 osid->NumAuth = 3;
1327 osid->Authority[5] = 5;
1328 osid->SubAuthorities[0] = cpu_to_le32(88);
1329 osid->SubAuthorities[1] = cpu_to_le32(1);
1330 osid->SubAuthorities[2] = cpu_to_le32(id);
1331
1332 } else {
1333 rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1334 if (rc) {
1335 cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1336 __func__, rc, id);
1337 goto chown_chgrp_exit;
1338 }
1339 }
1340 *aclflag |= CIFS_ACL_OWNER;
1341 }
1342 if (gid_valid(gid)) {
1343 gid_t id;
1344 ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1345 GFP_KERNEL);
1346 if (!ngroup_sid_ptr) {
1347 rc = -ENOMEM;
1348 goto chown_chgrp_exit;
1349 }
1350 id = from_kgid(&init_user_ns, gid);
1351 if (id_from_sid) {
1352 struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1353
1354 gsid->Revision = 1;
1355 gsid->NumAuth = 3;
1356 gsid->Authority[5] = 5;
1357 gsid->SubAuthorities[0] = cpu_to_le32(88);
1358 gsid->SubAuthorities[1] = cpu_to_le32(2);
1359 gsid->SubAuthorities[2] = cpu_to_le32(id);
1360
1361 } else {
1362 rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1363 if (rc) {
1364 cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1365 __func__, rc, id);
1366 goto chown_chgrp_exit;
1367 }
1368 }
1369 *aclflag |= CIFS_ACL_GROUP;
1370 }
1371
1372 if (dacloffset) {
1373
1374 size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1375 owner_sid_ptr, group_sid_ptr,
1376 nowner_sid_ptr, ngroup_sid_ptr);
1377 ndacl_ptr->size = cpu_to_le16(size);
1378 }
1379
1380 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1381
1382 *pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1383 nowner_sid_ptr, ngroup_sid_ptr);
1384
1385chown_chgrp_exit:
1386
1387 kfree(nowner_sid_ptr);
1388 kfree(ngroup_sid_ptr);
1389 }
1390
1391 return rc;
1392}
1393
1394struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1395 const struct cifs_fid *cifsfid, u32 *pacllen,
1396 u32 __maybe_unused unused)
1397{
1398 struct cifs_ntsd *pntsd = NULL;
1399 unsigned int xid;
1400 int rc;
1401 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1402
1403 if (IS_ERR(tlink))
1404 return ERR_CAST(tlink);
1405
1406 xid = get_xid();
1407 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1408 pacllen);
1409 free_xid(xid);
1410
1411 cifs_put_tlink(tlink);
1412
1413 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1414 if (rc)
1415 return ERR_PTR(rc);
1416 return pntsd;
1417}
1418
1419static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1420 const char *path, u32 *pacllen)
1421{
1422 struct cifs_ntsd *pntsd = NULL;
1423 int oplock = 0;
1424 unsigned int xid;
1425 int rc;
1426 struct cifs_tcon *tcon;
1427 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1428 struct cifs_fid fid;
1429 struct cifs_open_parms oparms;
1430
1431 if (IS_ERR(tlink))
1432 return ERR_CAST(tlink);
1433
1434 tcon = tlink_tcon(tlink);
1435 xid = get_xid();
1436
1437 oparms.tcon = tcon;
1438 oparms.cifs_sb = cifs_sb;
1439 oparms.desired_access = READ_CONTROL;
1440 oparms.create_options = cifs_create_options(cifs_sb, 0);
1441 oparms.disposition = FILE_OPEN;
1442 oparms.path = path;
1443 oparms.fid = &fid;
1444 oparms.reconnect = false;
1445
1446 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1447 if (!rc) {
1448 rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1449 CIFSSMBClose(xid, tcon, fid.netfid);
1450 }
1451
1452 cifs_put_tlink(tlink);
1453 free_xid(xid);
1454
1455 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1456 if (rc)
1457 return ERR_PTR(rc);
1458 return pntsd;
1459}
1460
1461
1462struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1463 struct inode *inode, const char *path,
1464 u32 *pacllen, u32 info)
1465{
1466 struct cifs_ntsd *pntsd = NULL;
1467 struct cifsFileInfo *open_file = NULL;
1468
1469 if (inode)
1470 open_file = find_readable_file(CIFS_I(inode), true);
1471 if (!open_file)
1472 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1473
1474 pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1475 cifsFileInfo_put(open_file);
1476 return pntsd;
1477}
1478
1479
1480int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1481 struct inode *inode, const char *path, int aclflag)
1482{
1483 int oplock = 0;
1484 unsigned int xid;
1485 int rc, access_flags;
1486 struct cifs_tcon *tcon;
1487 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1488 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1489 struct cifs_fid fid;
1490 struct cifs_open_parms oparms;
1491
1492 if (IS_ERR(tlink))
1493 return PTR_ERR(tlink);
1494
1495 tcon = tlink_tcon(tlink);
1496 xid = get_xid();
1497
1498 if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1499 access_flags = WRITE_OWNER;
1500 else
1501 access_flags = WRITE_DAC;
1502
1503 oparms.tcon = tcon;
1504 oparms.cifs_sb = cifs_sb;
1505 oparms.desired_access = access_flags;
1506 oparms.create_options = cifs_create_options(cifs_sb, 0);
1507 oparms.disposition = FILE_OPEN;
1508 oparms.path = path;
1509 oparms.fid = &fid;
1510 oparms.reconnect = false;
1511
1512 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1513 if (rc) {
1514 cifs_dbg(VFS, "Unable to open file to set ACL\n");
1515 goto out;
1516 }
1517
1518 rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1519 cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1520
1521 CIFSSMBClose(xid, tcon, fid.netfid);
1522out:
1523 free_xid(xid);
1524 cifs_put_tlink(tlink);
1525 return rc;
1526}
1527
1528
1529int
1530cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1531 struct inode *inode, bool mode_from_special_sid,
1532 const char *path, const struct cifs_fid *pfid)
1533{
1534 struct cifs_ntsd *pntsd = NULL;
1535 u32 acllen = 0;
1536 int rc = 0;
1537 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1538 struct smb_version_operations *ops;
1539 const u32 info = 0;
1540
1541 cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1542
1543 if (IS_ERR(tlink))
1544 return PTR_ERR(tlink);
1545
1546 ops = tlink_tcon(tlink)->ses->server->ops;
1547
1548 if (pfid && (ops->get_acl_by_fid))
1549 pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1550 else if (ops->get_acl)
1551 pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1552 else {
1553 cifs_put_tlink(tlink);
1554 return -EOPNOTSUPP;
1555 }
1556
1557 if (IS_ERR(pntsd)) {
1558 rc = PTR_ERR(pntsd);
1559 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1560 } else if (mode_from_special_sid) {
1561 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1562 kfree(pntsd);
1563 } else {
1564
1565 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1566 kfree(pntsd);
1567 if (rc)
1568 cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1569 }
1570
1571 cifs_put_tlink(tlink);
1572
1573 return rc;
1574}
1575
1576
1577int
1578id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1579 kuid_t uid, kgid_t gid)
1580{
1581 int rc = 0;
1582 int aclflag = CIFS_ACL_DACL;
1583 __u32 secdesclen = 0;
1584 __u32 nsecdesclen = 0;
1585 __u32 dacloffset = 0;
1586 struct cifs_acl *dacl_ptr = NULL;
1587 struct cifs_ntsd *pntsd = NULL;
1588 struct cifs_ntsd *pnntsd = NULL;
1589 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1590 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1591 struct smb_version_operations *ops;
1592 bool mode_from_sid, id_from_sid;
1593 const u32 info = 0;
1594
1595 if (IS_ERR(tlink))
1596 return PTR_ERR(tlink);
1597
1598 ops = tlink_tcon(tlink)->ses->server->ops;
1599
1600 cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1601
1602
1603
1604 if (ops->get_acl == NULL) {
1605 cifs_put_tlink(tlink);
1606 return -EOPNOTSUPP;
1607 }
1608
1609 pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1610 if (IS_ERR(pntsd)) {
1611 rc = PTR_ERR(pntsd);
1612 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1613 cifs_put_tlink(tlink);
1614 return rc;
1615 }
1616
1617 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1618 mode_from_sid = true;
1619 else
1620 mode_from_sid = false;
1621
1622 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1623 id_from_sid = true;
1624 else
1625 id_from_sid = false;
1626
1627
1628 nsecdesclen = secdesclen;
1629 if (pnmode && *pnmode != NO_CHANGE_64) {
1630 if (mode_from_sid)
1631 nsecdesclen += sizeof(struct cifs_ace);
1632 else
1633 nsecdesclen += 5 * sizeof(struct cifs_ace);
1634 } else {
1635
1636 nsecdesclen = sizeof(struct cifs_ntsd) + (sizeof(struct cifs_sid) * 2);
1637 dacloffset = le32_to_cpu(pntsd->dacloffset);
1638 if (dacloffset) {
1639 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1640 if (mode_from_sid)
1641 nsecdesclen +=
1642 le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace);
1643 else
1644 nsecdesclen += le16_to_cpu(dacl_ptr->size);
1645 }
1646 }
1647
1648
1649
1650
1651
1652
1653
1654 nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1655 pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);
1656 if (!pnntsd) {
1657 kfree(pntsd);
1658 cifs_put_tlink(tlink);
1659 return -ENOMEM;
1660 }
1661
1662 rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1663 mode_from_sid, id_from_sid, &aclflag);
1664
1665 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1666
1667 if (ops->set_acl == NULL)
1668 rc = -EOPNOTSUPP;
1669
1670 if (!rc) {
1671
1672 rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1673 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1674 }
1675 cifs_put_tlink(tlink);
1676
1677 kfree(pnntsd);
1678 kfree(pntsd);
1679 return rc;
1680}
1681