4 * Copyright (C) International Business Machines Corp., 2007,2008
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for mapping CIFS/NTFS ACLs
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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>
33 #include "cifsproto.h"
34 #include "cifs_debug.h"
37 static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
38 {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
39 {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
40 {{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"},
41 {{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(18), 0, 0, 0, 0} }, "sys"},
42 {{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(544), 0, 0, 0} }, "root"},
43 {{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(545), 0, 0, 0} }, "users"},
44 {{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(546), 0, 0, 0} }, "guest"} }
48 /* security id for everyone/world system group */
49 static const struct cifs_sid sid_everyone = {
50 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
51 /* security id for Authenticated Users system group */
52 static const struct cifs_sid sid_authusers = {
53 1, 1, {0, 0, 0, 0, 0, 5}, {11} };
55 static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
57 const struct cred *root_cred;
60 shrink_idmap_tree(struct rb_root *root, int nr_to_scan, int *nr_rem,
65 struct cifs_sid_id *psidid;
67 node = rb_first(root);
71 psidid = rb_entry(tmp, struct cifs_sid_id, rbnode);
72 if (nr_to_scan == 0 || *nr_del == nr_to_scan)
75 if (time_after(jiffies, psidid->time + SID_MAP_EXPIRE)
76 && psidid->refcount == 0) {
86 * Run idmap cache shrinker.
89 cifs_idmap_shrinker(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask)
96 spin_lock(&siduidlock);
97 shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
98 spin_unlock(&siduidlock);
101 spin_lock(&sidgidlock);
102 shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
103 spin_unlock(&sidgidlock);
108 static struct shrinker cifs_shrinker = {
109 .shrink = cifs_idmap_shrinker,
110 .seeks = DEFAULT_SEEKS,
114 cifs_idmap_key_instantiate(struct key *key, const void *data, size_t datalen)
118 payload = kmalloc(datalen, GFP_KERNEL);
122 memcpy(payload, data, datalen);
123 key->payload.data = payload;
128 cifs_idmap_key_destroy(struct key *key)
130 kfree(key->payload.data);
133 struct key_type cifs_idmap_key_type = {
134 .name = "cifs.cifs_idmap",
135 .instantiate = cifs_idmap_key_instantiate,
136 .destroy = cifs_idmap_key_destroy,
137 .describe = user_describe,
142 sid_to_str(struct cifs_sid *sidptr, char *sidstr)
150 sprintf(strptr, "%s", "S");
151 strptr = sidstr + strlen(sidstr);
153 sprintf(strptr, "-%d", sidptr->revision);
154 strptr = sidstr + strlen(sidstr);
156 for (i = 0; i < 6; ++i) {
157 if (sidptr->authority[i]) {
158 sprintf(strptr, "-%d", sidptr->authority[i]);
159 strptr = sidstr + strlen(sidstr);
163 for (i = 0; i < sidptr->num_subauth; ++i) {
164 saval = le32_to_cpu(sidptr->sub_auth[i]);
165 sprintf(strptr, "-%ld", saval);
166 strptr = sidstr + strlen(sidstr);
171 id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
172 struct cifs_sid_id **psidid, char *typestr)
176 struct rb_node *node = root->rb_node;
177 struct rb_node *parent = NULL;
178 struct rb_node **linkto = &(root->rb_node);
179 struct cifs_sid_id *lsidid;
182 lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
184 rc = compare_sids(sidptr, &((lsidid)->sid));
186 linkto = &(node->rb_left);
187 node = node->rb_left;
189 linkto = &(node->rb_right);
190 node = node->rb_right;
194 memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid));
195 (*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
196 (*psidid)->refcount = 0;
198 sprintf((*psidid)->sidstr, "%s", typestr);
199 strptr = (*psidid)->sidstr + strlen((*psidid)->sidstr);
200 sid_to_str(&(*psidid)->sid, strptr);
202 clear_bit(SID_ID_PENDING, &(*psidid)->state);
203 clear_bit(SID_ID_MAPPED, &(*psidid)->state);
205 rb_link_node(&(*psidid)->rbnode, parent, linkto);
206 rb_insert_color(&(*psidid)->rbnode, root);
209 static struct cifs_sid_id *
210 id_rb_search(struct rb_root *root, struct cifs_sid *sidptr)
213 struct rb_node *node = root->rb_node;
214 struct rb_node *parent = NULL;
215 struct rb_node **linkto = &(root->rb_node);
216 struct cifs_sid_id *lsidid;
219 lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
221 rc = compare_sids(sidptr, &((lsidid)->sid));
223 linkto = &(node->rb_left);
224 node = node->rb_left;
226 linkto = &(node->rb_right);
227 node = node->rb_right;
228 } else /* node found */
236 sidid_pending_wait(void *unused)
239 return signal_pending(current) ? -ERESTARTSYS : 0;
243 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
244 struct cifs_fattr *fattr, uint sidtype)
249 const struct cred *saved_cred;
250 struct cifs_sid_id *psidid, *npsidid;
251 struct rb_root *cidtree;
254 if (sidtype == SIDOWNER) {
255 cid = cifs_sb->mnt_uid; /* default uid, in case upcall fails */
256 cidlock = &siduidlock;
258 } else if (sidtype == SIDGROUP) {
259 cid = cifs_sb->mnt_gid; /* default gid, in case upcall fails */
260 cidlock = &sidgidlock;
266 psidid = id_rb_search(cidtree, psid);
268 if (!psidid) { /* node does not exist, allocate one & attempt adding */
269 spin_unlock(cidlock);
270 npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL);
274 npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL);
275 if (!npsidid->sidstr) {
281 psidid = id_rb_search(cidtree, psid);
282 if (psidid) { /* node happened to get inserted meanwhile */
284 spin_unlock(cidlock);
285 kfree(npsidid->sidstr);
289 id_rb_insert(cidtree, psid, &psidid,
290 sidtype == SIDOWNER ? "os:" : "gs:");
292 spin_unlock(cidlock);
296 spin_unlock(cidlock);
300 * If we are here, it is safe to access psidid and its fields
301 * since a reference was taken earlier while holding the spinlock.
302 * A reference on the node is put without holding the spinlock
303 * and it is OK to do so in this case, shrinker will not erase
304 * this node until all references are put and we do not access
305 * any fields of the node after a reference is put .
307 if (test_bit(SID_ID_MAPPED, &psidid->state)) {
309 psidid->time = jiffies; /* update ts for accessing */
313 if (time_after(psidid->time + SID_MAP_RETRY, jiffies))
316 if (!test_and_set_bit(SID_ID_PENDING, &psidid->state)) {
317 saved_cred = override_creds(root_cred);
318 idkey = request_key(&cifs_idmap_key_type, psidid->sidstr, "");
320 cFYI(1, "%s: Can't map SID to an id", __func__);
322 cid = *(unsigned long *)idkey->payload.value;
324 set_bit(SID_ID_MAPPED, &psidid->state);
326 kfree(psidid->sidstr);
328 revert_creds(saved_cred);
329 psidid->time = jiffies; /* update ts for accessing */
330 clear_bit(SID_ID_PENDING, &psidid->state);
331 wake_up_bit(&psidid->state, SID_ID_PENDING);
333 rc = wait_on_bit(&psidid->state, SID_ID_PENDING,
334 sidid_pending_wait, TASK_INTERRUPTIBLE);
336 cFYI(1, "%s: sidid_pending_wait interrupted %d",
338 --psidid->refcount; /* decremented without spinlock */
341 if (test_bit(SID_ID_MAPPED, &psidid->state))
346 --psidid->refcount; /* decremented without spinlock */
347 if (sidtype == SIDOWNER)
356 init_cifs_idmap(void)
362 cFYI(1, "Registering the %s key type\n", cifs_idmap_key_type.name);
364 /* create an override credential set with a special thread keyring in
365 * which requests are cached
367 * this is used to prevent malicious redirections from being installed
370 cred = prepare_kernel_cred(NULL);
374 keyring = key_alloc(&key_type_keyring, ".cifs_idmap", 0, 0, cred,
375 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
376 KEY_USR_VIEW | KEY_USR_READ,
377 KEY_ALLOC_NOT_IN_QUOTA);
378 if (IS_ERR(keyring)) {
379 ret = PTR_ERR(keyring);
380 goto failed_put_cred;
383 ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL);
387 ret = register_key_type(&cifs_idmap_key_type);
391 /* instruct request_key() to use this special keyring as a cache for
392 * the results it looks up */
393 cred->thread_keyring = keyring;
394 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
397 spin_lock_init(&siduidlock);
399 spin_lock_init(&sidgidlock);
402 register_shrinker(&cifs_shrinker);
404 cFYI(1, "cifs idmap keyring: %d\n", key_serial(keyring));
415 exit_cifs_idmap(void)
417 key_revoke(root_cred->thread_keyring);
418 unregister_key_type(&cifs_idmap_key_type);
420 unregister_shrinker(&cifs_shrinker);
421 cFYI(1, "Unregistered %s key type\n", cifs_idmap_key_type.name);
425 cifs_destroy_idmaptrees(void)
427 struct rb_root *root;
428 struct rb_node *node;
431 spin_lock(&siduidlock);
432 while ((node = rb_first(root)))
433 rb_erase(node, root);
434 spin_unlock(&siduidlock);
437 spin_lock(&sidgidlock);
438 while ((node = rb_first(root)))
439 rb_erase(node, root);
440 spin_unlock(&sidgidlock);
443 int match_sid(struct cifs_sid *ctsid)
446 int num_subauth, num_sat, num_saw;
447 struct cifs_sid *cwsid;
452 for (i = 0; i < NUM_WK_SIDS; ++i) {
453 cwsid = &(wksidarr[i].cifssid);
455 /* compare the revision */
456 if (ctsid->revision != cwsid->revision)
459 /* compare all of the six auth values */
460 for (j = 0; j < 6; ++j) {
461 if (ctsid->authority[j] != cwsid->authority[j])
465 continue; /* all of the auth values did not match */
467 /* compare all of the subauth values if any */
468 num_sat = ctsid->num_subauth;
469 num_saw = cwsid->num_subauth;
470 num_subauth = num_sat < num_saw ? num_sat : num_saw;
472 for (j = 0; j < num_subauth; ++j) {
473 if (ctsid->sub_auth[j] != cwsid->sub_auth[j])
477 continue; /* all sub_auth values do not match */
480 cFYI(1, "matching sid: %s\n", wksidarr[i].sidname);
481 return 0; /* sids compare/match */
484 cFYI(1, "No matching sid");
488 /* if the two SIDs (roughly equivalent to a UUID for a user or group) are
489 the same returns 1, if they do not match returns 0 */
490 int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
493 int num_subauth, num_sat, num_saw;
495 if ((!ctsid) || (!cwsid))
498 /* compare the revision */
499 if (ctsid->revision != cwsid->revision) {
500 if (ctsid->revision > cwsid->revision)
506 /* compare all of the six auth values */
507 for (i = 0; i < 6; ++i) {
508 if (ctsid->authority[i] != cwsid->authority[i]) {
509 if (ctsid->authority[i] > cwsid->authority[i])
516 /* compare all of the subauth values if any */
517 num_sat = ctsid->num_subauth;
518 num_saw = cwsid->num_subauth;
519 num_subauth = num_sat < num_saw ? num_sat : num_saw;
521 for (i = 0; i < num_subauth; ++i) {
522 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
523 if (ctsid->sub_auth[i] > cwsid->sub_auth[i])
531 return 0; /* sids compare/match */
535 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
536 static void copy_sec_desc(const struct cifs_ntsd *pntsd,
537 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
541 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
542 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
544 /* copy security descriptor control portion */
545 pnntsd->revision = pntsd->revision;
546 pnntsd->type = pntsd->type;
547 pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
548 pnntsd->sacloffset = 0;
549 pnntsd->osidoffset = cpu_to_le32(sidsoffset);
550 pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
553 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
554 le32_to_cpu(pntsd->osidoffset));
555 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
557 nowner_sid_ptr->revision = owner_sid_ptr->revision;
558 nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
559 for (i = 0; i < 6; i++)
560 nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
561 for (i = 0; i < 5; i++)
562 nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
565 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
566 le32_to_cpu(pntsd->gsidoffset));
567 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
568 sizeof(struct cifs_sid));
570 ngroup_sid_ptr->revision = group_sid_ptr->revision;
571 ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
572 for (i = 0; i < 6; i++)
573 ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
574 for (i = 0; i < 5; i++)
575 ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
582 change posix mode to reflect permissions
583 pmode is the existing mode (we only want to overwrite part of this
584 bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
586 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
587 umode_t *pbits_to_set)
589 __u32 flags = le32_to_cpu(ace_flags);
590 /* the order of ACEs is important. The canonical order is to begin with
591 DENY entries followed by ALLOW, otherwise an allow entry could be
592 encountered first, making the subsequent deny entry like "dead code"
593 which would be superflous since Windows stops when a match is made
594 for the operation you are trying to perform for your user */
596 /* For deny ACEs we change the mask so that subsequent allow access
597 control entries do not turn on the bits we are denying */
598 if (type == ACCESS_DENIED) {
599 if (flags & GENERIC_ALL)
600 *pbits_to_set &= ~S_IRWXUGO;
602 if ((flags & GENERIC_WRITE) ||
603 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
604 *pbits_to_set &= ~S_IWUGO;
605 if ((flags & GENERIC_READ) ||
606 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
607 *pbits_to_set &= ~S_IRUGO;
608 if ((flags & GENERIC_EXECUTE) ||
609 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
610 *pbits_to_set &= ~S_IXUGO;
612 } else if (type != ACCESS_ALLOWED) {
613 cERROR(1, "unknown access control type %d", type);
616 /* else ACCESS_ALLOWED type */
618 if (flags & GENERIC_ALL) {
619 *pmode |= (S_IRWXUGO & (*pbits_to_set));
620 cFYI(DBG2, "all perms");
623 if ((flags & GENERIC_WRITE) ||
624 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
625 *pmode |= (S_IWUGO & (*pbits_to_set));
626 if ((flags & GENERIC_READ) ||
627 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
628 *pmode |= (S_IRUGO & (*pbits_to_set));
629 if ((flags & GENERIC_EXECUTE) ||
630 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
631 *pmode |= (S_IXUGO & (*pbits_to_set));
633 cFYI(DBG2, "access flags 0x%x mode now 0x%x", flags, *pmode);
638 Generate access flags to reflect permissions mode is the existing mode.
639 This function is called for every ACE in the DACL whose SID matches
640 with either owner or group or everyone.
643 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
646 /* reset access mask */
649 /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
652 /* check for R/W/X UGO since we do not know whose flags
653 is this but we have cleared all the bits sans RWX for
654 either user or group or other as per bits_to_use */
656 *pace_flags |= SET_FILE_READ_RIGHTS;
658 *pace_flags |= SET_FILE_WRITE_RIGHTS;
660 *pace_flags |= SET_FILE_EXEC_RIGHTS;
662 cFYI(DBG2, "mode: 0x%x, access flags now 0x%x", mode, *pace_flags);
666 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
667 const struct cifs_sid *psid, __u64 nmode, umode_t bits)
671 __u32 access_req = 0;
673 pntace->type = ACCESS_ALLOWED;
675 mode_to_access_flags(nmode, bits, &access_req);
677 access_req = SET_MINIMUM_RIGHTS;
678 pntace->access_req = cpu_to_le32(access_req);
680 pntace->sid.revision = psid->revision;
681 pntace->sid.num_subauth = psid->num_subauth;
682 for (i = 0; i < 6; i++)
683 pntace->sid.authority[i] = psid->authority[i];
684 for (i = 0; i < psid->num_subauth; i++)
685 pntace->sid.sub_auth[i] = psid->sub_auth[i];
687 size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
688 pntace->size = cpu_to_le16(size);
694 #ifdef CONFIG_CIFS_DEBUG2
695 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
699 /* validate that we do not go past end of acl */
701 if (le16_to_cpu(pace->size) < 16) {
702 cERROR(1, "ACE too small %d", le16_to_cpu(pace->size));
706 if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
707 cERROR(1, "ACL too small to parse ACE");
711 num_subauth = pace->sid.num_subauth;
714 cFYI(1, "ACE revision %d num_auth %d type %d flags %d size %d",
715 pace->sid.revision, pace->sid.num_subauth, pace->type,
716 pace->flags, le16_to_cpu(pace->size));
717 for (i = 0; i < num_subauth; ++i) {
718 cFYI(1, "ACE sub_auth[%d]: 0x%x", i,
719 le32_to_cpu(pace->sid.sub_auth[i]));
722 /* BB add length check to make sure that we do not have huge
723 num auths and therefore go off the end */
731 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
732 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
733 struct cifs_fattr *fattr)
739 struct cifs_ace **ppace;
741 /* BB need to add parm so we can store the SID BB */
744 /* no DACL in the security descriptor, set
745 all the permissions for user/group/other */
746 fattr->cf_mode |= S_IRWXUGO;
750 /* validate that we do not go past end of acl */
751 if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
752 cERROR(1, "ACL too small to parse DACL");
756 cFYI(DBG2, "DACL revision %d size %d num aces %d",
757 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
758 le32_to_cpu(pdacl->num_aces));
760 /* reset rwx permissions for user/group/other.
761 Also, if num_aces is 0 i.e. DACL has no ACEs,
762 user/group/other have no permissions */
763 fattr->cf_mode &= ~(S_IRWXUGO);
765 acl_base = (char *)pdacl;
766 acl_size = sizeof(struct cifs_acl);
768 num_aces = le32_to_cpu(pdacl->num_aces);
770 umode_t user_mask = S_IRWXU;
771 umode_t group_mask = S_IRWXG;
772 umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
774 ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
777 cERROR(1, "DACL memory allocation error");
781 for (i = 0; i < num_aces; ++i) {
782 ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
783 #ifdef CONFIG_CIFS_DEBUG2
784 dump_ace(ppace[i], end_of_acl);
786 if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
787 access_flags_to_mode(ppace[i]->access_req,
791 if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
792 access_flags_to_mode(ppace[i]->access_req,
796 if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
797 access_flags_to_mode(ppace[i]->access_req,
801 if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
802 access_flags_to_mode(ppace[i]->access_req,
808 /* memcpy((void *)(&(cifscred->aces[i])),
810 sizeof(struct cifs_ace)); */
812 acl_base = (char *)ppace[i];
813 acl_size = le16_to_cpu(ppace[i]->size);
823 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
824 struct cifs_sid *pgrpsid, __u64 nmode)
827 struct cifs_acl *pnndacl;
829 pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
831 size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
832 pownersid, nmode, S_IRWXU);
833 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
834 pgrpsid, nmode, S_IRWXG);
835 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
836 &sid_everyone, nmode, S_IRWXO);
838 pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
839 pndacl->num_aces = cpu_to_le32(3);
845 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
847 /* BB need to add parm so we can store the SID BB */
849 /* validate that we do not go past end of ACL - sid must be at least 8
850 bytes long (assuming no sub-auths - e.g. the null SID */
851 if (end_of_acl < (char *)psid + 8) {
852 cERROR(1, "ACL too small to parse SID %p", psid);
856 if (psid->num_subauth) {
857 #ifdef CONFIG_CIFS_DEBUG2
859 cFYI(1, "SID revision %d num_auth %d",
860 psid->revision, psid->num_subauth);
862 for (i = 0; i < psid->num_subauth; i++) {
863 cFYI(1, "SID sub_auth[%d]: 0x%x ", i,
864 le32_to_cpu(psid->sub_auth[i]));
867 /* BB add length check to make sure that we do not have huge
868 num auths and therefore go off the end */
870 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
878 /* Convert CIFS ACL to POSIX form */
879 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
880 struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr)
883 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
884 struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
885 char *end_of_acl = ((char *)pntsd) + acl_len;
891 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
892 le32_to_cpu(pntsd->osidoffset));
893 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
894 le32_to_cpu(pntsd->gsidoffset));
895 dacloffset = le32_to_cpu(pntsd->dacloffset);
896 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
897 cFYI(DBG2, "revision %d type 0x%x ooffset 0x%x goffset 0x%x "
898 "sacloffset 0x%x dacloffset 0x%x",
899 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
900 le32_to_cpu(pntsd->gsidoffset),
901 le32_to_cpu(pntsd->sacloffset), dacloffset);
902 /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
903 rc = parse_sid(owner_sid_ptr, end_of_acl);
905 cFYI(1, "%s: Error %d parsing Owner SID", __func__, rc);
908 rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
910 cFYI(1, "%s: Error %d mapping Owner SID to uid", __func__, rc);
914 rc = parse_sid(group_sid_ptr, end_of_acl);
916 cFYI(1, "%s: Error %d mapping Owner SID to gid", __func__, rc);
919 rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
921 cFYI(1, "%s: Error %d mapping Group SID to gid", __func__, rc);
926 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
927 group_sid_ptr, fattr);
929 cFYI(1, "no ACL"); /* BB grant all or default perms? */
931 /* cifscred->uid = owner_sid_ptr->rid;
932 cifscred->gid = group_sid_ptr->rid;
933 memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr,
934 sizeof(struct cifs_sid));
935 memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
936 sizeof(struct cifs_sid)); */
942 /* Convert permission bits from mode to equivalent CIFS ACL */
943 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
944 struct inode *inode, __u64 nmode)
950 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
951 struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */
952 struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
954 if ((inode == NULL) || (pntsd == NULL) || (pnntsd == NULL))
957 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
958 le32_to_cpu(pntsd->osidoffset));
959 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
960 le32_to_cpu(pntsd->gsidoffset));
962 dacloffset = le32_to_cpu(pntsd->dacloffset);
963 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
965 ndacloffset = sizeof(struct cifs_ntsd);
966 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
967 ndacl_ptr->revision = dacl_ptr->revision;
969 ndacl_ptr->num_aces = 0;
971 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr, nmode);
973 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
975 /* copy security descriptor control portion and owner and group sid */
976 copy_sec_desc(pntsd, pnntsd, sidsoffset);
981 static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
982 __u16 fid, u32 *pacllen)
984 struct cifs_ntsd *pntsd = NULL;
986 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
989 return ERR_CAST(tlink);
992 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
995 cifs_put_tlink(tlink);
997 cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
1003 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1004 const char *path, u32 *pacllen)
1006 struct cifs_ntsd *pntsd = NULL;
1010 struct cifsTconInfo *tcon;
1011 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1014 return ERR_CAST(tlink);
1016 tcon = tlink_tcon(tlink);
1019 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
1020 &fid, &oplock, NULL, cifs_sb->local_nls,
1021 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1023 rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
1024 CIFSSMBClose(xid, tcon, fid);
1027 cifs_put_tlink(tlink);
1030 cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
1036 /* Retrieve an ACL from the server */
1037 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1038 struct inode *inode, const char *path,
1041 struct cifs_ntsd *pntsd = NULL;
1042 struct cifsFileInfo *open_file = NULL;
1045 open_file = find_readable_file(CIFS_I(inode), true);
1047 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1049 pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen);
1050 cifsFileInfo_put(open_file);
1054 static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid,
1055 struct cifs_ntsd *pnntsd, u32 acllen)
1058 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1061 return PTR_ERR(tlink);
1064 rc = CIFSSMBSetCIFSACL(xid, tlink_tcon(tlink), fid, pnntsd, acllen);
1066 cifs_put_tlink(tlink);
1068 cFYI(DBG2, "SetCIFSACL rc = %d", rc);
1072 static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
1073 struct cifs_ntsd *pnntsd, u32 acllen)
1078 struct cifsTconInfo *tcon;
1079 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1082 return PTR_ERR(tlink);
1084 tcon = tlink_tcon(tlink);
1087 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, 0,
1088 &fid, &oplock, NULL, cifs_sb->local_nls,
1089 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1091 cERROR(1, "Unable to open file to set ACL");
1095 rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen);
1096 cFYI(DBG2, "SetCIFSACL rc = %d", rc);
1098 CIFSSMBClose(xid, tcon, fid);
1101 cifs_put_tlink(tlink);
1105 /* Set an ACL on the server */
1106 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1107 struct inode *inode, const char *path)
1109 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1110 struct cifsFileInfo *open_file;
1113 cFYI(DBG2, "set ACL for %s from mode 0x%x", path, inode->i_mode);
1115 open_file = find_readable_file(CIFS_I(inode), true);
1117 return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen);
1119 rc = set_cifs_acl_by_fid(cifs_sb, open_file->netfid, pnntsd, acllen);
1120 cifsFileInfo_put(open_file);
1124 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
1126 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1127 struct inode *inode, const char *path, const __u16 *pfid)
1129 struct cifs_ntsd *pntsd = NULL;
1133 cFYI(DBG2, "converting ACL to mode for %s", path);
1136 pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
1138 pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
1140 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1141 if (IS_ERR(pntsd)) {
1142 rc = PTR_ERR(pntsd);
1143 cERROR(1, "%s: error %d getting sec desc", __func__, rc);
1145 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr);
1148 cERROR(1, "parse sec desc failed rc = %d", rc);
1154 /* Convert mode bits to an ACL so we can update the ACL on the server */
1155 int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode)
1158 __u32 secdesclen = 0;
1159 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1160 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1162 cFYI(DBG2, "set ACL from mode for %s", path);
1164 /* Get the security descriptor */
1165 pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
1167 /* Add three ACEs for owner, group, everyone getting rid of
1168 other ACEs as chmod disables ACEs and set the security descriptor */
1170 if (IS_ERR(pntsd)) {
1171 rc = PTR_ERR(pntsd);
1172 cERROR(1, "%s: error %d getting sec desc", __func__, rc);
1174 /* allocate memory for the smb header,
1175 set security descriptor request security descriptor
1176 parameters, and secuirty descriptor itself */
1178 secdesclen = secdesclen < DEFSECDESCLEN ?
1179 DEFSECDESCLEN : secdesclen;
1180 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1182 cERROR(1, "Unable to allocate security descriptor");
1187 rc = build_sec_desc(pntsd, pnntsd, inode, nmode);
1189 cFYI(DBG2, "build_sec_desc rc: %d", rc);
1192 /* Set the security descriptor */
1193 rc = set_cifs_acl(pnntsd, secdesclen, inode, path);
1194 cFYI(DBG2, "set_cifs_acl rc: %d", rc);