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"
36 /* security id for everyone/world system group */
37 static const struct cifs_sid sid_everyone = {
38 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
39 /* security id for Authenticated Users system group */
40 static const struct cifs_sid sid_authusers = {
41 1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
43 /* S-1-22-1 Unmapped Unix users */
44 static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
45 {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
47 /* S-1-22-2 Unmapped Unix groups */
48 static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
49 {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
52 * See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
55 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
57 /* S-1-5-88-1 Unix uid */
58 static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
60 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
62 /* S-1-5-88-2 Unix gid */
63 static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
65 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
67 /* S-1-5-88-3 Unix mode */
68 static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
70 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
72 static const struct cred *root_cred;
75 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
80 * If the payload is less than or equal to the size of a pointer, then
81 * an allocation here is wasteful. Just copy the data directly to the
82 * payload.value union member instead.
84 * With this however, you must check the datalen before trying to
85 * dereference payload.data!
87 if (prep->datalen <= sizeof(key->payload)) {
88 key->payload.data[0] = NULL;
89 memcpy(&key->payload, prep->data, prep->datalen);
91 payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
94 key->payload.data[0] = payload;
97 key->datalen = prep->datalen;
102 cifs_idmap_key_destroy(struct key *key)
104 if (key->datalen > sizeof(key->payload))
105 kfree(key->payload.data[0]);
108 static struct key_type cifs_idmap_key_type = {
109 .name = "cifs.idmap",
110 .instantiate = cifs_idmap_key_instantiate,
111 .destroy = cifs_idmap_key_destroy,
112 .describe = user_describe,
116 sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
120 char *sidstr, *strptr;
121 unsigned long long id_auth_val;
123 /* 3 bytes for prefix */
124 sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
125 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
131 len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
135 /* The authority field is a single 48-bit number */
136 id_auth_val = (unsigned long long)sidptr->authority[5];
137 id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
138 id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
139 id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
140 id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
141 id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
144 * MS-DTYP states that if the authority is >= 2^32, then it should be
145 * expressed as a hex value.
147 if (id_auth_val <= UINT_MAX)
148 len = sprintf(strptr, "-%llu", id_auth_val);
150 len = sprintf(strptr, "-0x%llx", id_auth_val);
154 for (i = 0; i < sidptr->num_subauth; ++i) {
155 saval = le32_to_cpu(sidptr->sub_auth[i]);
156 len = sprintf(strptr, "-%u", saval);
164 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
165 * the same returns zero, if they do not match returns non-zero.
168 compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
171 int num_subauth, num_sat, num_saw;
173 if ((!ctsid) || (!cwsid))
176 /* compare the revision */
177 if (ctsid->revision != cwsid->revision) {
178 if (ctsid->revision > cwsid->revision)
184 /* compare all of the six auth values */
185 for (i = 0; i < NUM_AUTHS; ++i) {
186 if (ctsid->authority[i] != cwsid->authority[i]) {
187 if (ctsid->authority[i] > cwsid->authority[i])
194 /* compare all of the subauth values if any */
195 num_sat = ctsid->num_subauth;
196 num_saw = cwsid->num_subauth;
197 num_subauth = num_sat < num_saw ? num_sat : num_saw;
199 for (i = 0; i < num_subauth; ++i) {
200 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
201 if (le32_to_cpu(ctsid->sub_auth[i]) >
202 le32_to_cpu(cwsid->sub_auth[i]))
210 return 0; /* sids compare/match */
214 is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
218 const struct cifs_sid *pwell_known_sid;
220 if (!psid || (puid == NULL))
223 num_subauth = psid->num_subauth;
225 /* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
226 if (num_subauth == 2) {
228 pwell_known_sid = &sid_unix_groups;
230 pwell_known_sid = &sid_unix_users;
231 } else if (num_subauth == 3) {
233 pwell_known_sid = &sid_unix_NFS_groups;
235 pwell_known_sid = &sid_unix_NFS_users;
239 /* compare the revision */
240 if (psid->revision != pwell_known_sid->revision)
243 /* compare all of the six auth values */
244 for (i = 0; i < NUM_AUTHS; ++i) {
245 if (psid->authority[i] != pwell_known_sid->authority[i]) {
246 cifs_dbg(FYI, "auth %d did not match\n", i);
251 if (num_subauth == 2) {
252 if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
255 *puid = le32_to_cpu(psid->sub_auth[1]);
256 } else /* 3 subauths, ie Windows/Mac style */ {
257 *puid = le32_to_cpu(psid->sub_auth[0]);
258 if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
259 (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
262 *puid = le32_to_cpu(psid->sub_auth[2]);
265 cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
266 return true; /* well known sid found, uid returned */
270 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
274 dst->revision = src->revision;
275 dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
276 for (i = 0; i < NUM_AUTHS; ++i)
277 dst->authority[i] = src->authority[i];
278 for (i = 0; i < dst->num_subauth; ++i)
279 dst->sub_auth[i] = src->sub_auth[i];
283 id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
287 struct cifs_sid *ksid;
288 unsigned int ksid_size;
289 char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
290 const struct cred *saved_cred;
292 rc = snprintf(desc, sizeof(desc), "%ci:%u",
293 sidtype == SIDOWNER ? 'o' : 'g', cid);
294 if (rc >= sizeof(desc))
298 saved_cred = override_creds(root_cred);
299 sidkey = request_key(&cifs_idmap_key_type, desc, "");
300 if (IS_ERR(sidkey)) {
302 cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
303 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
304 goto out_revert_creds;
305 } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
307 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
308 __func__, sidkey->datalen);
313 * A sid is usually too large to be embedded in payload.value, but if
314 * there are no subauthorities and the host has 8-byte pointers, then
317 ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
318 (struct cifs_sid *)&sidkey->payload :
319 (struct cifs_sid *)sidkey->payload.data[0];
321 ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
322 if (ksid_size > sidkey->datalen) {
324 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
325 __func__, sidkey->datalen, ksid_size);
329 cifs_copy_sid(ssid, ksid);
333 revert_creds(saved_cred);
337 key_invalidate(sidkey);
342 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
343 struct cifs_fattr *fattr, uint sidtype)
348 const struct cred *saved_cred;
349 kuid_t fuid = cifs_sb->mnt_uid;
350 kgid_t fgid = cifs_sb->mnt_gid;
353 * If we have too many subauthorities, then something is really wrong.
354 * Just return an error.
356 if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
357 cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
358 __func__, psid->num_subauth);
362 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) {
366 if (sidtype != SIDOWNER)
371 if (is_well_known_sid(psid, &unix_id, is_group) == false)
372 goto try_upcall_to_get_id;
379 gid = make_kgid(&init_user_ns, id);
380 if (gid_valid(gid)) {
389 uid = make_kuid(&init_user_ns, id);
390 if (uid_valid(uid)) {
395 /* If unable to find uid/gid easily from SID try via upcall */
398 try_upcall_to_get_id:
399 sidstr = sid_to_key_str(psid, sidtype);
403 saved_cred = override_creds(root_cred);
404 sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
405 if (IS_ERR(sidkey)) {
407 cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
408 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
409 goto out_revert_creds;
413 * FIXME: Here we assume that uid_t and gid_t are same size. It's
414 * probably a safe assumption but might be better to check based on
417 BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
418 if (sidkey->datalen != sizeof(uid_t)) {
420 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
421 __func__, sidkey->datalen);
422 key_invalidate(sidkey);
426 if (sidtype == SIDOWNER) {
429 memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
430 uid = make_kuid(&init_user_ns, id);
436 memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
437 gid = make_kgid(&init_user_ns, id);
445 revert_creds(saved_cred);
449 * Note that we return 0 here unconditionally. If the mapping
450 * fails then we just fall back to using the mnt_uid/mnt_gid.
453 if (sidtype == SIDOWNER)
454 fattr->cf_uid = fuid;
456 fattr->cf_gid = fgid;
461 init_cifs_idmap(void)
467 cifs_dbg(FYI, "Registering the %s key type\n",
468 cifs_idmap_key_type.name);
470 /* create an override credential set with a special thread keyring in
471 * which requests are cached
473 * this is used to prevent malicious redirections from being installed
476 cred = prepare_kernel_cred(NULL);
480 keyring = keyring_alloc(".cifs_idmap",
481 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
482 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
483 KEY_USR_VIEW | KEY_USR_READ,
484 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
485 if (IS_ERR(keyring)) {
486 ret = PTR_ERR(keyring);
487 goto failed_put_cred;
490 ret = register_key_type(&cifs_idmap_key_type);
494 /* instruct request_key() to use this special keyring as a cache for
495 * the results it looks up */
496 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
497 cred->thread_keyring = keyring;
498 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
501 cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
512 exit_cifs_idmap(void)
514 key_revoke(root_cred->thread_keyring);
515 unregister_key_type(&cifs_idmap_key_type);
517 cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
520 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
521 static void copy_sec_desc(const struct cifs_ntsd *pntsd,
522 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
524 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
525 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
527 /* copy security descriptor control portion */
528 pnntsd->revision = pntsd->revision;
529 pnntsd->type = pntsd->type;
530 pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
531 pnntsd->sacloffset = 0;
532 pnntsd->osidoffset = cpu_to_le32(sidsoffset);
533 pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
536 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
537 le32_to_cpu(pntsd->osidoffset));
538 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
539 cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
542 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
543 le32_to_cpu(pntsd->gsidoffset));
544 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
545 sizeof(struct cifs_sid));
546 cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
553 change posix mode to reflect permissions
554 pmode is the existing mode (we only want to overwrite part of this
555 bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
557 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
558 umode_t *pbits_to_set)
560 __u32 flags = le32_to_cpu(ace_flags);
561 /* the order of ACEs is important. The canonical order is to begin with
562 DENY entries followed by ALLOW, otherwise an allow entry could be
563 encountered first, making the subsequent deny entry like "dead code"
564 which would be superflous since Windows stops when a match is made
565 for the operation you are trying to perform for your user */
567 /* For deny ACEs we change the mask so that subsequent allow access
568 control entries do not turn on the bits we are denying */
569 if (type == ACCESS_DENIED) {
570 if (flags & GENERIC_ALL)
571 *pbits_to_set &= ~S_IRWXUGO;
573 if ((flags & GENERIC_WRITE) ||
574 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
575 *pbits_to_set &= ~S_IWUGO;
576 if ((flags & GENERIC_READ) ||
577 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
578 *pbits_to_set &= ~S_IRUGO;
579 if ((flags & GENERIC_EXECUTE) ||
580 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
581 *pbits_to_set &= ~S_IXUGO;
583 } else if (type != ACCESS_ALLOWED) {
584 cifs_dbg(VFS, "unknown access control type %d\n", type);
587 /* else ACCESS_ALLOWED type */
589 if (flags & GENERIC_ALL) {
590 *pmode |= (S_IRWXUGO & (*pbits_to_set));
591 cifs_dbg(NOISY, "all perms\n");
594 if ((flags & GENERIC_WRITE) ||
595 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
596 *pmode |= (S_IWUGO & (*pbits_to_set));
597 if ((flags & GENERIC_READ) ||
598 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
599 *pmode |= (S_IRUGO & (*pbits_to_set));
600 if ((flags & GENERIC_EXECUTE) ||
601 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
602 *pmode |= (S_IXUGO & (*pbits_to_set));
604 cifs_dbg(NOISY, "access flags 0x%x mode now 0x%x\n", flags, *pmode);
609 Generate access flags to reflect permissions mode is the existing mode.
610 This function is called for every ACE in the DACL whose SID matches
611 with either owner or group or everyone.
614 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
617 /* reset access mask */
620 /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
623 /* check for R/W/X UGO since we do not know whose flags
624 is this but we have cleared all the bits sans RWX for
625 either user or group or other as per bits_to_use */
627 *pace_flags |= SET_FILE_READ_RIGHTS;
629 *pace_flags |= SET_FILE_WRITE_RIGHTS;
631 *pace_flags |= SET_FILE_EXEC_RIGHTS;
633 cifs_dbg(NOISY, "mode: 0x%x, access flags now 0x%x\n",
638 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
639 const struct cifs_sid *psid, __u64 nmode, umode_t bits)
643 __u32 access_req = 0;
645 pntace->type = ACCESS_ALLOWED;
647 mode_to_access_flags(nmode, bits, &access_req);
649 access_req = SET_MINIMUM_RIGHTS;
650 pntace->access_req = cpu_to_le32(access_req);
652 pntace->sid.revision = psid->revision;
653 pntace->sid.num_subauth = psid->num_subauth;
654 for (i = 0; i < NUM_AUTHS; i++)
655 pntace->sid.authority[i] = psid->authority[i];
656 for (i = 0; i < psid->num_subauth; i++)
657 pntace->sid.sub_auth[i] = psid->sub_auth[i];
659 size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
660 pntace->size = cpu_to_le16(size);
666 #ifdef CONFIG_CIFS_DEBUG2
667 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
671 /* validate that we do not go past end of acl */
673 if (le16_to_cpu(pace->size) < 16) {
674 cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
678 if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
679 cifs_dbg(VFS, "ACL too small to parse ACE\n");
683 num_subauth = pace->sid.num_subauth;
686 cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
687 pace->sid.revision, pace->sid.num_subauth, pace->type,
688 pace->flags, le16_to_cpu(pace->size));
689 for (i = 0; i < num_subauth; ++i) {
690 cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
691 i, le32_to_cpu(pace->sid.sub_auth[i]));
694 /* BB add length check to make sure that we do not have huge
695 num auths and therefore go off the end */
702 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
703 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
704 struct cifs_fattr *fattr, bool mode_from_special_sid)
710 struct cifs_ace **ppace;
712 /* BB need to add parm so we can store the SID BB */
715 /* no DACL in the security descriptor, set
716 all the permissions for user/group/other */
717 fattr->cf_mode |= S_IRWXUGO;
721 /* validate that we do not go past end of acl */
722 if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
723 cifs_dbg(VFS, "ACL too small to parse DACL\n");
727 cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
728 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
729 le32_to_cpu(pdacl->num_aces));
731 /* reset rwx permissions for user/group/other.
732 Also, if num_aces is 0 i.e. DACL has no ACEs,
733 user/group/other have no permissions */
734 fattr->cf_mode &= ~(S_IRWXUGO);
736 acl_base = (char *)pdacl;
737 acl_size = sizeof(struct cifs_acl);
739 num_aces = le32_to_cpu(pdacl->num_aces);
741 umode_t user_mask = S_IRWXU;
742 umode_t group_mask = S_IRWXG;
743 umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
745 if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
747 ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
752 for (i = 0; i < num_aces; ++i) {
753 ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
754 #ifdef CONFIG_CIFS_DEBUG2
755 dump_ace(ppace[i], end_of_acl);
757 if (mode_from_special_sid &&
758 (compare_sids(&(ppace[i]->sid),
759 &sid_unix_NFS_mode) == 0)) {
761 * Full permissions are:
762 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
763 * S_IRWXU | S_IRWXG | S_IRWXO
765 fattr->cf_mode &= ~07777;
767 le32_to_cpu(ppace[i]->sid.sub_auth[2]);
769 } else if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
770 access_flags_to_mode(ppace[i]->access_req,
774 else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
775 access_flags_to_mode(ppace[i]->access_req,
779 else if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
780 access_flags_to_mode(ppace[i]->access_req,
784 else if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
785 access_flags_to_mode(ppace[i]->access_req,
791 /* memcpy((void *)(&(cifscred->aces[i])),
793 sizeof(struct cifs_ace)); */
795 acl_base = (char *)ppace[i];
796 acl_size = le16_to_cpu(ppace[i]->size);
806 * Fill in the special SID based on the mode. See
807 * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
809 unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
812 unsigned int ace_size = 28;
814 pntace->type = ACCESS_DENIED_ACE_TYPE;
816 pntace->access_req = 0;
817 pntace->sid.num_subauth = 3;
818 pntace->sid.revision = 1;
819 for (i = 0; i < NUM_AUTHS; i++)
820 pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
822 pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
823 pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
824 pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
826 /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
827 pntace->size = cpu_to_le16(ace_size);
831 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
832 struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
836 struct cifs_acl *pnndacl;
838 pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
841 struct cifs_ace *pntace =
842 (struct cifs_ace *)((char *)pnndacl + size);
844 size += setup_special_mode_ACE(pntace, nmode);
848 size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
849 pownersid, nmode, S_IRWXU);
851 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
852 pgrpsid, nmode, S_IRWXG);
854 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
855 &sid_everyone, nmode, S_IRWXO);
858 pndacl->num_aces = cpu_to_le32(num_aces);
859 pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
865 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
867 /* BB need to add parm so we can store the SID BB */
869 /* validate that we do not go past end of ACL - sid must be at least 8
870 bytes long (assuming no sub-auths - e.g. the null SID */
871 if (end_of_acl < (char *)psid + 8) {
872 cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
876 #ifdef CONFIG_CIFS_DEBUG2
877 if (psid->num_subauth) {
879 cifs_dbg(FYI, "SID revision %d num_auth %d\n",
880 psid->revision, psid->num_subauth);
882 for (i = 0; i < psid->num_subauth; i++) {
883 cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
884 i, le32_to_cpu(psid->sub_auth[i]));
887 /* BB add length check to make sure that we do not have huge
888 num auths and therefore go off the end */
889 cifs_dbg(FYI, "RID 0x%x\n",
890 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
898 /* Convert CIFS ACL to POSIX form */
899 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
900 struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
901 bool get_mode_from_special_sid)
904 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
905 struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
906 char *end_of_acl = ((char *)pntsd) + acl_len;
912 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
913 le32_to_cpu(pntsd->osidoffset));
914 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
915 le32_to_cpu(pntsd->gsidoffset));
916 dacloffset = le32_to_cpu(pntsd->dacloffset);
917 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
918 cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
919 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
920 le32_to_cpu(pntsd->gsidoffset),
921 le32_to_cpu(pntsd->sacloffset), dacloffset);
922 /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
923 rc = parse_sid(owner_sid_ptr, end_of_acl);
925 cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
928 rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
930 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
935 rc = parse_sid(group_sid_ptr, end_of_acl);
937 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
941 rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
943 cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
949 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
950 group_sid_ptr, fattr, get_mode_from_special_sid);
952 cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
957 /* Convert permission bits from mode to equivalent CIFS ACL */
958 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
959 __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid,
960 bool mode_from_sid, int *aclflag)
966 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
967 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
968 struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */
969 struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
971 if (nmode != NO_CHANGE_64) { /* chmod */
972 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
973 le32_to_cpu(pntsd->osidoffset));
974 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
975 le32_to_cpu(pntsd->gsidoffset));
976 dacloffset = le32_to_cpu(pntsd->dacloffset);
977 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
978 ndacloffset = sizeof(struct cifs_ntsd);
979 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
980 ndacl_ptr->revision = dacl_ptr->revision;
982 ndacl_ptr->num_aces = 0;
984 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
985 nmode, mode_from_sid);
986 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
987 /* copy sec desc control portion & owner and group sids */
988 copy_sec_desc(pntsd, pnntsd, sidsoffset);
989 *aclflag = CIFS_ACL_DACL;
991 memcpy(pnntsd, pntsd, secdesclen);
992 if (uid_valid(uid)) { /* chown */
994 owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
995 le32_to_cpu(pnntsd->osidoffset));
996 nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1000 id = from_kuid(&init_user_ns, uid);
1001 rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1003 cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1005 kfree(nowner_sid_ptr);
1008 cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
1009 kfree(nowner_sid_ptr);
1010 *aclflag = CIFS_ACL_OWNER;
1012 if (gid_valid(gid)) { /* chgrp */
1014 group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1015 le32_to_cpu(pnntsd->gsidoffset));
1016 ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1018 if (!ngroup_sid_ptr)
1020 id = from_kgid(&init_user_ns, gid);
1021 rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1023 cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1025 kfree(ngroup_sid_ptr);
1028 cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
1029 kfree(ngroup_sid_ptr);
1030 *aclflag = CIFS_ACL_GROUP;
1037 struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1038 const struct cifs_fid *cifsfid, u32 *pacllen)
1040 struct cifs_ntsd *pntsd = NULL;
1043 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1046 return ERR_CAST(tlink);
1049 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1053 cifs_put_tlink(tlink);
1055 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1061 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1062 const char *path, u32 *pacllen)
1064 struct cifs_ntsd *pntsd = NULL;
1067 int rc, create_options = 0;
1068 struct cifs_tcon *tcon;
1069 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1070 struct cifs_fid fid;
1071 struct cifs_open_parms oparms;
1074 return ERR_CAST(tlink);
1076 tcon = tlink_tcon(tlink);
1079 if (backup_cred(cifs_sb))
1080 create_options |= CREATE_OPEN_BACKUP_INTENT;
1083 oparms.cifs_sb = cifs_sb;
1084 oparms.desired_access = READ_CONTROL;
1085 oparms.create_options = create_options;
1086 oparms.disposition = FILE_OPEN;
1089 oparms.reconnect = false;
1091 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1093 rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1094 CIFSSMBClose(xid, tcon, fid.netfid);
1097 cifs_put_tlink(tlink);
1100 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1106 /* Retrieve an ACL from the server */
1107 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1108 struct inode *inode, const char *path,
1111 struct cifs_ntsd *pntsd = NULL;
1112 struct cifsFileInfo *open_file = NULL;
1115 open_file = find_readable_file(CIFS_I(inode), true);
1117 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1119 pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
1120 cifsFileInfo_put(open_file);
1124 /* Set an ACL on the server */
1125 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1126 struct inode *inode, const char *path, int aclflag)
1130 int rc, access_flags, create_options = 0;
1131 struct cifs_tcon *tcon;
1132 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1133 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1134 struct cifs_fid fid;
1135 struct cifs_open_parms oparms;
1138 return PTR_ERR(tlink);
1140 tcon = tlink_tcon(tlink);
1143 if (backup_cred(cifs_sb))
1144 create_options |= CREATE_OPEN_BACKUP_INTENT;
1146 if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1147 access_flags = WRITE_OWNER;
1149 access_flags = WRITE_DAC;
1152 oparms.cifs_sb = cifs_sb;
1153 oparms.desired_access = access_flags;
1154 oparms.create_options = create_options;
1155 oparms.disposition = FILE_OPEN;
1158 oparms.reconnect = false;
1160 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1162 cifs_dbg(VFS, "Unable to open file to set ACL\n");
1166 rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1167 cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1169 CIFSSMBClose(xid, tcon, fid.netfid);
1172 cifs_put_tlink(tlink);
1176 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1178 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1179 struct inode *inode, bool mode_from_special_sid,
1180 const char *path, const struct cifs_fid *pfid)
1182 struct cifs_ntsd *pntsd = NULL;
1185 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1186 struct smb_version_operations *ops;
1188 cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1191 return PTR_ERR(tlink);
1193 ops = tlink_tcon(tlink)->ses->server->ops;
1195 if (pfid && (ops->get_acl_by_fid))
1196 pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
1197 else if (ops->get_acl)
1198 pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
1200 cifs_put_tlink(tlink);
1203 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1204 if (IS_ERR(pntsd)) {
1205 rc = PTR_ERR(pntsd);
1206 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1207 } else if (mode_from_special_sid) {
1208 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1210 /* get approximated mode from ACL */
1211 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1214 cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1217 cifs_put_tlink(tlink);
1222 /* Convert mode bits to an ACL so we can update the ACL on the server */
1224 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1225 kuid_t uid, kgid_t gid)
1228 int aclflag = CIFS_ACL_DACL; /* default flag to set */
1229 __u32 secdesclen = 0;
1230 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1231 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1232 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1233 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1234 struct smb_version_operations *ops;
1238 return PTR_ERR(tlink);
1240 ops = tlink_tcon(tlink)->ses->server->ops;
1242 cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1244 /* Get the security descriptor */
1246 if (ops->get_acl == NULL) {
1247 cifs_put_tlink(tlink);
1251 pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
1252 if (IS_ERR(pntsd)) {
1253 rc = PTR_ERR(pntsd);
1254 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1255 cifs_put_tlink(tlink);
1260 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1261 * as chmod disables ACEs and set the security descriptor. Allocate
1262 * memory for the smb header, set security descriptor request security
1263 * descriptor parameters, and secuirty descriptor itself
1265 secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1266 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1269 cifs_put_tlink(tlink);
1273 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1274 mode_from_sid = true;
1276 mode_from_sid = false;
1278 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1279 mode_from_sid, &aclflag);
1281 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1283 if (ops->set_acl == NULL)
1287 /* Set the security descriptor */
1288 rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
1289 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1291 cifs_put_tlink(tlink);