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 <linux/moduleparam.h>
30 #include <keys/user-type.h>
34 #include "cifsproto.h"
35 #include "cifs_debug.h"
37 /* security id for everyone/world system group */
38 static const struct cifs_sid sid_everyone = {
39 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
40 /* security id for Authenticated Users system group */
41 static const struct cifs_sid sid_authusers = {
42 1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(11)} };
44 static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
46 static const struct cred *root_cred;
48 static unsigned int cifs_idmap_cache_timeout = 600;
49 module_param(cifs_idmap_cache_timeout, uint, 0644);
50 MODULE_PARM_DESC(cifs_idmap_cache_timeout, "Number of seconds that ID mappings "
51 "stay in cache. (default=600)");
54 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
59 * If the payload is less than or equal to the size of a pointer, then
60 * an allocation here is wasteful. Just copy the data directly to the
61 * payload.value union member instead.
63 * With this however, you must check the datalen before trying to
64 * dereference payload.data!
66 if (prep->datalen <= sizeof(void *)) {
67 key->payload.value = 0;
68 memcpy(&key->payload.value, prep->data, prep->datalen);
69 key->datalen = prep->datalen;
72 payload = kmalloc(prep->datalen, GFP_KERNEL);
76 memcpy(payload, prep->data, prep->datalen);
77 key->payload.data = payload;
78 key->datalen = prep->datalen;
83 cifs_idmap_key_destroy(struct key *key)
85 if (key->datalen > sizeof(void *))
86 kfree(key->payload.data);
89 static struct key_type cifs_idmap_key_type = {
91 .instantiate = cifs_idmap_key_instantiate,
92 .destroy = cifs_idmap_key_destroy,
93 .describe = user_describe,
98 sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
102 char *sidstr, *strptr;
104 /* 3 bytes for prefix */
105 sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
106 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
112 len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
116 for (i = 0; i < NUM_AUTHS; ++i) {
117 if (sidptr->authority[i]) {
118 len = sprintf(strptr, "-%hhu", sidptr->authority[i]);
123 for (i = 0; i < sidptr->num_subauth; ++i) {
124 saval = le32_to_cpu(sidptr->sub_auth[i]);
125 len = sprintf(strptr, "-%u", saval);
133 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
134 * the same returns zero, if they do not match returns non-zero.
137 compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
140 int num_subauth, num_sat, num_saw;
142 if ((!ctsid) || (!cwsid))
145 /* compare the revision */
146 if (ctsid->revision != cwsid->revision) {
147 if (ctsid->revision > cwsid->revision)
153 /* compare all of the six auth values */
154 for (i = 0; i < NUM_AUTHS; ++i) {
155 if (ctsid->authority[i] != cwsid->authority[i]) {
156 if (ctsid->authority[i] > cwsid->authority[i])
163 /* compare all of the subauth values if any */
164 num_sat = ctsid->num_subauth;
165 num_saw = cwsid->num_subauth;
166 num_subauth = num_sat < num_saw ? num_sat : num_saw;
168 for (i = 0; i < num_subauth; ++i) {
169 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
170 if (le32_to_cpu(ctsid->sub_auth[i]) >
171 le32_to_cpu(cwsid->sub_auth[i]))
179 return 0; /* sids compare/match */
183 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
187 dst->revision = src->revision;
188 dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
189 for (i = 0; i < NUM_AUTHS; ++i)
190 dst->authority[i] = src->authority[i];
191 for (i = 0; i < dst->num_subauth; ++i)
192 dst->sub_auth[i] = src->sub_auth[i];
196 id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
200 struct cifs_sid *ksid;
201 unsigned int ksid_size;
202 char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
203 const struct cred *saved_cred;
205 rc = snprintf(desc, sizeof(desc), "%ci:%u",
206 sidtype == SIDOWNER ? 'o' : 'g', cid);
207 if (rc >= sizeof(desc))
211 saved_cred = override_creds(root_cred);
212 sidkey = request_key(&cifs_idmap_key_type, desc, "");
213 if (IS_ERR(sidkey)) {
215 cFYI(1, "%s: Can't map %cid %u to a SID", __func__,
216 sidtype == SIDOWNER ? 'u' : 'g', cid);
217 goto out_revert_creds;
218 } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
220 cFYI(1, "%s: Downcall contained malformed key "
221 "(datalen=%hu)", __func__, sidkey->datalen);
225 ksid = (struct cifs_sid *)sidkey->payload.data;
226 ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
227 if (ksid_size > sidkey->datalen) {
229 cFYI(1, "%s: Downcall contained malformed key (datalen=%hu, "
230 "ksid_size=%u)", __func__, sidkey->datalen, ksid_size);
233 cifs_copy_sid(ssid, ksid);
234 key_set_timeout(sidkey, cifs_idmap_cache_timeout);
238 revert_creds(saved_cred);
242 key_invalidate(sidkey);
247 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
248 struct cifs_fattr *fattr, uint sidtype)
253 const struct cred *saved_cred;
254 uid_t fuid = cifs_sb->mnt_uid;
255 gid_t fgid = cifs_sb->mnt_gid;
258 * If we have too many subauthorities, then something is really wrong.
259 * Just return an error.
261 if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
262 cFYI(1, "%s: %u subauthorities is too many!", __func__,
267 sidstr = sid_to_key_str(psid, sidtype);
271 saved_cred = override_creds(root_cred);
272 sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
273 if (IS_ERR(sidkey)) {
275 cFYI(1, "%s: Can't map SID %s to a %cid", __func__, sidstr,
276 sidtype == SIDOWNER ? 'u' : 'g');
277 goto out_revert_creds;
281 * FIXME: Here we assume that uid_t and gid_t are same size. It's
282 * probably a safe assumption but might be better to check based on
285 if (sidkey->datalen != sizeof(uid_t)) {
287 cFYI(1, "%s: Downcall contained malformed key "
288 "(datalen=%hu)", __func__, sidkey->datalen);
289 key_invalidate(sidkey);
293 if (sidtype == SIDOWNER)
294 fuid = (uid_t)sidkey->payload.value;
296 fgid = (gid_t)sidkey->payload.value;
298 key_set_timeout(sidkey, cifs_idmap_cache_timeout);
302 revert_creds(saved_cred);
306 * Note that we return 0 here unconditionally. If the mapping
307 * fails then we just fall back to using the mnt_uid/mnt_gid.
309 if (sidtype == SIDOWNER)
310 fattr->cf_uid = fuid;
312 fattr->cf_gid = fgid;
317 init_cifs_idmap(void)
323 cFYI(1, "Registering the %s key type", cifs_idmap_key_type.name);
325 /* create an override credential set with a special thread keyring in
326 * which requests are cached
328 * this is used to prevent malicious redirections from being installed
331 cred = prepare_kernel_cred(NULL);
335 keyring = keyring_alloc(".cifs_idmap", 0, 0, cred,
336 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
337 KEY_USR_VIEW | KEY_USR_READ,
338 KEY_ALLOC_NOT_IN_QUOTA, NULL);
339 if (IS_ERR(keyring)) {
340 ret = PTR_ERR(keyring);
341 goto failed_put_cred;
344 ret = register_key_type(&cifs_idmap_key_type);
348 /* instruct request_key() to use this special keyring as a cache for
349 * the results it looks up */
350 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
351 cred->thread_keyring = keyring;
352 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
355 cFYI(1, "cifs idmap keyring: %d", key_serial(keyring));
366 exit_cifs_idmap(void)
368 key_revoke(root_cred->thread_keyring);
369 unregister_key_type(&cifs_idmap_key_type);
371 cFYI(1, "Unregistered %s key type", cifs_idmap_key_type.name);
374 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
375 static void copy_sec_desc(const struct cifs_ntsd *pntsd,
376 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
378 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
379 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
381 /* copy security descriptor control portion */
382 pnntsd->revision = pntsd->revision;
383 pnntsd->type = pntsd->type;
384 pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
385 pnntsd->sacloffset = 0;
386 pnntsd->osidoffset = cpu_to_le32(sidsoffset);
387 pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
390 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
391 le32_to_cpu(pntsd->osidoffset));
392 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
393 cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
396 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
397 le32_to_cpu(pntsd->gsidoffset));
398 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
399 sizeof(struct cifs_sid));
400 cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
407 change posix mode to reflect permissions
408 pmode is the existing mode (we only want to overwrite part of this
409 bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
411 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
412 umode_t *pbits_to_set)
414 __u32 flags = le32_to_cpu(ace_flags);
415 /* the order of ACEs is important. The canonical order is to begin with
416 DENY entries followed by ALLOW, otherwise an allow entry could be
417 encountered first, making the subsequent deny entry like "dead code"
418 which would be superflous since Windows stops when a match is made
419 for the operation you are trying to perform for your user */
421 /* For deny ACEs we change the mask so that subsequent allow access
422 control entries do not turn on the bits we are denying */
423 if (type == ACCESS_DENIED) {
424 if (flags & GENERIC_ALL)
425 *pbits_to_set &= ~S_IRWXUGO;
427 if ((flags & GENERIC_WRITE) ||
428 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
429 *pbits_to_set &= ~S_IWUGO;
430 if ((flags & GENERIC_READ) ||
431 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
432 *pbits_to_set &= ~S_IRUGO;
433 if ((flags & GENERIC_EXECUTE) ||
434 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
435 *pbits_to_set &= ~S_IXUGO;
437 } else if (type != ACCESS_ALLOWED) {
438 cERROR(1, "unknown access control type %d", type);
441 /* else ACCESS_ALLOWED type */
443 if (flags & GENERIC_ALL) {
444 *pmode |= (S_IRWXUGO & (*pbits_to_set));
445 cFYI(DBG2, "all perms");
448 if ((flags & GENERIC_WRITE) ||
449 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
450 *pmode |= (S_IWUGO & (*pbits_to_set));
451 if ((flags & GENERIC_READ) ||
452 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
453 *pmode |= (S_IRUGO & (*pbits_to_set));
454 if ((flags & GENERIC_EXECUTE) ||
455 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
456 *pmode |= (S_IXUGO & (*pbits_to_set));
458 cFYI(DBG2, "access flags 0x%x mode now 0x%x", flags, *pmode);
463 Generate access flags to reflect permissions mode is the existing mode.
464 This function is called for every ACE in the DACL whose SID matches
465 with either owner or group or everyone.
468 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
471 /* reset access mask */
474 /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
477 /* check for R/W/X UGO since we do not know whose flags
478 is this but we have cleared all the bits sans RWX for
479 either user or group or other as per bits_to_use */
481 *pace_flags |= SET_FILE_READ_RIGHTS;
483 *pace_flags |= SET_FILE_WRITE_RIGHTS;
485 *pace_flags |= SET_FILE_EXEC_RIGHTS;
487 cFYI(DBG2, "mode: 0x%x, access flags now 0x%x", mode, *pace_flags);
491 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
492 const struct cifs_sid *psid, __u64 nmode, umode_t bits)
496 __u32 access_req = 0;
498 pntace->type = ACCESS_ALLOWED;
500 mode_to_access_flags(nmode, bits, &access_req);
502 access_req = SET_MINIMUM_RIGHTS;
503 pntace->access_req = cpu_to_le32(access_req);
505 pntace->sid.revision = psid->revision;
506 pntace->sid.num_subauth = psid->num_subauth;
507 for (i = 0; i < NUM_AUTHS; i++)
508 pntace->sid.authority[i] = psid->authority[i];
509 for (i = 0; i < psid->num_subauth; i++)
510 pntace->sid.sub_auth[i] = psid->sub_auth[i];
512 size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
513 pntace->size = cpu_to_le16(size);
519 #ifdef CONFIG_CIFS_DEBUG2
520 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
524 /* validate that we do not go past end of acl */
526 if (le16_to_cpu(pace->size) < 16) {
527 cERROR(1, "ACE too small %d", le16_to_cpu(pace->size));
531 if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
532 cERROR(1, "ACL too small to parse ACE");
536 num_subauth = pace->sid.num_subauth;
539 cFYI(1, "ACE revision %d num_auth %d type %d flags %d size %d",
540 pace->sid.revision, pace->sid.num_subauth, pace->type,
541 pace->flags, le16_to_cpu(pace->size));
542 for (i = 0; i < num_subauth; ++i) {
543 cFYI(1, "ACE sub_auth[%d]: 0x%x", i,
544 le32_to_cpu(pace->sid.sub_auth[i]));
547 /* BB add length check to make sure that we do not have huge
548 num auths and therefore go off the end */
556 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
557 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
558 struct cifs_fattr *fattr)
564 struct cifs_ace **ppace;
566 /* BB need to add parm so we can store the SID BB */
569 /* no DACL in the security descriptor, set
570 all the permissions for user/group/other */
571 fattr->cf_mode |= S_IRWXUGO;
575 /* validate that we do not go past end of acl */
576 if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
577 cERROR(1, "ACL too small to parse DACL");
581 cFYI(DBG2, "DACL revision %d size %d num aces %d",
582 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
583 le32_to_cpu(pdacl->num_aces));
585 /* reset rwx permissions for user/group/other.
586 Also, if num_aces is 0 i.e. DACL has no ACEs,
587 user/group/other have no permissions */
588 fattr->cf_mode &= ~(S_IRWXUGO);
590 acl_base = (char *)pdacl;
591 acl_size = sizeof(struct cifs_acl);
593 num_aces = le32_to_cpu(pdacl->num_aces);
595 umode_t user_mask = S_IRWXU;
596 umode_t group_mask = S_IRWXG;
597 umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
599 if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
601 ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
604 cERROR(1, "DACL memory allocation error");
608 for (i = 0; i < num_aces; ++i) {
609 ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
610 #ifdef CONFIG_CIFS_DEBUG2
611 dump_ace(ppace[i], end_of_acl);
613 if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
614 access_flags_to_mode(ppace[i]->access_req,
618 if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
619 access_flags_to_mode(ppace[i]->access_req,
623 if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
624 access_flags_to_mode(ppace[i]->access_req,
628 if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
629 access_flags_to_mode(ppace[i]->access_req,
635 /* memcpy((void *)(&(cifscred->aces[i])),
637 sizeof(struct cifs_ace)); */
639 acl_base = (char *)ppace[i];
640 acl_size = le16_to_cpu(ppace[i]->size);
650 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
651 struct cifs_sid *pgrpsid, __u64 nmode)
654 struct cifs_acl *pnndacl;
656 pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
658 size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
659 pownersid, nmode, S_IRWXU);
660 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
661 pgrpsid, nmode, S_IRWXG);
662 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
663 &sid_everyone, nmode, S_IRWXO);
665 pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
666 pndacl->num_aces = cpu_to_le32(3);
672 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
674 /* BB need to add parm so we can store the SID BB */
676 /* validate that we do not go past end of ACL - sid must be at least 8
677 bytes long (assuming no sub-auths - e.g. the null SID */
678 if (end_of_acl < (char *)psid + 8) {
679 cERROR(1, "ACL too small to parse SID %p", psid);
683 #ifdef CONFIG_CIFS_DEBUG2
684 if (psid->num_subauth) {
686 cFYI(1, "SID revision %d num_auth %d",
687 psid->revision, psid->num_subauth);
689 for (i = 0; i < psid->num_subauth; i++) {
690 cFYI(1, "SID sub_auth[%d]: 0x%x ", i,
691 le32_to_cpu(psid->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 */
697 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
705 /* Convert CIFS ACL to POSIX form */
706 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
707 struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr)
710 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
711 struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
712 char *end_of_acl = ((char *)pntsd) + acl_len;
718 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
719 le32_to_cpu(pntsd->osidoffset));
720 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
721 le32_to_cpu(pntsd->gsidoffset));
722 dacloffset = le32_to_cpu(pntsd->dacloffset);
723 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
724 cFYI(DBG2, "revision %d type 0x%x ooffset 0x%x goffset 0x%x "
725 "sacloffset 0x%x dacloffset 0x%x",
726 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
727 le32_to_cpu(pntsd->gsidoffset),
728 le32_to_cpu(pntsd->sacloffset), dacloffset);
729 /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
730 rc = parse_sid(owner_sid_ptr, end_of_acl);
732 cFYI(1, "%s: Error %d parsing Owner SID", __func__, rc);
735 rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
737 cFYI(1, "%s: Error %d mapping Owner SID to uid", __func__, rc);
741 rc = parse_sid(group_sid_ptr, end_of_acl);
743 cFYI(1, "%s: Error %d mapping Owner SID to gid", __func__, rc);
746 rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
748 cFYI(1, "%s: Error %d mapping Group SID to gid", __func__, rc);
753 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
754 group_sid_ptr, fattr);
756 cFYI(1, "no ACL"); /* BB grant all or default perms? */
761 /* Convert permission bits from mode to equivalent CIFS ACL */
762 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
763 __u32 secdesclen, __u64 nmode, uid_t uid, gid_t gid, int *aclflag)
769 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
770 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
771 struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */
772 struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
774 if (nmode != NO_CHANGE_64) { /* chmod */
775 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
776 le32_to_cpu(pntsd->osidoffset));
777 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
778 le32_to_cpu(pntsd->gsidoffset));
779 dacloffset = le32_to_cpu(pntsd->dacloffset);
780 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
781 ndacloffset = sizeof(struct cifs_ntsd);
782 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
783 ndacl_ptr->revision = dacl_ptr->revision;
785 ndacl_ptr->num_aces = 0;
787 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
789 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
790 /* copy sec desc control portion & owner and group sids */
791 copy_sec_desc(pntsd, pnntsd, sidsoffset);
792 *aclflag = CIFS_ACL_DACL;
794 memcpy(pnntsd, pntsd, secdesclen);
795 if (uid != NO_CHANGE_32) { /* chown */
796 owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
797 le32_to_cpu(pnntsd->osidoffset));
798 nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
802 rc = id_to_sid(uid, SIDOWNER, nowner_sid_ptr);
804 cFYI(1, "%s: Mapping error %d for owner id %d",
806 kfree(nowner_sid_ptr);
809 cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
810 kfree(nowner_sid_ptr);
811 *aclflag = CIFS_ACL_OWNER;
813 if (gid != NO_CHANGE_32) { /* chgrp */
814 group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
815 le32_to_cpu(pnntsd->gsidoffset));
816 ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
820 rc = id_to_sid(gid, SIDGROUP, ngroup_sid_ptr);
822 cFYI(1, "%s: Mapping error %d for group id %d",
824 kfree(ngroup_sid_ptr);
827 cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
828 kfree(ngroup_sid_ptr);
829 *aclflag = CIFS_ACL_GROUP;
836 static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
837 __u16 fid, u32 *pacllen)
839 struct cifs_ntsd *pntsd = NULL;
842 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
845 return ERR_CAST(tlink);
848 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
851 cifs_put_tlink(tlink);
853 cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
859 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
860 const char *path, u32 *pacllen)
862 struct cifs_ntsd *pntsd = NULL;
865 int rc, create_options = 0;
867 struct cifs_tcon *tcon;
868 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
871 return ERR_CAST(tlink);
873 tcon = tlink_tcon(tlink);
876 if (backup_cred(cifs_sb))
877 create_options |= CREATE_OPEN_BACKUP_INTENT;
879 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
880 create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
881 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
883 rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
884 CIFSSMBClose(xid, tcon, fid);
887 cifs_put_tlink(tlink);
890 cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
896 /* Retrieve an ACL from the server */
897 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
898 struct inode *inode, const char *path,
901 struct cifs_ntsd *pntsd = NULL;
902 struct cifsFileInfo *open_file = NULL;
905 open_file = find_readable_file(CIFS_I(inode), true);
907 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
909 pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->fid.netfid, pacllen);
910 cifsFileInfo_put(open_file);
914 /* Set an ACL on the server */
915 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
916 struct inode *inode, const char *path, int aclflag)
920 int rc, access_flags, create_options = 0;
922 struct cifs_tcon *tcon;
923 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
924 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
927 return PTR_ERR(tlink);
929 tcon = tlink_tcon(tlink);
932 if (backup_cred(cifs_sb))
933 create_options |= CREATE_OPEN_BACKUP_INTENT;
935 if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
936 access_flags = WRITE_OWNER;
938 access_flags = WRITE_DAC;
940 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, access_flags,
941 create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
942 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
944 cERROR(1, "Unable to open file to set ACL");
948 rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen, aclflag);
949 cFYI(DBG2, "SetCIFSACL rc = %d", rc);
951 CIFSSMBClose(xid, tcon, fid);
954 cifs_put_tlink(tlink);
958 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
960 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
961 struct inode *inode, const char *path, const __u16 *pfid)
963 struct cifs_ntsd *pntsd = NULL;
967 cFYI(DBG2, "converting ACL to mode for %s", path);
970 pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
972 pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
974 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
977 cERROR(1, "%s: error %d getting sec desc", __func__, rc);
979 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr);
982 cERROR(1, "parse sec desc failed rc = %d", rc);
988 /* Convert mode bits to an ACL so we can update the ACL on the server */
990 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
991 uid_t uid, gid_t gid)
994 int aclflag = CIFS_ACL_DACL; /* default flag to set */
995 __u32 secdesclen = 0;
996 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
997 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
999 cFYI(DBG2, "set ACL from mode for %s", path);
1001 /* Get the security descriptor */
1002 pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
1003 if (IS_ERR(pntsd)) {
1004 rc = PTR_ERR(pntsd);
1005 cERROR(1, "%s: error %d getting sec desc", __func__, rc);
1010 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1011 * as chmod disables ACEs and set the security descriptor. Allocate
1012 * memory for the smb header, set security descriptor request security
1013 * descriptor parameters, and secuirty descriptor itself
1015 secdesclen = max_t(u32, secdesclen, DEFSECDESCLEN);
1016 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1018 cERROR(1, "Unable to allocate security descriptor");
1023 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1026 cFYI(DBG2, "build_sec_desc rc: %d", rc);
1029 /* Set the security descriptor */
1030 rc = set_cifs_acl(pnntsd, secdesclen, inode, path, aclflag);
1031 cFYI(DBG2, "set_cifs_acl rc: %d", rc);