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}, {__constant_cpu_to_le32(11)} };
43 static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
45 static const struct cred *root_cred;
48 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
53 * If the payload is less than or equal to the size of a pointer, then
54 * an allocation here is wasteful. Just copy the data directly to the
55 * payload.value union member instead.
57 * With this however, you must check the datalen before trying to
58 * dereference payload.data!
60 if (prep->datalen <= sizeof(key->payload)) {
61 key->payload.value = 0;
62 memcpy(&key->payload.value, prep->data, prep->datalen);
63 key->datalen = prep->datalen;
66 payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
70 key->payload.data = payload;
71 key->datalen = prep->datalen;
76 cifs_idmap_key_destroy(struct key *key)
78 if (key->datalen > sizeof(key->payload))
79 kfree(key->payload.data);
82 static struct key_type cifs_idmap_key_type = {
84 .instantiate = cifs_idmap_key_instantiate,
85 .destroy = cifs_idmap_key_destroy,
86 .describe = user_describe,
91 sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
95 char *sidstr, *strptr;
96 unsigned long long id_auth_val;
98 /* 3 bytes for prefix */
99 sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
100 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
106 len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
110 /* The authority field is a single 48-bit number */
111 id_auth_val = (unsigned long long)sidptr->authority[5];
112 id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
113 id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
114 id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
115 id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
116 id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
119 * MS-DTYP states that if the authority is >= 2^32, then it should be
120 * expressed as a hex value.
122 if (id_auth_val <= UINT_MAX)
123 len = sprintf(strptr, "-%llu", id_auth_val);
125 len = sprintf(strptr, "-0x%llx", id_auth_val);
129 for (i = 0; i < sidptr->num_subauth; ++i) {
130 saval = le32_to_cpu(sidptr->sub_auth[i]);
131 len = sprintf(strptr, "-%u", saval);
139 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
140 * the same returns zero, if they do not match returns non-zero.
143 compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
146 int num_subauth, num_sat, num_saw;
148 if ((!ctsid) || (!cwsid))
151 /* compare the revision */
152 if (ctsid->revision != cwsid->revision) {
153 if (ctsid->revision > cwsid->revision)
159 /* compare all of the six auth values */
160 for (i = 0; i < NUM_AUTHS; ++i) {
161 if (ctsid->authority[i] != cwsid->authority[i]) {
162 if (ctsid->authority[i] > cwsid->authority[i])
169 /* compare all of the subauth values if any */
170 num_sat = ctsid->num_subauth;
171 num_saw = cwsid->num_subauth;
172 num_subauth = num_sat < num_saw ? num_sat : num_saw;
174 for (i = 0; i < num_subauth; ++i) {
175 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
176 if (le32_to_cpu(ctsid->sub_auth[i]) >
177 le32_to_cpu(cwsid->sub_auth[i]))
185 return 0; /* sids compare/match */
189 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
193 dst->revision = src->revision;
194 dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
195 for (i = 0; i < NUM_AUTHS; ++i)
196 dst->authority[i] = src->authority[i];
197 for (i = 0; i < dst->num_subauth; ++i)
198 dst->sub_auth[i] = src->sub_auth[i];
202 id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
206 struct cifs_sid *ksid;
207 unsigned int ksid_size;
208 char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
209 const struct cred *saved_cred;
211 rc = snprintf(desc, sizeof(desc), "%ci:%u",
212 sidtype == SIDOWNER ? 'o' : 'g', cid);
213 if (rc >= sizeof(desc))
217 saved_cred = override_creds(root_cred);
218 sidkey = request_key(&cifs_idmap_key_type, desc, "");
219 if (IS_ERR(sidkey)) {
221 cFYI(1, "%s: Can't map %cid %u to a SID", __func__,
222 sidtype == SIDOWNER ? 'u' : 'g', cid);
223 goto out_revert_creds;
224 } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
226 cFYI(1, "%s: Downcall contained malformed key "
227 "(datalen=%hu)", __func__, sidkey->datalen);
232 * A sid is usually too large to be embedded in payload.value, but if
233 * there are no subauthorities and the host has 8-byte pointers, then
236 ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
237 (struct cifs_sid *)&sidkey->payload.value :
238 (struct cifs_sid *)sidkey->payload.data;
240 ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
241 if (ksid_size > sidkey->datalen) {
243 cFYI(1, "%s: Downcall contained malformed key (datalen=%hu, "
244 "ksid_size=%u)", __func__, sidkey->datalen, ksid_size);
248 cifs_copy_sid(ssid, ksid);
252 revert_creds(saved_cred);
256 key_invalidate(sidkey);
261 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
262 struct cifs_fattr *fattr, uint sidtype)
267 const struct cred *saved_cred;
268 kuid_t fuid = cifs_sb->mnt_uid;
269 kgid_t fgid = cifs_sb->mnt_gid;
272 * If we have too many subauthorities, then something is really wrong.
273 * Just return an error.
275 if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
276 cFYI(1, "%s: %u subauthorities is too many!", __func__,
281 sidstr = sid_to_key_str(psid, sidtype);
285 saved_cred = override_creds(root_cred);
286 sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
287 if (IS_ERR(sidkey)) {
289 cFYI(1, "%s: Can't map SID %s to a %cid", __func__, sidstr,
290 sidtype == SIDOWNER ? 'u' : 'g');
291 goto out_revert_creds;
295 * FIXME: Here we assume that uid_t and gid_t are same size. It's
296 * probably a safe assumption but might be better to check based on
299 BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
300 if (sidkey->datalen != sizeof(uid_t)) {
302 cFYI(1, "%s: Downcall contained malformed key "
303 "(datalen=%hu)", __func__, sidkey->datalen);
304 key_invalidate(sidkey);
308 if (sidtype == SIDOWNER) {
311 memcpy(&id, &sidkey->payload.value, sizeof(uid_t));
312 uid = make_kuid(&init_user_ns, id);
318 memcpy(&id, &sidkey->payload.value, sizeof(gid_t));
319 gid = make_kgid(&init_user_ns, id);
327 revert_creds(saved_cred);
331 * Note that we return 0 here unconditionally. If the mapping
332 * fails then we just fall back to using the mnt_uid/mnt_gid.
334 if (sidtype == SIDOWNER)
335 fattr->cf_uid = fuid;
337 fattr->cf_gid = fgid;
342 init_cifs_idmap(void)
348 cFYI(1, "Registering the %s key type", cifs_idmap_key_type.name);
350 /* create an override credential set with a special thread keyring in
351 * which requests are cached
353 * this is used to prevent malicious redirections from being installed
356 cred = prepare_kernel_cred(NULL);
360 keyring = keyring_alloc(".cifs_idmap",
361 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
362 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
363 KEY_USR_VIEW | KEY_USR_READ,
364 KEY_ALLOC_NOT_IN_QUOTA, NULL);
365 if (IS_ERR(keyring)) {
366 ret = PTR_ERR(keyring);
367 goto failed_put_cred;
370 ret = register_key_type(&cifs_idmap_key_type);
374 /* instruct request_key() to use this special keyring as a cache for
375 * the results it looks up */
376 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
377 cred->thread_keyring = keyring;
378 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
381 cFYI(1, "cifs idmap keyring: %d", key_serial(keyring));
392 exit_cifs_idmap(void)
394 key_revoke(root_cred->thread_keyring);
395 unregister_key_type(&cifs_idmap_key_type);
397 cFYI(1, "Unregistered %s key type", cifs_idmap_key_type.name);
400 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
401 static void copy_sec_desc(const struct cifs_ntsd *pntsd,
402 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
404 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
405 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
407 /* copy security descriptor control portion */
408 pnntsd->revision = pntsd->revision;
409 pnntsd->type = pntsd->type;
410 pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
411 pnntsd->sacloffset = 0;
412 pnntsd->osidoffset = cpu_to_le32(sidsoffset);
413 pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
416 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
417 le32_to_cpu(pntsd->osidoffset));
418 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
419 cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
422 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
423 le32_to_cpu(pntsd->gsidoffset));
424 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
425 sizeof(struct cifs_sid));
426 cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
433 change posix mode to reflect permissions
434 pmode is the existing mode (we only want to overwrite part of this
435 bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
437 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
438 umode_t *pbits_to_set)
440 __u32 flags = le32_to_cpu(ace_flags);
441 /* the order of ACEs is important. The canonical order is to begin with
442 DENY entries followed by ALLOW, otherwise an allow entry could be
443 encountered first, making the subsequent deny entry like "dead code"
444 which would be superflous since Windows stops when a match is made
445 for the operation you are trying to perform for your user */
447 /* For deny ACEs we change the mask so that subsequent allow access
448 control entries do not turn on the bits we are denying */
449 if (type == ACCESS_DENIED) {
450 if (flags & GENERIC_ALL)
451 *pbits_to_set &= ~S_IRWXUGO;
453 if ((flags & GENERIC_WRITE) ||
454 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
455 *pbits_to_set &= ~S_IWUGO;
456 if ((flags & GENERIC_READ) ||
457 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
458 *pbits_to_set &= ~S_IRUGO;
459 if ((flags & GENERIC_EXECUTE) ||
460 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
461 *pbits_to_set &= ~S_IXUGO;
463 } else if (type != ACCESS_ALLOWED) {
464 cERROR(1, "unknown access control type %d", type);
467 /* else ACCESS_ALLOWED type */
469 if (flags & GENERIC_ALL) {
470 *pmode |= (S_IRWXUGO & (*pbits_to_set));
471 cFYI(DBG2, "all perms");
474 if ((flags & GENERIC_WRITE) ||
475 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
476 *pmode |= (S_IWUGO & (*pbits_to_set));
477 if ((flags & GENERIC_READ) ||
478 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
479 *pmode |= (S_IRUGO & (*pbits_to_set));
480 if ((flags & GENERIC_EXECUTE) ||
481 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
482 *pmode |= (S_IXUGO & (*pbits_to_set));
484 cFYI(DBG2, "access flags 0x%x mode now 0x%x", flags, *pmode);
489 Generate access flags to reflect permissions mode is the existing mode.
490 This function is called for every ACE in the DACL whose SID matches
491 with either owner or group or everyone.
494 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
497 /* reset access mask */
500 /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
503 /* check for R/W/X UGO since we do not know whose flags
504 is this but we have cleared all the bits sans RWX for
505 either user or group or other as per bits_to_use */
507 *pace_flags |= SET_FILE_READ_RIGHTS;
509 *pace_flags |= SET_FILE_WRITE_RIGHTS;
511 *pace_flags |= SET_FILE_EXEC_RIGHTS;
513 cFYI(DBG2, "mode: 0x%x, access flags now 0x%x", mode, *pace_flags);
517 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
518 const struct cifs_sid *psid, __u64 nmode, umode_t bits)
522 __u32 access_req = 0;
524 pntace->type = ACCESS_ALLOWED;
526 mode_to_access_flags(nmode, bits, &access_req);
528 access_req = SET_MINIMUM_RIGHTS;
529 pntace->access_req = cpu_to_le32(access_req);
531 pntace->sid.revision = psid->revision;
532 pntace->sid.num_subauth = psid->num_subauth;
533 for (i = 0; i < NUM_AUTHS; i++)
534 pntace->sid.authority[i] = psid->authority[i];
535 for (i = 0; i < psid->num_subauth; i++)
536 pntace->sid.sub_auth[i] = psid->sub_auth[i];
538 size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
539 pntace->size = cpu_to_le16(size);
545 #ifdef CONFIG_CIFS_DEBUG2
546 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
550 /* validate that we do not go past end of acl */
552 if (le16_to_cpu(pace->size) < 16) {
553 cERROR(1, "ACE too small %d", le16_to_cpu(pace->size));
557 if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
558 cERROR(1, "ACL too small to parse ACE");
562 num_subauth = pace->sid.num_subauth;
565 cFYI(1, "ACE revision %d num_auth %d type %d flags %d size %d",
566 pace->sid.revision, pace->sid.num_subauth, pace->type,
567 pace->flags, le16_to_cpu(pace->size));
568 for (i = 0; i < num_subauth; ++i) {
569 cFYI(1, "ACE sub_auth[%d]: 0x%x", i,
570 le32_to_cpu(pace->sid.sub_auth[i]));
573 /* BB add length check to make sure that we do not have huge
574 num auths and therefore go off the end */
582 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
583 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
584 struct cifs_fattr *fattr)
590 struct cifs_ace **ppace;
592 /* BB need to add parm so we can store the SID BB */
595 /* no DACL in the security descriptor, set
596 all the permissions for user/group/other */
597 fattr->cf_mode |= S_IRWXUGO;
601 /* validate that we do not go past end of acl */
602 if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
603 cERROR(1, "ACL too small to parse DACL");
607 cFYI(DBG2, "DACL revision %d size %d num aces %d",
608 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
609 le32_to_cpu(pdacl->num_aces));
611 /* reset rwx permissions for user/group/other.
612 Also, if num_aces is 0 i.e. DACL has no ACEs,
613 user/group/other have no permissions */
614 fattr->cf_mode &= ~(S_IRWXUGO);
616 acl_base = (char *)pdacl;
617 acl_size = sizeof(struct cifs_acl);
619 num_aces = le32_to_cpu(pdacl->num_aces);
621 umode_t user_mask = S_IRWXU;
622 umode_t group_mask = S_IRWXG;
623 umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
625 if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
627 ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
630 cERROR(1, "DACL memory allocation error");
634 for (i = 0; i < num_aces; ++i) {
635 ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
636 #ifdef CONFIG_CIFS_DEBUG2
637 dump_ace(ppace[i], end_of_acl);
639 if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
640 access_flags_to_mode(ppace[i]->access_req,
644 if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
645 access_flags_to_mode(ppace[i]->access_req,
649 if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
650 access_flags_to_mode(ppace[i]->access_req,
654 if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
655 access_flags_to_mode(ppace[i]->access_req,
661 /* memcpy((void *)(&(cifscred->aces[i])),
663 sizeof(struct cifs_ace)); */
665 acl_base = (char *)ppace[i];
666 acl_size = le16_to_cpu(ppace[i]->size);
676 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
677 struct cifs_sid *pgrpsid, __u64 nmode)
680 struct cifs_acl *pnndacl;
682 pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
684 size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
685 pownersid, nmode, S_IRWXU);
686 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
687 pgrpsid, nmode, S_IRWXG);
688 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
689 &sid_everyone, nmode, S_IRWXO);
691 pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
692 pndacl->num_aces = cpu_to_le32(3);
698 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
700 /* BB need to add parm so we can store the SID BB */
702 /* validate that we do not go past end of ACL - sid must be at least 8
703 bytes long (assuming no sub-auths - e.g. the null SID */
704 if (end_of_acl < (char *)psid + 8) {
705 cERROR(1, "ACL too small to parse SID %p", psid);
709 #ifdef CONFIG_CIFS_DEBUG2
710 if (psid->num_subauth) {
712 cFYI(1, "SID revision %d num_auth %d",
713 psid->revision, psid->num_subauth);
715 for (i = 0; i < psid->num_subauth; i++) {
716 cFYI(1, "SID sub_auth[%d]: 0x%x ", i,
717 le32_to_cpu(psid->sub_auth[i]));
720 /* BB add length check to make sure that we do not have huge
721 num auths and therefore go off the end */
723 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
731 /* Convert CIFS ACL to POSIX form */
732 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
733 struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr)
736 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
737 struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
738 char *end_of_acl = ((char *)pntsd) + acl_len;
744 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
745 le32_to_cpu(pntsd->osidoffset));
746 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
747 le32_to_cpu(pntsd->gsidoffset));
748 dacloffset = le32_to_cpu(pntsd->dacloffset);
749 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
750 cFYI(DBG2, "revision %d type 0x%x ooffset 0x%x goffset 0x%x "
751 "sacloffset 0x%x dacloffset 0x%x",
752 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
753 le32_to_cpu(pntsd->gsidoffset),
754 le32_to_cpu(pntsd->sacloffset), dacloffset);
755 /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
756 rc = parse_sid(owner_sid_ptr, end_of_acl);
758 cFYI(1, "%s: Error %d parsing Owner SID", __func__, rc);
761 rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
763 cFYI(1, "%s: Error %d mapping Owner SID to uid", __func__, rc);
767 rc = parse_sid(group_sid_ptr, end_of_acl);
769 cFYI(1, "%s: Error %d mapping Owner SID to gid", __func__, rc);
772 rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
774 cFYI(1, "%s: Error %d mapping Group SID to gid", __func__, rc);
779 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
780 group_sid_ptr, fattr);
782 cFYI(1, "no ACL"); /* BB grant all or default perms? */
787 /* Convert permission bits from mode to equivalent CIFS ACL */
788 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
789 __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag)
795 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
796 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
797 struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */
798 struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
800 if (nmode != NO_CHANGE_64) { /* chmod */
801 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
802 le32_to_cpu(pntsd->osidoffset));
803 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
804 le32_to_cpu(pntsd->gsidoffset));
805 dacloffset = le32_to_cpu(pntsd->dacloffset);
806 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
807 ndacloffset = sizeof(struct cifs_ntsd);
808 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
809 ndacl_ptr->revision = dacl_ptr->revision;
811 ndacl_ptr->num_aces = 0;
813 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
815 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
816 /* copy sec desc control portion & owner and group sids */
817 copy_sec_desc(pntsd, pnntsd, sidsoffset);
818 *aclflag = CIFS_ACL_DACL;
820 memcpy(pnntsd, pntsd, secdesclen);
821 if (uid_valid(uid)) { /* chown */
823 owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
824 le32_to_cpu(pnntsd->osidoffset));
825 nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
829 id = from_kuid(&init_user_ns, uid);
830 rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
832 cFYI(1, "%s: Mapping error %d for owner id %d",
834 kfree(nowner_sid_ptr);
837 cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
838 kfree(nowner_sid_ptr);
839 *aclflag = CIFS_ACL_OWNER;
841 if (gid_valid(gid)) { /* chgrp */
843 group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
844 le32_to_cpu(pnntsd->gsidoffset));
845 ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
849 id = from_kgid(&init_user_ns, gid);
850 rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
852 cFYI(1, "%s: Mapping error %d for group id %d",
854 kfree(ngroup_sid_ptr);
857 cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
858 kfree(ngroup_sid_ptr);
859 *aclflag = CIFS_ACL_GROUP;
866 static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
867 __u16 fid, u32 *pacllen)
869 struct cifs_ntsd *pntsd = NULL;
872 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
875 return ERR_CAST(tlink);
878 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
881 cifs_put_tlink(tlink);
883 cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
889 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
890 const char *path, u32 *pacllen)
892 struct cifs_ntsd *pntsd = NULL;
895 int rc, create_options = 0;
897 struct cifs_tcon *tcon;
898 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
901 return ERR_CAST(tlink);
903 tcon = tlink_tcon(tlink);
906 if (backup_cred(cifs_sb))
907 create_options |= CREATE_OPEN_BACKUP_INTENT;
909 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
910 create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
911 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
913 rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
914 CIFSSMBClose(xid, tcon, fid);
917 cifs_put_tlink(tlink);
920 cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
926 /* Retrieve an ACL from the server */
927 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
928 struct inode *inode, const char *path,
931 struct cifs_ntsd *pntsd = NULL;
932 struct cifsFileInfo *open_file = NULL;
935 open_file = find_readable_file(CIFS_I(inode), true);
937 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
939 pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->fid.netfid, pacllen);
940 cifsFileInfo_put(open_file);
944 /* Set an ACL on the server */
945 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
946 struct inode *inode, const char *path, int aclflag)
950 int rc, access_flags, create_options = 0;
952 struct cifs_tcon *tcon;
953 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
954 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
957 return PTR_ERR(tlink);
959 tcon = tlink_tcon(tlink);
962 if (backup_cred(cifs_sb))
963 create_options |= CREATE_OPEN_BACKUP_INTENT;
965 if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
966 access_flags = WRITE_OWNER;
968 access_flags = WRITE_DAC;
970 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, access_flags,
971 create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
972 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
974 cERROR(1, "Unable to open file to set ACL");
978 rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen, aclflag);
979 cFYI(DBG2, "SetCIFSACL rc = %d", rc);
981 CIFSSMBClose(xid, tcon, fid);
984 cifs_put_tlink(tlink);
988 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
990 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
991 struct inode *inode, const char *path, const __u16 *pfid)
993 struct cifs_ntsd *pntsd = NULL;
997 cFYI(DBG2, "converting ACL to mode for %s", path);
1000 pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
1002 pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
1004 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1005 if (IS_ERR(pntsd)) {
1006 rc = PTR_ERR(pntsd);
1007 cERROR(1, "%s: error %d getting sec desc", __func__, rc);
1009 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr);
1012 cERROR(1, "parse sec desc failed rc = %d", rc);
1018 /* Convert mode bits to an ACL so we can update the ACL on the server */
1020 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1021 kuid_t uid, kgid_t gid)
1024 int aclflag = CIFS_ACL_DACL; /* default flag to set */
1025 __u32 secdesclen = 0;
1026 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1027 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1029 cFYI(DBG2, "set ACL from mode for %s", path);
1031 /* Get the security descriptor */
1032 pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
1033 if (IS_ERR(pntsd)) {
1034 rc = PTR_ERR(pntsd);
1035 cERROR(1, "%s: error %d getting sec desc", __func__, rc);
1040 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1041 * as chmod disables ACEs and set the security descriptor. Allocate
1042 * memory for the smb header, set security descriptor request security
1043 * descriptor parameters, and secuirty descriptor itself
1045 secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1046 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1048 cERROR(1, "Unable to allocate security descriptor");
1053 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1056 cFYI(DBG2, "build_sec_desc rc: %d", rc);
1059 /* Set the security descriptor */
1060 rc = set_cifs_acl(pnntsd, secdesclen, inode, path, aclflag);
1061 cFYI(DBG2, "set_cifs_acl rc: %d", rc);