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
36
37static const struct cifs_sid sid_everyone = {
38 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
39
40static const struct cifs_sid sid_authusers = {
41 1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
42
43static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
44
45
46static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
47 {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
48
49
50static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
51 {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
52
53
54
55
56
57
58
59
60static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
61 {cpu_to_le32(88),
62 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
63
64
65static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
66 {cpu_to_le32(88),
67 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
68
69
70static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
71 {cpu_to_le32(88),
72 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
73
74static const struct cred *root_cred;
75
76static int
77cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
78{
79 char *payload;
80
81
82
83
84
85
86
87
88
89 if (prep->datalen <= sizeof(key->payload)) {
90 key->payload.data[0] = NULL;
91 memcpy(&key->payload, prep->data, prep->datalen);
92 } else {
93 payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
94 if (!payload)
95 return -ENOMEM;
96 key->payload.data[0] = payload;
97 }
98
99 key->datalen = prep->datalen;
100 return 0;
101}
102
103static inline void
104cifs_idmap_key_destroy(struct key *key)
105{
106 if (key->datalen > sizeof(key->payload))
107 kfree(key->payload.data[0]);
108}
109
110static struct key_type cifs_idmap_key_type = {
111 .name = "cifs.idmap",
112 .instantiate = cifs_idmap_key_instantiate,
113 .destroy = cifs_idmap_key_destroy,
114 .describe = user_describe,
115};
116
117static char *
118sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
119{
120 int i, len;
121 unsigned int saval;
122 char *sidstr, *strptr;
123 unsigned long long id_auth_val;
124
125
126 sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
127 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
128 GFP_KERNEL);
129 if (!sidstr)
130 return sidstr;
131
132 strptr = sidstr;
133 len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
134 sidptr->revision);
135 strptr += len;
136
137
138 id_auth_val = (unsigned long long)sidptr->authority[5];
139 id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
140 id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
141 id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
142 id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
143 id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
144
145
146
147
148
149 if (id_auth_val <= UINT_MAX)
150 len = sprintf(strptr, "-%llu", id_auth_val);
151 else
152 len = sprintf(strptr, "-0x%llx", id_auth_val);
153
154 strptr += len;
155
156 for (i = 0; i < sidptr->num_subauth; ++i) {
157 saval = le32_to_cpu(sidptr->sub_auth[i]);
158 len = sprintf(strptr, "-%u", saval);
159 strptr += len;
160 }
161
162 return sidstr;
163}
164
165
166
167
168
169static int
170compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
171{
172 int i;
173 int num_subauth, num_sat, num_saw;
174
175 if ((!ctsid) || (!cwsid))
176 return 1;
177
178
179 if (ctsid->revision != cwsid->revision) {
180 if (ctsid->revision > cwsid->revision)
181 return 1;
182 else
183 return -1;
184 }
185
186
187 for (i = 0; i < NUM_AUTHS; ++i) {
188 if (ctsid->authority[i] != cwsid->authority[i]) {
189 if (ctsid->authority[i] > cwsid->authority[i])
190 return 1;
191 else
192 return -1;
193 }
194 }
195
196
197 num_sat = ctsid->num_subauth;
198 num_saw = cwsid->num_subauth;
199 num_subauth = num_sat < num_saw ? num_sat : num_saw;
200 if (num_subauth) {
201 for (i = 0; i < num_subauth; ++i) {
202 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
203 if (le32_to_cpu(ctsid->sub_auth[i]) >
204 le32_to_cpu(cwsid->sub_auth[i]))
205 return 1;
206 else
207 return -1;
208 }
209 }
210 }
211
212 return 0;
213}
214
215static bool
216is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
217{
218 int i;
219 int num_subauth;
220 const struct cifs_sid *pwell_known_sid;
221
222 if (!psid || (puid == NULL))
223 return false;
224
225 num_subauth = psid->num_subauth;
226
227
228 if (num_subauth == 2) {
229 if (is_group)
230 pwell_known_sid = &sid_unix_groups;
231 else
232 pwell_known_sid = &sid_unix_users;
233 } else if (num_subauth == 3) {
234 if (is_group)
235 pwell_known_sid = &sid_unix_NFS_groups;
236 else
237 pwell_known_sid = &sid_unix_NFS_users;
238 } else
239 return false;
240
241
242 if (psid->revision != pwell_known_sid->revision)
243 return false;
244
245
246 for (i = 0; i < NUM_AUTHS; ++i) {
247 if (psid->authority[i] != pwell_known_sid->authority[i]) {
248 cifs_dbg(FYI, "auth %d did not match\n", i);
249 return false;
250 }
251 }
252
253 if (num_subauth == 2) {
254 if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
255 return false;
256
257 *puid = le32_to_cpu(psid->sub_auth[1]);
258 } else {
259 *puid = le32_to_cpu(psid->sub_auth[0]);
260 if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
261 (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
262 return false;
263
264 *puid = le32_to_cpu(psid->sub_auth[2]);
265 }
266
267 cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
268 return true;
269}
270
271static void
272cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
273{
274 int i;
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}
283
284static int
285id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
286{
287 int rc;
288 struct key *sidkey;
289 struct cifs_sid *ksid;
290 unsigned int ksid_size;
291 char desc[3 + 10 + 1];
292 const struct cred *saved_cred;
293
294 rc = snprintf(desc, sizeof(desc), "%ci:%u",
295 sidtype == SIDOWNER ? 'o' : 'g', cid);
296 if (rc >= sizeof(desc))
297 return -EINVAL;
298
299 rc = 0;
300 saved_cred = override_creds(root_cred);
301 sidkey = request_key(&cifs_idmap_key_type, desc, "");
302 if (IS_ERR(sidkey)) {
303 rc = -EINVAL;
304 cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
305 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
306 goto out_revert_creds;
307 } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
308 rc = -EIO;
309 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
310 __func__, sidkey->datalen);
311 goto invalidate_key;
312 }
313
314
315
316
317
318
319 ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
320 (struct cifs_sid *)&sidkey->payload :
321 (struct cifs_sid *)sidkey->payload.data[0];
322
323 ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
324 if (ksid_size > sidkey->datalen) {
325 rc = -EIO;
326 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
327 __func__, sidkey->datalen, ksid_size);
328 goto invalidate_key;
329 }
330
331 cifs_copy_sid(ssid, ksid);
332out_key_put:
333 key_put(sidkey);
334out_revert_creds:
335 revert_creds(saved_cred);
336 return rc;
337
338invalidate_key:
339 key_invalidate(sidkey);
340 goto out_key_put;
341}
342
343static int
344sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
345 struct cifs_fattr *fattr, uint sidtype)
346{
347 int rc;
348 struct key *sidkey;
349 char *sidstr;
350 const struct cred *saved_cred;
351 kuid_t fuid = cifs_sb->mnt_uid;
352 kgid_t fgid = cifs_sb->mnt_gid;
353
354
355
356
357
358 if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
359 cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
360 __func__, psid->num_subauth);
361 return -EIO;
362 }
363
364 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) {
365 uint32_t unix_id;
366 bool is_group;
367
368 if (sidtype != SIDOWNER)
369 is_group = true;
370 else
371 is_group = false;
372
373 if (is_well_known_sid(psid, &unix_id, is_group) == false)
374 goto try_upcall_to_get_id;
375
376 if (is_group) {
377 kgid_t gid;
378 gid_t id;
379
380 id = (gid_t)unix_id;
381 gid = make_kgid(&init_user_ns, id);
382 if (gid_valid(gid)) {
383 fgid = gid;
384 goto got_valid_id;
385 }
386 } else {
387 kuid_t uid;
388 uid_t id;
389
390 id = (uid_t)unix_id;
391 uid = make_kuid(&init_user_ns, id);
392 if (uid_valid(uid)) {
393 fuid = uid;
394 goto got_valid_id;
395 }
396 }
397
398 }
399
400try_upcall_to_get_id:
401 sidstr = sid_to_key_str(psid, sidtype);
402 if (!sidstr)
403 return -ENOMEM;
404
405 saved_cred = override_creds(root_cred);
406 sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
407 if (IS_ERR(sidkey)) {
408 rc = -EINVAL;
409 cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
410 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
411 goto out_revert_creds;
412 }
413
414
415
416
417
418
419 BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
420 if (sidkey->datalen != sizeof(uid_t)) {
421 rc = -EIO;
422 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
423 __func__, sidkey->datalen);
424 key_invalidate(sidkey);
425 goto out_key_put;
426 }
427
428 if (sidtype == SIDOWNER) {
429 kuid_t uid;
430 uid_t id;
431 memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
432 uid = make_kuid(&init_user_ns, id);
433 if (uid_valid(uid))
434 fuid = uid;
435 } else {
436 kgid_t gid;
437 gid_t id;
438 memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
439 gid = make_kgid(&init_user_ns, id);
440 if (gid_valid(gid))
441 fgid = gid;
442 }
443
444out_key_put:
445 key_put(sidkey);
446out_revert_creds:
447 revert_creds(saved_cred);
448 kfree(sidstr);
449
450
451
452
453
454got_valid_id:
455 if (sidtype == SIDOWNER)
456 fattr->cf_uid = fuid;
457 else
458 fattr->cf_gid = fgid;
459 return 0;
460}
461
462int
463init_cifs_idmap(void)
464{
465 struct cred *cred;
466 struct key *keyring;
467 int ret;
468
469 cifs_dbg(FYI, "Registering the %s key type\n",
470 cifs_idmap_key_type.name);
471
472
473
474
475
476
477
478 cred = prepare_kernel_cred(NULL);
479 if (!cred)
480 return -ENOMEM;
481
482 keyring = keyring_alloc(".cifs_idmap",
483 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
484 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
485 KEY_USR_VIEW | KEY_USR_READ,
486 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
487 if (IS_ERR(keyring)) {
488 ret = PTR_ERR(keyring);
489 goto failed_put_cred;
490 }
491
492 ret = register_key_type(&cifs_idmap_key_type);
493 if (ret < 0)
494 goto failed_put_key;
495
496
497
498 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
499 cred->thread_keyring = keyring;
500 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
501 root_cred = cred;
502
503 cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
504 return 0;
505
506failed_put_key:
507 key_put(keyring);
508failed_put_cred:
509 put_cred(cred);
510 return ret;
511}
512
513void
514exit_cifs_idmap(void)
515{
516 key_revoke(root_cred->thread_keyring);
517 unregister_key_type(&cifs_idmap_key_type);
518 put_cred(root_cred);
519 cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
520}
521
522
523static void copy_sec_desc(const struct cifs_ntsd *pntsd,
524 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
525{
526 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
527 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
528
529
530 pnntsd->revision = pntsd->revision;
531 pnntsd->type = pntsd->type;
532 pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
533 pnntsd->sacloffset = 0;
534 pnntsd->osidoffset = cpu_to_le32(sidsoffset);
535 pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
536
537
538 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
539 le32_to_cpu(pntsd->osidoffset));
540 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
541 cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
542
543
544 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
545 le32_to_cpu(pntsd->gsidoffset));
546 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
547 sizeof(struct cifs_sid));
548 cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
549
550 return;
551}
552
553
554
555
556
557
558
559static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
560 umode_t *pbits_to_set)
561{
562 __u32 flags = le32_to_cpu(ace_flags);
563
564
565
566
567
568
569
570
571 if (type == ACCESS_DENIED) {
572 if (flags & GENERIC_ALL)
573 *pbits_to_set &= ~S_IRWXUGO;
574
575 if ((flags & GENERIC_WRITE) ||
576 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
577 *pbits_to_set &= ~S_IWUGO;
578 if ((flags & GENERIC_READ) ||
579 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
580 *pbits_to_set &= ~S_IRUGO;
581 if ((flags & GENERIC_EXECUTE) ||
582 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
583 *pbits_to_set &= ~S_IXUGO;
584 return;
585 } else if (type != ACCESS_ALLOWED) {
586 cifs_dbg(VFS, "unknown access control type %d\n", type);
587 return;
588 }
589
590
591 if (flags & GENERIC_ALL) {
592 *pmode |= (S_IRWXUGO & (*pbits_to_set));
593 cifs_dbg(NOISY, "all perms\n");
594 return;
595 }
596 if ((flags & GENERIC_WRITE) ||
597 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
598 *pmode |= (S_IWUGO & (*pbits_to_set));
599 if ((flags & GENERIC_READ) ||
600 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
601 *pmode |= (S_IRUGO & (*pbits_to_set));
602 if ((flags & GENERIC_EXECUTE) ||
603 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
604 *pmode |= (S_IXUGO & (*pbits_to_set));
605
606 cifs_dbg(NOISY, "access flags 0x%x mode now 0x%x\n", flags, *pmode);
607 return;
608}
609
610
611
612
613
614
615
616static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
617 __u32 *pace_flags)
618{
619
620 *pace_flags = 0x0;
621
622
623 mode &= bits_to_use;
624
625
626
627
628 if (mode & S_IRUGO)
629 *pace_flags |= SET_FILE_READ_RIGHTS;
630 if (mode & S_IWUGO)
631 *pace_flags |= SET_FILE_WRITE_RIGHTS;
632 if (mode & S_IXUGO)
633 *pace_flags |= SET_FILE_EXEC_RIGHTS;
634
635 cifs_dbg(NOISY, "mode: 0x%x, access flags now 0x%x\n",
636 mode, *pace_flags);
637 return;
638}
639
640static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
641 const struct cifs_sid *psid, __u64 nmode, umode_t bits)
642{
643 int i;
644 __u16 size = 0;
645 __u32 access_req = 0;
646
647 pntace->type = ACCESS_ALLOWED;
648 pntace->flags = 0x0;
649 mode_to_access_flags(nmode, bits, &access_req);
650 if (!access_req)
651 access_req = SET_MINIMUM_RIGHTS;
652 pntace->access_req = cpu_to_le32(access_req);
653
654 pntace->sid.revision = psid->revision;
655 pntace->sid.num_subauth = psid->num_subauth;
656 for (i = 0; i < NUM_AUTHS; i++)
657 pntace->sid.authority[i] = psid->authority[i];
658 for (i = 0; i < psid->num_subauth; i++)
659 pntace->sid.sub_auth[i] = psid->sub_auth[i];
660
661 size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
662 pntace->size = cpu_to_le16(size);
663
664 return size;
665}
666
667
668#ifdef CONFIG_CIFS_DEBUG2
669static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
670{
671 int num_subauth;
672
673
674
675 if (le16_to_cpu(pace->size) < 16) {
676 cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
677 return;
678 }
679
680 if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
681 cifs_dbg(VFS, "ACL too small to parse ACE\n");
682 return;
683 }
684
685 num_subauth = pace->sid.num_subauth;
686 if (num_subauth) {
687 int i;
688 cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
689 pace->sid.revision, pace->sid.num_subauth, pace->type,
690 pace->flags, le16_to_cpu(pace->size));
691 for (i = 0; i < num_subauth; ++i) {
692 cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
693 i, le32_to_cpu(pace->sid.sub_auth[i]));
694 }
695
696
697
698 }
699
700 return;
701}
702#endif
703
704
705static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
706 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
707 struct cifs_fattr *fattr)
708{
709 int i;
710 int num_aces = 0;
711 int acl_size;
712 char *acl_base;
713 struct cifs_ace **ppace;
714
715
716
717 if (!pdacl) {
718
719
720 fattr->cf_mode |= S_IRWXUGO;
721 return;
722 }
723
724
725 if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
726 cifs_dbg(VFS, "ACL too small to parse DACL\n");
727 return;
728 }
729
730 cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
731 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
732 le32_to_cpu(pdacl->num_aces));
733
734
735
736
737 fattr->cf_mode &= ~(S_IRWXUGO);
738
739 acl_base = (char *)pdacl;
740 acl_size = sizeof(struct cifs_acl);
741
742 num_aces = le32_to_cpu(pdacl->num_aces);
743 if (num_aces > 0) {
744 umode_t user_mask = S_IRWXU;
745 umode_t group_mask = S_IRWXG;
746 umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
747
748 if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
749 return;
750 ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
751 GFP_KERNEL);
752 if (!ppace)
753 return;
754
755 for (i = 0; i < num_aces; ++i) {
756 ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
757#ifdef CONFIG_CIFS_DEBUG2
758 dump_ace(ppace[i], end_of_acl);
759#endif
760 if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
761 access_flags_to_mode(ppace[i]->access_req,
762 ppace[i]->type,
763 &fattr->cf_mode,
764 &user_mask);
765 if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
766 access_flags_to_mode(ppace[i]->access_req,
767 ppace[i]->type,
768 &fattr->cf_mode,
769 &group_mask);
770 if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
771 access_flags_to_mode(ppace[i]->access_req,
772 ppace[i]->type,
773 &fattr->cf_mode,
774 &other_mask);
775 if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
776 access_flags_to_mode(ppace[i]->access_req,
777 ppace[i]->type,
778 &fattr->cf_mode,
779 &other_mask);
780
781
782
783
784
785
786 acl_base = (char *)ppace[i];
787 acl_size = le16_to_cpu(ppace[i]->size);
788 }
789
790 kfree(ppace);
791 }
792
793 return;
794}
795
796
797static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
798 struct cifs_sid *pgrpsid, __u64 nmode)
799{
800 u16 size = 0;
801 struct cifs_acl *pnndacl;
802
803 pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
804
805 size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
806 pownersid, nmode, S_IRWXU);
807 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
808 pgrpsid, nmode, S_IRWXG);
809 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
810 &sid_everyone, nmode, S_IRWXO);
811
812 pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
813 pndacl->num_aces = cpu_to_le32(3);
814
815 return 0;
816}
817
818
819static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
820{
821
822
823
824
825 if (end_of_acl < (char *)psid + 8) {
826 cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
827 return -EINVAL;
828 }
829
830#ifdef CONFIG_CIFS_DEBUG2
831 if (psid->num_subauth) {
832 int i;
833 cifs_dbg(FYI, "SID revision %d num_auth %d\n",
834 psid->revision, psid->num_subauth);
835
836 for (i = 0; i < psid->num_subauth; i++) {
837 cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
838 i, le32_to_cpu(psid->sub_auth[i]));
839 }
840
841
842
843 cifs_dbg(FYI, "RID 0x%x\n",
844 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
845 }
846#endif
847
848 return 0;
849}
850
851
852
853static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
854 struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr)
855{
856 int rc = 0;
857 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
858 struct cifs_acl *dacl_ptr;
859 char *end_of_acl = ((char *)pntsd) + acl_len;
860 __u32 dacloffset;
861
862 if (pntsd == NULL)
863 return -EIO;
864
865 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
866 le32_to_cpu(pntsd->osidoffset));
867 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
868 le32_to_cpu(pntsd->gsidoffset));
869 dacloffset = le32_to_cpu(pntsd->dacloffset);
870 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
871 cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
872 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
873 le32_to_cpu(pntsd->gsidoffset),
874 le32_to_cpu(pntsd->sacloffset), dacloffset);
875
876 rc = parse_sid(owner_sid_ptr, end_of_acl);
877 if (rc) {
878 cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
879 return rc;
880 }
881 rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
882 if (rc) {
883 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
884 __func__, rc);
885 return rc;
886 }
887
888 rc = parse_sid(group_sid_ptr, end_of_acl);
889 if (rc) {
890 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
891 __func__, rc);
892 return rc;
893 }
894 rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
895 if (rc) {
896 cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
897 __func__, rc);
898 return rc;
899 }
900
901 if (dacloffset)
902 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
903 group_sid_ptr, fattr);
904 else
905 cifs_dbg(FYI, "no ACL\n");
906
907 return rc;
908}
909
910
911static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
912 __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag)
913{
914 int rc = 0;
915 __u32 dacloffset;
916 __u32 ndacloffset;
917 __u32 sidsoffset;
918 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
919 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
920 struct cifs_acl *dacl_ptr = NULL;
921 struct cifs_acl *ndacl_ptr = NULL;
922
923 if (nmode != NO_CHANGE_64) {
924 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
925 le32_to_cpu(pntsd->osidoffset));
926 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
927 le32_to_cpu(pntsd->gsidoffset));
928 dacloffset = le32_to_cpu(pntsd->dacloffset);
929 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
930 ndacloffset = sizeof(struct cifs_ntsd);
931 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
932 ndacl_ptr->revision = dacl_ptr->revision;
933 ndacl_ptr->size = 0;
934 ndacl_ptr->num_aces = 0;
935
936 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
937 nmode);
938 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
939
940 copy_sec_desc(pntsd, pnntsd, sidsoffset);
941 *aclflag = CIFS_ACL_DACL;
942 } else {
943 memcpy(pnntsd, pntsd, secdesclen);
944 if (uid_valid(uid)) {
945 uid_t id;
946 owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
947 le32_to_cpu(pnntsd->osidoffset));
948 nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
949 GFP_KERNEL);
950 if (!nowner_sid_ptr)
951 return -ENOMEM;
952 id = from_kuid(&init_user_ns, uid);
953 rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
954 if (rc) {
955 cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
956 __func__, rc, id);
957 kfree(nowner_sid_ptr);
958 return rc;
959 }
960 cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
961 kfree(nowner_sid_ptr);
962 *aclflag = CIFS_ACL_OWNER;
963 }
964 if (gid_valid(gid)) {
965 gid_t id;
966 group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
967 le32_to_cpu(pnntsd->gsidoffset));
968 ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
969 GFP_KERNEL);
970 if (!ngroup_sid_ptr)
971 return -ENOMEM;
972 id = from_kgid(&init_user_ns, gid);
973 rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
974 if (rc) {
975 cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
976 __func__, rc, id);
977 kfree(ngroup_sid_ptr);
978 return rc;
979 }
980 cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
981 kfree(ngroup_sid_ptr);
982 *aclflag = CIFS_ACL_GROUP;
983 }
984 }
985
986 return rc;
987}
988
989struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
990 const struct cifs_fid *cifsfid, u32 *pacllen)
991{
992 struct cifs_ntsd *pntsd = NULL;
993 unsigned int xid;
994 int rc;
995 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
996
997 if (IS_ERR(tlink))
998 return ERR_CAST(tlink);
999
1000 xid = get_xid();
1001 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1002 pacllen);
1003 free_xid(xid);
1004
1005 cifs_put_tlink(tlink);
1006
1007 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1008 if (rc)
1009 return ERR_PTR(rc);
1010 return pntsd;
1011}
1012
1013static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1014 const char *path, u32 *pacllen)
1015{
1016 struct cifs_ntsd *pntsd = NULL;
1017 int oplock = 0;
1018 unsigned int xid;
1019 int rc, create_options = 0;
1020 struct cifs_tcon *tcon;
1021 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1022 struct cifs_fid fid;
1023 struct cifs_open_parms oparms;
1024
1025 if (IS_ERR(tlink))
1026 return ERR_CAST(tlink);
1027
1028 tcon = tlink_tcon(tlink);
1029 xid = get_xid();
1030
1031 if (backup_cred(cifs_sb))
1032 create_options |= CREATE_OPEN_BACKUP_INTENT;
1033
1034 oparms.tcon = tcon;
1035 oparms.cifs_sb = cifs_sb;
1036 oparms.desired_access = READ_CONTROL;
1037 oparms.create_options = create_options;
1038 oparms.disposition = FILE_OPEN;
1039 oparms.path = path;
1040 oparms.fid = &fid;
1041 oparms.reconnect = false;
1042
1043 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1044 if (!rc) {
1045 rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1046 CIFSSMBClose(xid, tcon, fid.netfid);
1047 }
1048
1049 cifs_put_tlink(tlink);
1050 free_xid(xid);
1051
1052 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1053 if (rc)
1054 return ERR_PTR(rc);
1055 return pntsd;
1056}
1057
1058
1059struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1060 struct inode *inode, const char *path,
1061 u32 *pacllen)
1062{
1063 struct cifs_ntsd *pntsd = NULL;
1064 struct cifsFileInfo *open_file = NULL;
1065
1066 if (inode)
1067 open_file = find_readable_file(CIFS_I(inode), true);
1068 if (!open_file)
1069 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1070
1071 pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
1072 cifsFileInfo_put(open_file);
1073 return pntsd;
1074}
1075
1076
1077int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1078 struct inode *inode, const char *path, int aclflag)
1079{
1080 int oplock = 0;
1081 unsigned int xid;
1082 int rc, access_flags, create_options = 0;
1083 struct cifs_tcon *tcon;
1084 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1085 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1086 struct cifs_fid fid;
1087 struct cifs_open_parms oparms;
1088
1089 if (IS_ERR(tlink))
1090 return PTR_ERR(tlink);
1091
1092 tcon = tlink_tcon(tlink);
1093 xid = get_xid();
1094
1095 if (backup_cred(cifs_sb))
1096 create_options |= CREATE_OPEN_BACKUP_INTENT;
1097
1098 if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1099 access_flags = WRITE_OWNER;
1100 else
1101 access_flags = WRITE_DAC;
1102
1103 oparms.tcon = tcon;
1104 oparms.cifs_sb = cifs_sb;
1105 oparms.desired_access = access_flags;
1106 oparms.create_options = create_options;
1107 oparms.disposition = FILE_OPEN;
1108 oparms.path = path;
1109 oparms.fid = &fid;
1110 oparms.reconnect = false;
1111
1112 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1113 if (rc) {
1114 cifs_dbg(VFS, "Unable to open file to set ACL\n");
1115 goto out;
1116 }
1117
1118 rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1119 cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1120
1121 CIFSSMBClose(xid, tcon, fid.netfid);
1122out:
1123 free_xid(xid);
1124 cifs_put_tlink(tlink);
1125 return rc;
1126}
1127
1128
1129int
1130cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1131 struct inode *inode, const char *path,
1132 const struct cifs_fid *pfid)
1133{
1134 struct cifs_ntsd *pntsd = NULL;
1135 u32 acllen = 0;
1136 int rc = 0;
1137 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1138 struct smb_version_operations *ops;
1139
1140 cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1141
1142 if (IS_ERR(tlink))
1143 return PTR_ERR(tlink);
1144
1145 ops = tlink_tcon(tlink)->ses->server->ops;
1146
1147 if (pfid && (ops->get_acl_by_fid))
1148 pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
1149 else if (ops->get_acl)
1150 pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
1151 else {
1152 cifs_put_tlink(tlink);
1153 return -EOPNOTSUPP;
1154 }
1155
1156 if (IS_ERR(pntsd)) {
1157 rc = PTR_ERR(pntsd);
1158 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1159 } else {
1160 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr);
1161 kfree(pntsd);
1162 if (rc)
1163 cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1164 }
1165
1166 cifs_put_tlink(tlink);
1167
1168 return rc;
1169}
1170
1171
1172int
1173id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1174 kuid_t uid, kgid_t gid)
1175{
1176 int rc = 0;
1177 int aclflag = CIFS_ACL_DACL;
1178 __u32 secdesclen = 0;
1179 struct cifs_ntsd *pntsd = NULL;
1180 struct cifs_ntsd *pnntsd = NULL;
1181 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1182 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1183 struct smb_version_operations *ops;
1184
1185 if (IS_ERR(tlink))
1186 return PTR_ERR(tlink);
1187
1188 ops = tlink_tcon(tlink)->ses->server->ops;
1189
1190 cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1191
1192
1193
1194 if (ops->get_acl == NULL) {
1195 cifs_put_tlink(tlink);
1196 return -EOPNOTSUPP;
1197 }
1198
1199 pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
1200 if (IS_ERR(pntsd)) {
1201 rc = PTR_ERR(pntsd);
1202 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1203 cifs_put_tlink(tlink);
1204 return rc;
1205 }
1206
1207
1208
1209
1210
1211
1212
1213 secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1214 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1215 if (!pnntsd) {
1216 kfree(pntsd);
1217 cifs_put_tlink(tlink);
1218 return -ENOMEM;
1219 }
1220
1221 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1222 &aclflag);
1223
1224 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1225
1226 if (ops->set_acl == NULL)
1227 rc = -EOPNOTSUPP;
1228
1229 if (!rc) {
1230
1231 rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
1232 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1233 }
1234 cifs_put_tlink(tlink);
1235
1236 kfree(pnntsd);
1237 kfree(pntsd);
1238 return rc;
1239}
1240