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 static const struct cifs_sid sid_user
= {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
45 /* S-1-22-1 Unmapped Unix users */
46 static const struct cifs_sid sid_unix_users
= {1, 1, {0, 0, 0, 0, 0, 22},
47 {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
49 /* S-1-22-2 Unmapped Unix groups */
50 static const struct cifs_sid sid_unix_groups
= { 1, 1, {0, 0, 0, 0, 0, 22},
51 {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
54 * See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
57 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
59 /* S-1-5-88-1 Unix uid */
60 static const struct cifs_sid sid_unix_NFS_users
= { 1, 2, {0, 0, 0, 0, 0, 5},
62 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
64 /* S-1-5-88-2 Unix gid */
65 static const struct cifs_sid sid_unix_NFS_groups
= { 1, 2, {0, 0, 0, 0, 0, 5},
67 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
69 /* S-1-5-88-3 Unix mode */
70 static const struct cifs_sid sid_unix_NFS_mode
= { 1, 2, {0, 0, 0, 0, 0, 5},
72 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
74 static const struct cred
*root_cred
;
77 cifs_idmap_key_instantiate(struct key
*key
, struct key_preparsed_payload
*prep
)
82 * If the payload is less than or equal to the size of a pointer, then
83 * an allocation here is wasteful. Just copy the data directly to the
84 * payload.value union member instead.
86 * With this however, you must check the datalen before trying to
87 * dereference payload.data!
89 if (prep
->datalen
<= sizeof(key
->payload
)) {
90 key
->payload
.data
[0] = NULL
;
91 memcpy(&key
->payload
, prep
->data
, prep
->datalen
);
93 payload
= kmemdup(prep
->data
, prep
->datalen
, GFP_KERNEL
);
96 key
->payload
.data
[0] = payload
;
99 key
->datalen
= prep
->datalen
;
104 cifs_idmap_key_destroy(struct key
*key
)
106 if (key
->datalen
> sizeof(key
->payload
))
107 kfree(key
->payload
.data
[0]);
110 static struct key_type cifs_idmap_key_type
= {
111 .name
= "cifs.idmap",
112 .instantiate
= cifs_idmap_key_instantiate
,
113 .destroy
= cifs_idmap_key_destroy
,
114 .describe
= user_describe
,
118 sid_to_key_str(struct cifs_sid
*sidptr
, unsigned int type
)
122 char *sidstr
, *strptr
;
123 unsigned long long id_auth_val
;
125 /* 3 bytes for prefix */
126 sidstr
= kmalloc(3 + SID_STRING_BASE_SIZE
+
127 (SID_STRING_SUBAUTH_SIZE
* sidptr
->num_subauth
),
133 len
= sprintf(strptr
, "%cs:S-%hhu", type
== SIDOWNER
? 'o' : 'g',
137 /* The authority field is a single 48-bit number */
138 id_auth_val
= (unsigned long long)sidptr
->authority
[5];
139 id_auth_val
|= (unsigned long long)sidptr
->authority
[4] << 8;
140 id_auth_val
|= (unsigned long long)sidptr
->authority
[3] << 16;
141 id_auth_val
|= (unsigned long long)sidptr
->authority
[2] << 24;
142 id_auth_val
|= (unsigned long long)sidptr
->authority
[1] << 32;
143 id_auth_val
|= (unsigned long long)sidptr
->authority
[0] << 48;
146 * MS-DTYP states that if the authority is >= 2^32, then it should be
147 * expressed as a hex value.
149 if (id_auth_val
<= UINT_MAX
)
150 len
= sprintf(strptr
, "-%llu", id_auth_val
);
152 len
= sprintf(strptr
, "-0x%llx", id_auth_val
);
156 for (i
= 0; i
< sidptr
->num_subauth
; ++i
) {
157 saval
= le32_to_cpu(sidptr
->sub_auth
[i
]);
158 len
= sprintf(strptr
, "-%u", saval
);
166 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
167 * the same returns zero, if they do not match returns non-zero.
170 compare_sids(const struct cifs_sid
*ctsid
, const struct cifs_sid
*cwsid
)
173 int num_subauth
, num_sat
, num_saw
;
175 if ((!ctsid
) || (!cwsid
))
178 /* compare the revision */
179 if (ctsid
->revision
!= cwsid
->revision
) {
180 if (ctsid
->revision
> cwsid
->revision
)
186 /* compare all of the six auth values */
187 for (i
= 0; i
< NUM_AUTHS
; ++i
) {
188 if (ctsid
->authority
[i
] != cwsid
->authority
[i
]) {
189 if (ctsid
->authority
[i
] > cwsid
->authority
[i
])
196 /* compare all of the subauth values if any */
197 num_sat
= ctsid
->num_subauth
;
198 num_saw
= cwsid
->num_subauth
;
199 num_subauth
= num_sat
< num_saw
? num_sat
: num_saw
;
201 for (i
= 0; i
< num_subauth
; ++i
) {
202 if (ctsid
->sub_auth
[i
] != cwsid
->sub_auth
[i
]) {
203 if (le32_to_cpu(ctsid
->sub_auth
[i
]) >
204 le32_to_cpu(cwsid
->sub_auth
[i
]))
212 return 0; /* sids compare/match */
216 is_well_known_sid(const struct cifs_sid
*psid
, uint32_t *puid
, bool is_group
)
220 const struct cifs_sid
*pwell_known_sid
;
222 if (!psid
|| (puid
== NULL
))
225 num_subauth
= psid
->num_subauth
;
227 /* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
228 if (num_subauth
== 2) {
230 pwell_known_sid
= &sid_unix_groups
;
232 pwell_known_sid
= &sid_unix_users
;
233 } else if (num_subauth
== 3) {
235 pwell_known_sid
= &sid_unix_NFS_groups
;
237 pwell_known_sid
= &sid_unix_NFS_users
;
241 /* compare the revision */
242 if (psid
->revision
!= pwell_known_sid
->revision
)
245 /* compare all of the six auth values */
246 for (i
= 0; i
< NUM_AUTHS
; ++i
) {
247 if (psid
->authority
[i
] != pwell_known_sid
->authority
[i
]) {
248 cifs_dbg(FYI
, "auth %d did not match\n", i
);
253 if (num_subauth
== 2) {
254 if (psid
->sub_auth
[0] != pwell_known_sid
->sub_auth
[0])
257 *puid
= le32_to_cpu(psid
->sub_auth
[1]);
258 } else /* 3 subauths, ie Windows/Mac style */ {
259 *puid
= le32_to_cpu(psid
->sub_auth
[0]);
260 if ((psid
->sub_auth
[0] != pwell_known_sid
->sub_auth
[0]) ||
261 (psid
->sub_auth
[1] != pwell_known_sid
->sub_auth
[1]))
264 *puid
= le32_to_cpu(psid
->sub_auth
[2]);
267 cifs_dbg(FYI
, "Unix UID %d returned from SID\n", *puid
);
268 return true; /* well known sid found, uid returned */
272 cifs_copy_sid(struct cifs_sid
*dst
, const struct cifs_sid
*src
)
276 dst
->revision
= src
->revision
;
277 dst
->num_subauth
= min_t(u8
, src
->num_subauth
, SID_MAX_SUB_AUTHORITIES
);
278 for (i
= 0; i
< NUM_AUTHS
; ++i
)
279 dst
->authority
[i
] = src
->authority
[i
];
280 for (i
= 0; i
< dst
->num_subauth
; ++i
)
281 dst
->sub_auth
[i
] = src
->sub_auth
[i
];
285 id_to_sid(unsigned int cid
, uint sidtype
, struct cifs_sid
*ssid
)
289 struct cifs_sid
*ksid
;
290 unsigned int ksid_size
;
291 char desc
[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
292 const struct cred
*saved_cred
;
294 rc
= snprintf(desc
, sizeof(desc
), "%ci:%u",
295 sidtype
== SIDOWNER
? 'o' : 'g', cid
);
296 if (rc
>= sizeof(desc
))
300 saved_cred
= override_creds(root_cred
);
301 sidkey
= request_key(&cifs_idmap_key_type
, desc
, "");
302 if (IS_ERR(sidkey
)) {
304 cifs_dbg(FYI
, "%s: Can't map %cid %u to a SID\n",
305 __func__
, sidtype
== SIDOWNER
? 'u' : 'g', cid
);
306 goto out_revert_creds
;
307 } else if (sidkey
->datalen
< CIFS_SID_BASE_SIZE
) {
309 cifs_dbg(FYI
, "%s: Downcall contained malformed key (datalen=%hu)\n",
310 __func__
, sidkey
->datalen
);
315 * A sid is usually too large to be embedded in payload.value, but if
316 * there are no subauthorities and the host has 8-byte pointers, then
319 ksid
= sidkey
->datalen
<= sizeof(sidkey
->payload
) ?
320 (struct cifs_sid
*)&sidkey
->payload
:
321 (struct cifs_sid
*)sidkey
->payload
.data
[0];
323 ksid_size
= CIFS_SID_BASE_SIZE
+ (ksid
->num_subauth
* sizeof(__le32
));
324 if (ksid_size
> sidkey
->datalen
) {
326 cifs_dbg(FYI
, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
327 __func__
, sidkey
->datalen
, ksid_size
);
331 cifs_copy_sid(ssid
, ksid
);
335 revert_creds(saved_cred
);
339 key_invalidate(sidkey
);
344 sid_to_id(struct cifs_sb_info
*cifs_sb
, struct cifs_sid
*psid
,
345 struct cifs_fattr
*fattr
, uint sidtype
)
350 const struct cred
*saved_cred
;
351 kuid_t fuid
= cifs_sb
->mnt_uid
;
352 kgid_t fgid
= cifs_sb
->mnt_gid
;
355 * If we have too many subauthorities, then something is really wrong.
356 * Just return an error.
358 if (unlikely(psid
->num_subauth
> SID_MAX_SUB_AUTHORITIES
)) {
359 cifs_dbg(FYI
, "%s: %u subauthorities is too many!\n",
360 __func__
, psid
->num_subauth
);
364 if (cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_UID_FROM_ACL
) {
368 if (sidtype
!= SIDOWNER
)
373 if (is_well_known_sid(psid
, &unix_id
, is_group
) == false)
374 goto try_upcall_to_get_id
;
381 gid
= make_kgid(&init_user_ns
, id
);
382 if (gid_valid(gid
)) {
391 uid
= make_kuid(&init_user_ns
, id
);
392 if (uid_valid(uid
)) {
397 /* If unable to find uid/gid easily from SID try via upcall */
400 try_upcall_to_get_id
:
401 sidstr
= sid_to_key_str(psid
, sidtype
);
405 saved_cred
= override_creds(root_cred
);
406 sidkey
= request_key(&cifs_idmap_key_type
, sidstr
, "");
407 if (IS_ERR(sidkey
)) {
409 cifs_dbg(FYI
, "%s: Can't map SID %s to a %cid\n",
410 __func__
, sidstr
, sidtype
== SIDOWNER
? 'u' : 'g');
411 goto out_revert_creds
;
415 * FIXME: Here we assume that uid_t and gid_t are same size. It's
416 * probably a safe assumption but might be better to check based on
419 BUILD_BUG_ON(sizeof(uid_t
) != sizeof(gid_t
));
420 if (sidkey
->datalen
!= sizeof(uid_t
)) {
422 cifs_dbg(FYI
, "%s: Downcall contained malformed key (datalen=%hu)\n",
423 __func__
, sidkey
->datalen
);
424 key_invalidate(sidkey
);
428 if (sidtype
== SIDOWNER
) {
431 memcpy(&id
, &sidkey
->payload
.data
[0], sizeof(uid_t
));
432 uid
= make_kuid(&init_user_ns
, id
);
438 memcpy(&id
, &sidkey
->payload
.data
[0], sizeof(gid_t
));
439 gid
= make_kgid(&init_user_ns
, id
);
447 revert_creds(saved_cred
);
451 * Note that we return 0 here unconditionally. If the mapping
452 * fails then we just fall back to using the mnt_uid/mnt_gid.
455 if (sidtype
== SIDOWNER
)
456 fattr
->cf_uid
= fuid
;
458 fattr
->cf_gid
= fgid
;
463 init_cifs_idmap(void)
469 cifs_dbg(FYI
, "Registering the %s key type\n",
470 cifs_idmap_key_type
.name
);
472 /* create an override credential set with a special thread keyring in
473 * which requests are cached
475 * this is used to prevent malicious redirections from being installed
478 cred
= prepare_kernel_cred(NULL
);
482 keyring
= keyring_alloc(".cifs_idmap",
483 GLOBAL_ROOT_UID
, GLOBAL_ROOT_GID
, cred
,
484 (KEY_POS_ALL
& ~KEY_POS_SETATTR
) |
485 KEY_USR_VIEW
| KEY_USR_READ
,
486 KEY_ALLOC_NOT_IN_QUOTA
, NULL
, NULL
);
487 if (IS_ERR(keyring
)) {
488 ret
= PTR_ERR(keyring
);
489 goto failed_put_cred
;
492 ret
= register_key_type(&cifs_idmap_key_type
);
496 /* instruct request_key() to use this special keyring as a cache for
497 * the results it looks up */
498 set_bit(KEY_FLAG_ROOT_CAN_CLEAR
, &keyring
->flags
);
499 cred
->thread_keyring
= keyring
;
500 cred
->jit_keyring
= KEY_REQKEY_DEFL_THREAD_KEYRING
;
503 cifs_dbg(FYI
, "cifs idmap keyring: %d\n", key_serial(keyring
));
514 exit_cifs_idmap(void)
516 key_revoke(root_cred
->thread_keyring
);
517 unregister_key_type(&cifs_idmap_key_type
);
519 cifs_dbg(FYI
, "Unregistered %s key type\n", cifs_idmap_key_type
.name
);
522 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
523 static void copy_sec_desc(const struct cifs_ntsd
*pntsd
,
524 struct cifs_ntsd
*pnntsd
, __u32 sidsoffset
)
526 struct cifs_sid
*owner_sid_ptr
, *group_sid_ptr
;
527 struct cifs_sid
*nowner_sid_ptr
, *ngroup_sid_ptr
;
529 /* copy security descriptor control portion */
530 pnntsd
->revision
= pntsd
->revision
;
531 pnntsd
->type
= pntsd
->type
;
532 pnntsd
->dacloffset
= cpu_to_le32(sizeof(struct cifs_ntsd
));
533 pnntsd
->sacloffset
= 0;
534 pnntsd
->osidoffset
= cpu_to_le32(sidsoffset
);
535 pnntsd
->gsidoffset
= cpu_to_le32(sidsoffset
+ sizeof(struct cifs_sid
));
538 owner_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
539 le32_to_cpu(pntsd
->osidoffset
));
540 nowner_sid_ptr
= (struct cifs_sid
*)((char *)pnntsd
+ sidsoffset
);
541 cifs_copy_sid(nowner_sid_ptr
, owner_sid_ptr
);
544 group_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
545 le32_to_cpu(pntsd
->gsidoffset
));
546 ngroup_sid_ptr
= (struct cifs_sid
*)((char *)pnntsd
+ sidsoffset
+
547 sizeof(struct cifs_sid
));
548 cifs_copy_sid(ngroup_sid_ptr
, group_sid_ptr
);
555 change posix mode to reflect permissions
556 pmode is the existing mode (we only want to overwrite part of this
557 bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
559 static void access_flags_to_mode(__le32 ace_flags
, int type
, umode_t
*pmode
,
560 umode_t
*pbits_to_set
)
562 __u32 flags
= le32_to_cpu(ace_flags
);
563 /* the order of ACEs is important. The canonical order is to begin with
564 DENY entries followed by ALLOW, otherwise an allow entry could be
565 encountered first, making the subsequent deny entry like "dead code"
566 which would be superflous since Windows stops when a match is made
567 for the operation you are trying to perform for your user */
569 /* For deny ACEs we change the mask so that subsequent allow access
570 control entries do not turn on the bits we are denying */
571 if (type
== ACCESS_DENIED
) {
572 if (flags
& GENERIC_ALL
)
573 *pbits_to_set
&= ~S_IRWXUGO
;
575 if ((flags
& GENERIC_WRITE
) ||
576 ((flags
& FILE_WRITE_RIGHTS
) == FILE_WRITE_RIGHTS
))
577 *pbits_to_set
&= ~S_IWUGO
;
578 if ((flags
& GENERIC_READ
) ||
579 ((flags
& FILE_READ_RIGHTS
) == FILE_READ_RIGHTS
))
580 *pbits_to_set
&= ~S_IRUGO
;
581 if ((flags
& GENERIC_EXECUTE
) ||
582 ((flags
& FILE_EXEC_RIGHTS
) == FILE_EXEC_RIGHTS
))
583 *pbits_to_set
&= ~S_IXUGO
;
585 } else if (type
!= ACCESS_ALLOWED
) {
586 cifs_dbg(VFS
, "unknown access control type %d\n", type
);
589 /* else ACCESS_ALLOWED type */
591 if (flags
& GENERIC_ALL
) {
592 *pmode
|= (S_IRWXUGO
& (*pbits_to_set
));
593 cifs_dbg(NOISY
, "all perms\n");
596 if ((flags
& GENERIC_WRITE
) ||
597 ((flags
& FILE_WRITE_RIGHTS
) == FILE_WRITE_RIGHTS
))
598 *pmode
|= (S_IWUGO
& (*pbits_to_set
));
599 if ((flags
& GENERIC_READ
) ||
600 ((flags
& FILE_READ_RIGHTS
) == FILE_READ_RIGHTS
))
601 *pmode
|= (S_IRUGO
& (*pbits_to_set
));
602 if ((flags
& GENERIC_EXECUTE
) ||
603 ((flags
& FILE_EXEC_RIGHTS
) == FILE_EXEC_RIGHTS
))
604 *pmode
|= (S_IXUGO
& (*pbits_to_set
));
606 cifs_dbg(NOISY
, "access flags 0x%x mode now %04o\n", flags
, *pmode
);
611 Generate access flags to reflect permissions mode is the existing mode.
612 This function is called for every ACE in the DACL whose SID matches
613 with either owner or group or everyone.
616 static void mode_to_access_flags(umode_t mode
, umode_t bits_to_use
,
619 /* reset access mask */
622 /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
625 /* check for R/W/X UGO since we do not know whose flags
626 is this but we have cleared all the bits sans RWX for
627 either user or group or other as per bits_to_use */
629 *pace_flags
|= SET_FILE_READ_RIGHTS
;
631 *pace_flags
|= SET_FILE_WRITE_RIGHTS
;
633 *pace_flags
|= SET_FILE_EXEC_RIGHTS
;
635 cifs_dbg(NOISY
, "mode: %04o, access flags now 0x%x\n",
640 static __u16
fill_ace_for_sid(struct cifs_ace
*pntace
,
641 const struct cifs_sid
*psid
, __u64 nmode
, umode_t bits
)
645 __u32 access_req
= 0;
647 pntace
->type
= ACCESS_ALLOWED
;
649 mode_to_access_flags(nmode
, bits
, &access_req
);
651 access_req
= SET_MINIMUM_RIGHTS
;
652 pntace
->access_req
= cpu_to_le32(access_req
);
654 pntace
->sid
.revision
= psid
->revision
;
655 pntace
->sid
.num_subauth
= psid
->num_subauth
;
656 for (i
= 0; i
< NUM_AUTHS
; i
++)
657 pntace
->sid
.authority
[i
] = psid
->authority
[i
];
658 for (i
= 0; i
< psid
->num_subauth
; i
++)
659 pntace
->sid
.sub_auth
[i
] = psid
->sub_auth
[i
];
661 size
= 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid
->num_subauth
* 4);
662 pntace
->size
= cpu_to_le16(size
);
668 #ifdef CONFIG_CIFS_DEBUG2
669 static void dump_ace(struct cifs_ace
*pace
, char *end_of_acl
)
673 /* validate that we do not go past end of acl */
675 if (le16_to_cpu(pace
->size
) < 16) {
676 cifs_dbg(VFS
, "ACE too small %d\n", le16_to_cpu(pace
->size
));
680 if (end_of_acl
< (char *)pace
+ le16_to_cpu(pace
->size
)) {
681 cifs_dbg(VFS
, "ACL too small to parse ACE\n");
685 num_subauth
= pace
->sid
.num_subauth
;
688 cifs_dbg(FYI
, "ACE revision %d num_auth %d type %d flags %d size %d\n",
689 pace
->sid
.revision
, pace
->sid
.num_subauth
, pace
->type
,
690 pace
->flags
, le16_to_cpu(pace
->size
));
691 for (i
= 0; i
< num_subauth
; ++i
) {
692 cifs_dbg(FYI
, "ACE sub_auth[%d]: 0x%x\n",
693 i
, le32_to_cpu(pace
->sid
.sub_auth
[i
]));
696 /* BB add length check to make sure that we do not have huge
697 num auths and therefore go off the end */
704 static void parse_dacl(struct cifs_acl
*pdacl
, char *end_of_acl
,
705 struct cifs_sid
*pownersid
, struct cifs_sid
*pgrpsid
,
706 struct cifs_fattr
*fattr
, bool mode_from_special_sid
)
712 struct cifs_ace
**ppace
;
714 /* BB need to add parm so we can store the SID BB */
717 /* no DACL in the security descriptor, set
718 all the permissions for user/group/other */
719 fattr
->cf_mode
|= S_IRWXUGO
;
723 /* validate that we do not go past end of acl */
724 if (end_of_acl
< (char *)pdacl
+ le16_to_cpu(pdacl
->size
)) {
725 cifs_dbg(VFS
, "ACL too small to parse DACL\n");
729 cifs_dbg(NOISY
, "DACL revision %d size %d num aces %d\n",
730 le16_to_cpu(pdacl
->revision
), le16_to_cpu(pdacl
->size
),
731 le32_to_cpu(pdacl
->num_aces
));
733 /* reset rwx permissions for user/group/other.
734 Also, if num_aces is 0 i.e. DACL has no ACEs,
735 user/group/other have no permissions */
736 fattr
->cf_mode
&= ~(S_IRWXUGO
);
738 acl_base
= (char *)pdacl
;
739 acl_size
= sizeof(struct cifs_acl
);
741 num_aces
= le32_to_cpu(pdacl
->num_aces
);
743 umode_t user_mask
= S_IRWXU
;
744 umode_t group_mask
= S_IRWXG
;
745 umode_t other_mask
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
747 if (num_aces
> ULONG_MAX
/ sizeof(struct cifs_ace
*))
749 ppace
= kmalloc_array(num_aces
, sizeof(struct cifs_ace
*),
754 for (i
= 0; i
< num_aces
; ++i
) {
755 ppace
[i
] = (struct cifs_ace
*) (acl_base
+ acl_size
);
756 #ifdef CONFIG_CIFS_DEBUG2
757 dump_ace(ppace
[i
], end_of_acl
);
759 if (mode_from_special_sid
&&
760 (compare_sids(&(ppace
[i
]->sid
),
761 &sid_unix_NFS_mode
) == 0)) {
763 * Full permissions are:
764 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
765 * S_IRWXU | S_IRWXG | S_IRWXO
767 fattr
->cf_mode
&= ~07777;
769 le32_to_cpu(ppace
[i
]->sid
.sub_auth
[2]);
771 } else if (compare_sids(&(ppace
[i
]->sid
), pownersid
) == 0)
772 access_flags_to_mode(ppace
[i
]->access_req
,
776 else if (compare_sids(&(ppace
[i
]->sid
), pgrpsid
) == 0)
777 access_flags_to_mode(ppace
[i
]->access_req
,
781 else if (compare_sids(&(ppace
[i
]->sid
), &sid_everyone
) == 0)
782 access_flags_to_mode(ppace
[i
]->access_req
,
786 else if (compare_sids(&(ppace
[i
]->sid
), &sid_authusers
) == 0)
787 access_flags_to_mode(ppace
[i
]->access_req
,
793 /* memcpy((void *)(&(cifscred->aces[i])),
795 sizeof(struct cifs_ace)); */
797 acl_base
= (char *)ppace
[i
];
798 acl_size
= le16_to_cpu(ppace
[i
]->size
);
808 static int set_chmod_dacl(struct cifs_acl
*pndacl
, struct cifs_sid
*pownersid
,
809 struct cifs_sid
*pgrpsid
, __u64 nmode
, bool modefromsid
)
813 struct cifs_acl
*pnndacl
;
815 pnndacl
= (struct cifs_acl
*)((char *)pndacl
+ sizeof(struct cifs_acl
));
818 struct cifs_ace
*pntace
=
819 (struct cifs_ace
*)((char *)pnndacl
+ size
);
822 pntace
->type
= ACCESS_ALLOWED
;
824 pntace
->access_req
= 0;
825 pntace
->sid
.num_subauth
= 3;
826 pntace
->sid
.revision
= 1;
827 for (i
= 0; i
< NUM_AUTHS
; i
++)
828 pntace
->sid
.authority
[i
] =
829 sid_unix_NFS_mode
.authority
[i
];
830 pntace
->sid
.sub_auth
[0] = sid_unix_NFS_mode
.sub_auth
[0];
831 pntace
->sid
.sub_auth
[1] = sid_unix_NFS_mode
.sub_auth
[1];
832 pntace
->sid
.sub_auth
[2] = cpu_to_le32(nmode
& 07777);
834 /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
835 pntace
->size
= cpu_to_le16(28);
840 size
+= fill_ace_for_sid((struct cifs_ace
*) ((char *)pnndacl
+ size
),
841 pownersid
, nmode
, S_IRWXU
);
843 size
+= fill_ace_for_sid((struct cifs_ace
*)((char *)pnndacl
+ size
),
844 pgrpsid
, nmode
, S_IRWXG
);
846 size
+= fill_ace_for_sid((struct cifs_ace
*)((char *)pnndacl
+ size
),
847 &sid_everyone
, nmode
, S_IRWXO
);
850 pndacl
->num_aces
= cpu_to_le32(num_aces
);
851 pndacl
->size
= cpu_to_le16(size
+ sizeof(struct cifs_acl
));
857 static int parse_sid(struct cifs_sid
*psid
, char *end_of_acl
)
859 /* BB need to add parm so we can store the SID BB */
861 /* validate that we do not go past end of ACL - sid must be at least 8
862 bytes long (assuming no sub-auths - e.g. the null SID */
863 if (end_of_acl
< (char *)psid
+ 8) {
864 cifs_dbg(VFS
, "ACL too small to parse SID %p\n", psid
);
868 #ifdef CONFIG_CIFS_DEBUG2
869 if (psid
->num_subauth
) {
871 cifs_dbg(FYI
, "SID revision %d num_auth %d\n",
872 psid
->revision
, psid
->num_subauth
);
874 for (i
= 0; i
< psid
->num_subauth
; i
++) {
875 cifs_dbg(FYI
, "SID sub_auth[%d]: 0x%x\n",
876 i
, le32_to_cpu(psid
->sub_auth
[i
]));
879 /* BB add length check to make sure that we do not have huge
880 num auths and therefore go off the end */
881 cifs_dbg(FYI
, "RID 0x%x\n",
882 le32_to_cpu(psid
->sub_auth
[psid
->num_subauth
-1]));
890 /* Convert CIFS ACL to POSIX form */
891 static int parse_sec_desc(struct cifs_sb_info
*cifs_sb
,
892 struct cifs_ntsd
*pntsd
, int acl_len
, struct cifs_fattr
*fattr
,
893 bool get_mode_from_special_sid
)
896 struct cifs_sid
*owner_sid_ptr
, *group_sid_ptr
;
897 struct cifs_acl
*dacl_ptr
; /* no need for SACL ptr */
898 char *end_of_acl
= ((char *)pntsd
) + acl_len
;
904 owner_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
905 le32_to_cpu(pntsd
->osidoffset
));
906 group_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
907 le32_to_cpu(pntsd
->gsidoffset
));
908 dacloffset
= le32_to_cpu(pntsd
->dacloffset
);
909 dacl_ptr
= (struct cifs_acl
*)((char *)pntsd
+ dacloffset
);
910 cifs_dbg(NOISY
, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
911 pntsd
->revision
, pntsd
->type
, le32_to_cpu(pntsd
->osidoffset
),
912 le32_to_cpu(pntsd
->gsidoffset
),
913 le32_to_cpu(pntsd
->sacloffset
), dacloffset
);
914 /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
915 rc
= parse_sid(owner_sid_ptr
, end_of_acl
);
917 cifs_dbg(FYI
, "%s: Error %d parsing Owner SID\n", __func__
, rc
);
920 rc
= sid_to_id(cifs_sb
, owner_sid_ptr
, fattr
, SIDOWNER
);
922 cifs_dbg(FYI
, "%s: Error %d mapping Owner SID to uid\n",
927 rc
= parse_sid(group_sid_ptr
, end_of_acl
);
929 cifs_dbg(FYI
, "%s: Error %d mapping Owner SID to gid\n",
933 rc
= sid_to_id(cifs_sb
, group_sid_ptr
, fattr
, SIDGROUP
);
935 cifs_dbg(FYI
, "%s: Error %d mapping Group SID to gid\n",
941 parse_dacl(dacl_ptr
, end_of_acl
, owner_sid_ptr
,
942 group_sid_ptr
, fattr
, get_mode_from_special_sid
);
944 cifs_dbg(FYI
, "no ACL\n"); /* BB grant all or default perms? */
949 /* Convert permission bits from mode to equivalent CIFS ACL */
950 static int build_sec_desc(struct cifs_ntsd
*pntsd
, struct cifs_ntsd
*pnntsd
,
951 __u32 secdesclen
, __u64 nmode
, kuid_t uid
, kgid_t gid
,
952 bool mode_from_sid
, int *aclflag
)
958 struct cifs_sid
*owner_sid_ptr
, *group_sid_ptr
;
959 struct cifs_sid
*nowner_sid_ptr
, *ngroup_sid_ptr
;
960 struct cifs_acl
*dacl_ptr
= NULL
; /* no need for SACL ptr */
961 struct cifs_acl
*ndacl_ptr
= NULL
; /* no need for SACL ptr */
963 if (nmode
!= NO_CHANGE_64
) { /* chmod */
964 owner_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
965 le32_to_cpu(pntsd
->osidoffset
));
966 group_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
967 le32_to_cpu(pntsd
->gsidoffset
));
968 dacloffset
= le32_to_cpu(pntsd
->dacloffset
);
969 dacl_ptr
= (struct cifs_acl
*)((char *)pntsd
+ dacloffset
);
970 ndacloffset
= sizeof(struct cifs_ntsd
);
971 ndacl_ptr
= (struct cifs_acl
*)((char *)pnntsd
+ ndacloffset
);
972 ndacl_ptr
->revision
= dacl_ptr
->revision
;
974 ndacl_ptr
->num_aces
= 0;
976 rc
= set_chmod_dacl(ndacl_ptr
, owner_sid_ptr
, group_sid_ptr
,
977 nmode
, mode_from_sid
);
978 sidsoffset
= ndacloffset
+ le16_to_cpu(ndacl_ptr
->size
);
979 /* copy sec desc control portion & owner and group sids */
980 copy_sec_desc(pntsd
, pnntsd
, sidsoffset
);
981 *aclflag
= CIFS_ACL_DACL
;
983 memcpy(pnntsd
, pntsd
, secdesclen
);
984 if (uid_valid(uid
)) { /* chown */
986 owner_sid_ptr
= (struct cifs_sid
*)((char *)pnntsd
+
987 le32_to_cpu(pnntsd
->osidoffset
));
988 nowner_sid_ptr
= kmalloc(sizeof(struct cifs_sid
),
992 id
= from_kuid(&init_user_ns
, uid
);
993 rc
= id_to_sid(id
, SIDOWNER
, nowner_sid_ptr
);
995 cifs_dbg(FYI
, "%s: Mapping error %d for owner id %d\n",
997 kfree(nowner_sid_ptr
);
1000 cifs_copy_sid(owner_sid_ptr
, nowner_sid_ptr
);
1001 kfree(nowner_sid_ptr
);
1002 *aclflag
= CIFS_ACL_OWNER
;
1004 if (gid_valid(gid
)) { /* chgrp */
1006 group_sid_ptr
= (struct cifs_sid
*)((char *)pnntsd
+
1007 le32_to_cpu(pnntsd
->gsidoffset
));
1008 ngroup_sid_ptr
= kmalloc(sizeof(struct cifs_sid
),
1010 if (!ngroup_sid_ptr
)
1012 id
= from_kgid(&init_user_ns
, gid
);
1013 rc
= id_to_sid(id
, SIDGROUP
, ngroup_sid_ptr
);
1015 cifs_dbg(FYI
, "%s: Mapping error %d for group id %d\n",
1017 kfree(ngroup_sid_ptr
);
1020 cifs_copy_sid(group_sid_ptr
, ngroup_sid_ptr
);
1021 kfree(ngroup_sid_ptr
);
1022 *aclflag
= CIFS_ACL_GROUP
;
1029 struct cifs_ntsd
*get_cifs_acl_by_fid(struct cifs_sb_info
*cifs_sb
,
1030 const struct cifs_fid
*cifsfid
, u32
*pacllen
)
1032 struct cifs_ntsd
*pntsd
= NULL
;
1035 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
1038 return ERR_CAST(tlink
);
1041 rc
= CIFSSMBGetCIFSACL(xid
, tlink_tcon(tlink
), cifsfid
->netfid
, &pntsd
,
1045 cifs_put_tlink(tlink
);
1047 cifs_dbg(FYI
, "%s: rc = %d ACL len %d\n", __func__
, rc
, *pacllen
);
1053 static struct cifs_ntsd
*get_cifs_acl_by_path(struct cifs_sb_info
*cifs_sb
,
1054 const char *path
, u32
*pacllen
)
1056 struct cifs_ntsd
*pntsd
= NULL
;
1059 int rc
, create_options
= 0;
1060 struct cifs_tcon
*tcon
;
1061 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
1062 struct cifs_fid fid
;
1063 struct cifs_open_parms oparms
;
1066 return ERR_CAST(tlink
);
1068 tcon
= tlink_tcon(tlink
);
1071 if (backup_cred(cifs_sb
))
1072 create_options
|= CREATE_OPEN_BACKUP_INTENT
;
1075 oparms
.cifs_sb
= cifs_sb
;
1076 oparms
.desired_access
= READ_CONTROL
;
1077 oparms
.create_options
= create_options
;
1078 oparms
.disposition
= FILE_OPEN
;
1081 oparms
.reconnect
= false;
1083 rc
= CIFS_open(xid
, &oparms
, &oplock
, NULL
);
1085 rc
= CIFSSMBGetCIFSACL(xid
, tcon
, fid
.netfid
, &pntsd
, pacllen
);
1086 CIFSSMBClose(xid
, tcon
, fid
.netfid
);
1089 cifs_put_tlink(tlink
);
1092 cifs_dbg(FYI
, "%s: rc = %d ACL len %d\n", __func__
, rc
, *pacllen
);
1098 /* Retrieve an ACL from the server */
1099 struct cifs_ntsd
*get_cifs_acl(struct cifs_sb_info
*cifs_sb
,
1100 struct inode
*inode
, const char *path
,
1103 struct cifs_ntsd
*pntsd
= NULL
;
1104 struct cifsFileInfo
*open_file
= NULL
;
1107 open_file
= find_readable_file(CIFS_I(inode
), true);
1109 return get_cifs_acl_by_path(cifs_sb
, path
, pacllen
);
1111 pntsd
= get_cifs_acl_by_fid(cifs_sb
, &open_file
->fid
, pacllen
);
1112 cifsFileInfo_put(open_file
);
1116 /* Set an ACL on the server */
1117 int set_cifs_acl(struct cifs_ntsd
*pnntsd
, __u32 acllen
,
1118 struct inode
*inode
, const char *path
, int aclflag
)
1122 int rc
, access_flags
, create_options
= 0;
1123 struct cifs_tcon
*tcon
;
1124 struct cifs_sb_info
*cifs_sb
= CIFS_SB(inode
->i_sb
);
1125 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
1126 struct cifs_fid fid
;
1127 struct cifs_open_parms oparms
;
1130 return PTR_ERR(tlink
);
1132 tcon
= tlink_tcon(tlink
);
1135 if (backup_cred(cifs_sb
))
1136 create_options
|= CREATE_OPEN_BACKUP_INTENT
;
1138 if (aclflag
== CIFS_ACL_OWNER
|| aclflag
== CIFS_ACL_GROUP
)
1139 access_flags
= WRITE_OWNER
;
1141 access_flags
= WRITE_DAC
;
1144 oparms
.cifs_sb
= cifs_sb
;
1145 oparms
.desired_access
= access_flags
;
1146 oparms
.create_options
= create_options
;
1147 oparms
.disposition
= FILE_OPEN
;
1150 oparms
.reconnect
= false;
1152 rc
= CIFS_open(xid
, &oparms
, &oplock
, NULL
);
1154 cifs_dbg(VFS
, "Unable to open file to set ACL\n");
1158 rc
= CIFSSMBSetCIFSACL(xid
, tcon
, fid
.netfid
, pnntsd
, acllen
, aclflag
);
1159 cifs_dbg(NOISY
, "SetCIFSACL rc = %d\n", rc
);
1161 CIFSSMBClose(xid
, tcon
, fid
.netfid
);
1164 cifs_put_tlink(tlink
);
1168 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1170 cifs_acl_to_fattr(struct cifs_sb_info
*cifs_sb
, struct cifs_fattr
*fattr
,
1171 struct inode
*inode
, bool mode_from_special_sid
,
1172 const char *path
, const struct cifs_fid
*pfid
)
1174 struct cifs_ntsd
*pntsd
= NULL
;
1177 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
1178 struct smb_version_operations
*ops
;
1180 cifs_dbg(NOISY
, "converting ACL to mode for %s\n", path
);
1183 return PTR_ERR(tlink
);
1185 ops
= tlink_tcon(tlink
)->ses
->server
->ops
;
1187 if (pfid
&& (ops
->get_acl_by_fid
))
1188 pntsd
= ops
->get_acl_by_fid(cifs_sb
, pfid
, &acllen
);
1189 else if (ops
->get_acl
)
1190 pntsd
= ops
->get_acl(cifs_sb
, inode
, path
, &acllen
);
1192 cifs_put_tlink(tlink
);
1195 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1196 if (IS_ERR(pntsd
)) {
1197 rc
= PTR_ERR(pntsd
);
1198 cifs_dbg(VFS
, "%s: error %d getting sec desc\n", __func__
, rc
);
1199 } else if (mode_from_special_sid
) {
1200 rc
= parse_sec_desc(cifs_sb
, pntsd
, acllen
, fattr
, true);
1202 /* get approximated mode from ACL */
1203 rc
= parse_sec_desc(cifs_sb
, pntsd
, acllen
, fattr
, false);
1206 cifs_dbg(VFS
, "parse sec desc failed rc = %d\n", rc
);
1209 cifs_put_tlink(tlink
);
1214 /* Convert mode bits to an ACL so we can update the ACL on the server */
1216 id_mode_to_cifs_acl(struct inode
*inode
, const char *path
, __u64 nmode
,
1217 kuid_t uid
, kgid_t gid
)
1220 int aclflag
= CIFS_ACL_DACL
; /* default flag to set */
1221 __u32 secdesclen
= 0;
1222 struct cifs_ntsd
*pntsd
= NULL
; /* acl obtained from server */
1223 struct cifs_ntsd
*pnntsd
= NULL
; /* modified acl to be sent to server */
1224 struct cifs_sb_info
*cifs_sb
= CIFS_SB(inode
->i_sb
);
1225 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
1226 struct smb_version_operations
*ops
;
1230 return PTR_ERR(tlink
);
1232 ops
= tlink_tcon(tlink
)->ses
->server
->ops
;
1234 cifs_dbg(NOISY
, "set ACL from mode for %s\n", path
);
1236 /* Get the security descriptor */
1238 if (ops
->get_acl
== NULL
) {
1239 cifs_put_tlink(tlink
);
1243 pntsd
= ops
->get_acl(cifs_sb
, inode
, path
, &secdesclen
);
1244 if (IS_ERR(pntsd
)) {
1245 rc
= PTR_ERR(pntsd
);
1246 cifs_dbg(VFS
, "%s: error %d getting sec desc\n", __func__
, rc
);
1247 cifs_put_tlink(tlink
);
1252 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1253 * as chmod disables ACEs and set the security descriptor. Allocate
1254 * memory for the smb header, set security descriptor request security
1255 * descriptor parameters, and secuirty descriptor itself
1257 secdesclen
= max_t(u32
, secdesclen
, DEFAULT_SEC_DESC_LEN
);
1258 pnntsd
= kmalloc(secdesclen
, GFP_KERNEL
);
1261 cifs_put_tlink(tlink
);
1265 if (cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MODE_FROM_SID
)
1266 mode_from_sid
= true;
1268 mode_from_sid
= false;
1270 rc
= build_sec_desc(pntsd
, pnntsd
, secdesclen
, nmode
, uid
, gid
,
1271 mode_from_sid
, &aclflag
);
1273 cifs_dbg(NOISY
, "build_sec_desc rc: %d\n", rc
);
1275 if (ops
->set_acl
== NULL
)
1279 /* Set the security descriptor */
1280 rc
= ops
->set_acl(pnntsd
, secdesclen
, inode
, path
, aclflag
);
1281 cifs_dbg(NOISY
, "set_cifs_acl rc: %d\n", rc
);
1283 cifs_put_tlink(tlink
);