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"
35 #include "fs_context.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}, {cpu_to_le32(11)} };
44 /* S-1-22-1 Unmapped Unix users */
45 static const struct cifs_sid sid_unix_users
= {1, 1, {0, 0, 0, 0, 0, 22},
46 {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
48 /* S-1-22-2 Unmapped Unix groups */
49 static const struct cifs_sid sid_unix_groups
= { 1, 1, {0, 0, 0, 0, 0, 22},
50 {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
53 * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
56 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
58 /* S-1-5-88-1 Unix uid */
59 static const struct cifs_sid sid_unix_NFS_users
= { 1, 2, {0, 0, 0, 0, 0, 5},
61 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
63 /* S-1-5-88-2 Unix gid */
64 static const struct cifs_sid sid_unix_NFS_groups
= { 1, 2, {0, 0, 0, 0, 0, 5},
66 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
68 /* S-1-5-88-3 Unix mode */
69 static const struct cifs_sid sid_unix_NFS_mode
= { 1, 2, {0, 0, 0, 0, 0, 5},
71 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
73 static const struct cred
*root_cred
;
76 cifs_idmap_key_instantiate(struct key
*key
, struct key_preparsed_payload
*prep
)
81 * If the payload is less than or equal to the size of a pointer, then
82 * an allocation here is wasteful. Just copy the data directly to the
83 * payload.value union member instead.
85 * With this however, you must check the datalen before trying to
86 * dereference payload.data!
88 if (prep
->datalen
<= sizeof(key
->payload
)) {
89 key
->payload
.data
[0] = NULL
;
90 memcpy(&key
->payload
, prep
->data
, prep
->datalen
);
92 payload
= kmemdup(prep
->data
, prep
->datalen
, GFP_KERNEL
);
95 key
->payload
.data
[0] = payload
;
98 key
->datalen
= prep
->datalen
;
103 cifs_idmap_key_destroy(struct key
*key
)
105 if (key
->datalen
> sizeof(key
->payload
))
106 kfree(key
->payload
.data
[0]);
109 static struct key_type cifs_idmap_key_type
= {
110 .name
= "cifs.idmap",
111 .instantiate
= cifs_idmap_key_instantiate
,
112 .destroy
= cifs_idmap_key_destroy
,
113 .describe
= user_describe
,
117 sid_to_key_str(struct cifs_sid
*sidptr
, unsigned int type
)
121 char *sidstr
, *strptr
;
122 unsigned long long id_auth_val
;
124 /* 3 bytes for prefix */
125 sidstr
= kmalloc(3 + SID_STRING_BASE_SIZE
+
126 (SID_STRING_SUBAUTH_SIZE
* sidptr
->num_subauth
),
132 len
= sprintf(strptr
, "%cs:S-%hhu", type
== SIDOWNER
? 'o' : 'g',
136 /* The authority field is a single 48-bit number */
137 id_auth_val
= (unsigned long long)sidptr
->authority
[5];
138 id_auth_val
|= (unsigned long long)sidptr
->authority
[4] << 8;
139 id_auth_val
|= (unsigned long long)sidptr
->authority
[3] << 16;
140 id_auth_val
|= (unsigned long long)sidptr
->authority
[2] << 24;
141 id_auth_val
|= (unsigned long long)sidptr
->authority
[1] << 32;
142 id_auth_val
|= (unsigned long long)sidptr
->authority
[0] << 48;
145 * MS-DTYP states that if the authority is >= 2^32, then it should be
146 * expressed as a hex value.
148 if (id_auth_val
<= UINT_MAX
)
149 len
= sprintf(strptr
, "-%llu", id_auth_val
);
151 len
= sprintf(strptr
, "-0x%llx", id_auth_val
);
155 for (i
= 0; i
< sidptr
->num_subauth
; ++i
) {
156 saval
= le32_to_cpu(sidptr
->sub_auth
[i
]);
157 len
= sprintf(strptr
, "-%u", saval
);
165 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
166 * the same returns zero, if they do not match returns non-zero.
169 compare_sids(const struct cifs_sid
*ctsid
, const struct cifs_sid
*cwsid
)
172 int num_subauth
, num_sat
, num_saw
;
174 if ((!ctsid
) || (!cwsid
))
177 /* compare the revision */
178 if (ctsid
->revision
!= cwsid
->revision
) {
179 if (ctsid
->revision
> cwsid
->revision
)
185 /* compare all of the six auth values */
186 for (i
= 0; i
< NUM_AUTHS
; ++i
) {
187 if (ctsid
->authority
[i
] != cwsid
->authority
[i
]) {
188 if (ctsid
->authority
[i
] > cwsid
->authority
[i
])
195 /* compare all of the subauth values if any */
196 num_sat
= ctsid
->num_subauth
;
197 num_saw
= cwsid
->num_subauth
;
198 num_subauth
= num_sat
< num_saw
? num_sat
: num_saw
;
200 for (i
= 0; i
< num_subauth
; ++i
) {
201 if (ctsid
->sub_auth
[i
] != cwsid
->sub_auth
[i
]) {
202 if (le32_to_cpu(ctsid
->sub_auth
[i
]) >
203 le32_to_cpu(cwsid
->sub_auth
[i
]))
211 return 0; /* sids compare/match */
215 is_well_known_sid(const struct cifs_sid
*psid
, uint32_t *puid
, bool is_group
)
219 const struct cifs_sid
*pwell_known_sid
;
221 if (!psid
|| (puid
== NULL
))
224 num_subauth
= psid
->num_subauth
;
226 /* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
227 if (num_subauth
== 2) {
229 pwell_known_sid
= &sid_unix_groups
;
231 pwell_known_sid
= &sid_unix_users
;
232 } else if (num_subauth
== 3) {
234 pwell_known_sid
= &sid_unix_NFS_groups
;
236 pwell_known_sid
= &sid_unix_NFS_users
;
240 /* compare the revision */
241 if (psid
->revision
!= pwell_known_sid
->revision
)
244 /* compare all of the six auth values */
245 for (i
= 0; i
< NUM_AUTHS
; ++i
) {
246 if (psid
->authority
[i
] != pwell_known_sid
->authority
[i
]) {
247 cifs_dbg(FYI
, "auth %d did not match\n", i
);
252 if (num_subauth
== 2) {
253 if (psid
->sub_auth
[0] != pwell_known_sid
->sub_auth
[0])
256 *puid
= le32_to_cpu(psid
->sub_auth
[1]);
257 } else /* 3 subauths, ie Windows/Mac style */ {
258 *puid
= le32_to_cpu(psid
->sub_auth
[0]);
259 if ((psid
->sub_auth
[0] != pwell_known_sid
->sub_auth
[0]) ||
260 (psid
->sub_auth
[1] != pwell_known_sid
->sub_auth
[1]))
263 *puid
= le32_to_cpu(psid
->sub_auth
[2]);
266 cifs_dbg(FYI
, "Unix UID %d returned from SID\n", *puid
);
267 return true; /* well known sid found, uid returned */
271 cifs_copy_sid(struct cifs_sid
*dst
, const struct cifs_sid
*src
)
275 dst
->revision
= src
->revision
;
276 dst
->num_subauth
= min_t(u8
, src
->num_subauth
, SID_MAX_SUB_AUTHORITIES
);
277 for (i
= 0; i
< NUM_AUTHS
; ++i
)
278 dst
->authority
[i
] = src
->authority
[i
];
279 for (i
= 0; i
< dst
->num_subauth
; ++i
)
280 dst
->sub_auth
[i
] = src
->sub_auth
[i
];
284 id_to_sid(unsigned int cid
, uint sidtype
, struct cifs_sid
*ssid
)
288 struct cifs_sid
*ksid
;
289 unsigned int ksid_size
;
290 char desc
[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
291 const struct cred
*saved_cred
;
293 rc
= snprintf(desc
, sizeof(desc
), "%ci:%u",
294 sidtype
== SIDOWNER
? 'o' : 'g', cid
);
295 if (rc
>= sizeof(desc
))
299 saved_cred
= override_creds(root_cred
);
300 sidkey
= request_key(&cifs_idmap_key_type
, desc
, "");
301 if (IS_ERR(sidkey
)) {
303 cifs_dbg(FYI
, "%s: Can't map %cid %u to a SID\n",
304 __func__
, sidtype
== SIDOWNER
? 'u' : 'g', cid
);
305 goto out_revert_creds
;
306 } else if (sidkey
->datalen
< CIFS_SID_BASE_SIZE
) {
308 cifs_dbg(FYI
, "%s: Downcall contained malformed key (datalen=%hu)\n",
309 __func__
, sidkey
->datalen
);
314 * A sid is usually too large to be embedded in payload.value, but if
315 * there are no subauthorities and the host has 8-byte pointers, then
318 ksid
= sidkey
->datalen
<= sizeof(sidkey
->payload
) ?
319 (struct cifs_sid
*)&sidkey
->payload
:
320 (struct cifs_sid
*)sidkey
->payload
.data
[0];
322 ksid_size
= CIFS_SID_BASE_SIZE
+ (ksid
->num_subauth
* sizeof(__le32
));
323 if (ksid_size
> sidkey
->datalen
) {
325 cifs_dbg(FYI
, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
326 __func__
, sidkey
->datalen
, ksid_size
);
330 cifs_copy_sid(ssid
, ksid
);
334 revert_creds(saved_cred
);
338 key_invalidate(sidkey
);
343 sid_to_id(struct cifs_sb_info
*cifs_sb
, struct cifs_sid
*psid
,
344 struct cifs_fattr
*fattr
, uint sidtype
)
349 const struct cred
*saved_cred
;
350 kuid_t fuid
= cifs_sb
->ctx
->linux_uid
;
351 kgid_t fgid
= cifs_sb
->ctx
->linux_gid
;
354 * If we have too many subauthorities, then something is really wrong.
355 * Just return an error.
357 if (unlikely(psid
->num_subauth
> SID_MAX_SUB_AUTHORITIES
)) {
358 cifs_dbg(FYI
, "%s: %u subauthorities is too many!\n",
359 __func__
, psid
->num_subauth
);
363 if ((cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_UID_FROM_ACL
) ||
364 (cifs_sb_master_tcon(cifs_sb
)->posix_extensions
)) {
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 ctx->linux_uid/linux_gid.
456 if (sidtype
== SIDOWNER
)
457 fattr
->cf_uid
= fuid
;
459 fattr
->cf_gid
= fgid
;
464 init_cifs_idmap(void)
470 cifs_dbg(FYI
, "Registering the %s key type\n",
471 cifs_idmap_key_type
.name
);
473 /* create an override credential set with a special thread keyring in
474 * which requests are cached
476 * this is used to prevent malicious redirections from being installed
479 cred
= prepare_kernel_cred(NULL
);
483 keyring
= keyring_alloc(".cifs_idmap",
484 GLOBAL_ROOT_UID
, GLOBAL_ROOT_GID
, cred
,
485 (KEY_POS_ALL
& ~KEY_POS_SETATTR
) |
486 KEY_USR_VIEW
| KEY_USR_READ
,
487 KEY_ALLOC_NOT_IN_QUOTA
, NULL
, NULL
);
488 if (IS_ERR(keyring
)) {
489 ret
= PTR_ERR(keyring
);
490 goto failed_put_cred
;
493 ret
= register_key_type(&cifs_idmap_key_type
);
497 /* instruct request_key() to use this special keyring as a cache for
498 * the results it looks up */
499 set_bit(KEY_FLAG_ROOT_CAN_CLEAR
, &keyring
->flags
);
500 cred
->thread_keyring
= keyring
;
501 cred
->jit_keyring
= KEY_REQKEY_DEFL_THREAD_KEYRING
;
504 cifs_dbg(FYI
, "cifs idmap keyring: %d\n", key_serial(keyring
));
515 exit_cifs_idmap(void)
517 key_revoke(root_cred
->thread_keyring
);
518 unregister_key_type(&cifs_idmap_key_type
);
520 cifs_dbg(FYI
, "Unregistered %s key type\n", cifs_idmap_key_type
.name
);
523 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
524 static void copy_sec_desc(const struct cifs_ntsd
*pntsd
,
525 struct cifs_ntsd
*pnntsd
, __u32 sidsoffset
)
527 struct cifs_sid
*owner_sid_ptr
, *group_sid_ptr
;
528 struct cifs_sid
*nowner_sid_ptr
, *ngroup_sid_ptr
;
530 /* copy security descriptor control portion */
531 pnntsd
->revision
= pntsd
->revision
;
532 pnntsd
->type
= pntsd
->type
;
533 pnntsd
->dacloffset
= cpu_to_le32(sizeof(struct cifs_ntsd
));
534 pnntsd
->sacloffset
= 0;
535 pnntsd
->osidoffset
= cpu_to_le32(sidsoffset
);
536 pnntsd
->gsidoffset
= cpu_to_le32(sidsoffset
+ sizeof(struct cifs_sid
));
539 owner_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
540 le32_to_cpu(pntsd
->osidoffset
));
541 nowner_sid_ptr
= (struct cifs_sid
*)((char *)pnntsd
+ sidsoffset
);
542 cifs_copy_sid(nowner_sid_ptr
, owner_sid_ptr
);
545 group_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
546 le32_to_cpu(pntsd
->gsidoffset
));
547 ngroup_sid_ptr
= (struct cifs_sid
*)((char *)pnntsd
+ sidsoffset
+
548 sizeof(struct cifs_sid
));
549 cifs_copy_sid(ngroup_sid_ptr
, group_sid_ptr
);
556 change posix mode to reflect permissions
557 pmode is the existing mode (we only want to overwrite part of this
558 bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
560 static void access_flags_to_mode(__le32 ace_flags
, int type
, umode_t
*pmode
,
561 umode_t
*pdenied
, umode_t mask
)
563 __u32 flags
= le32_to_cpu(ace_flags
);
565 * Do not assume "preferred" or "canonical" order.
566 * The first DENY or ALLOW ACE which matches perfectly is
567 * the permission to be used. Once allowed or denied, same
568 * permission in later ACEs do not matter.
571 /* If not already allowed, deny these bits */
572 if (type
== ACCESS_DENIED
) {
573 if (flags
& GENERIC_ALL
&&
574 !(*pmode
& mask
& 0777))
575 *pdenied
|= mask
& 0777;
577 if (((flags
& GENERIC_WRITE
) ||
578 ((flags
& FILE_WRITE_RIGHTS
) == FILE_WRITE_RIGHTS
)) &&
579 !(*pmode
& mask
& 0222))
580 *pdenied
|= mask
& 0222;
582 if (((flags
& GENERIC_READ
) ||
583 ((flags
& FILE_READ_RIGHTS
) == FILE_READ_RIGHTS
)) &&
584 !(*pmode
& mask
& 0444))
585 *pdenied
|= mask
& 0444;
587 if (((flags
& GENERIC_EXECUTE
) ||
588 ((flags
& FILE_EXEC_RIGHTS
) == FILE_EXEC_RIGHTS
)) &&
589 !(*pmode
& mask
& 0111))
590 *pdenied
|= mask
& 0111;
593 } else if (type
!= ACCESS_ALLOWED
) {
594 cifs_dbg(VFS
, "unknown access control type %d\n", type
);
597 /* else ACCESS_ALLOWED type */
599 if ((flags
& GENERIC_ALL
) &&
600 !(*pdenied
& mask
& 0777)) {
601 *pmode
|= mask
& 0777;
602 cifs_dbg(NOISY
, "all perms\n");
606 if (((flags
& GENERIC_WRITE
) ||
607 ((flags
& FILE_WRITE_RIGHTS
) == FILE_WRITE_RIGHTS
)) &&
608 !(*pdenied
& mask
& 0222))
609 *pmode
|= mask
& 0222;
611 if (((flags
& GENERIC_READ
) ||
612 ((flags
& FILE_READ_RIGHTS
) == FILE_READ_RIGHTS
)) &&
613 !(*pdenied
& mask
& 0444))
614 *pmode
|= mask
& 0444;
616 if (((flags
& GENERIC_EXECUTE
) ||
617 ((flags
& FILE_EXEC_RIGHTS
) == FILE_EXEC_RIGHTS
)) &&
618 !(*pdenied
& mask
& 0111))
619 *pmode
|= mask
& 0111;
621 /* If DELETE_CHILD is set only on an owner ACE, set sticky bit */
622 if (flags
& FILE_DELETE_CHILD
) {
623 if (mask
== ACL_OWNER_MASK
) {
624 if (!(*pdenied
& 01000))
626 } else if (!(*pdenied
& 01000)) {
632 cifs_dbg(NOISY
, "access flags 0x%x mode now %04o\n", flags
, *pmode
);
637 Generate access flags to reflect permissions mode is the existing mode.
638 This function is called for every ACE in the DACL whose SID matches
639 with either owner or group or everyone.
642 static void mode_to_access_flags(umode_t mode
, umode_t bits_to_use
,
645 /* reset access mask */
648 /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
651 /* check for R/W/X UGO since we do not know whose flags
652 is this but we have cleared all the bits sans RWX for
653 either user or group or other as per bits_to_use */
655 *pace_flags
|= SET_FILE_READ_RIGHTS
;
657 *pace_flags
|= SET_FILE_WRITE_RIGHTS
;
659 *pace_flags
|= SET_FILE_EXEC_RIGHTS
;
661 cifs_dbg(NOISY
, "mode: %04o, access flags now 0x%x\n",
666 static __u16
fill_ace_for_sid(struct cifs_ace
*pntace
,
667 const struct cifs_sid
*psid
, __u64 nmode
,
668 umode_t bits
, __u8 access_type
,
669 bool allow_delete_child
)
673 __u32 access_req
= 0;
675 pntace
->type
= access_type
;
677 mode_to_access_flags(nmode
, bits
, &access_req
);
679 if (access_type
== ACCESS_ALLOWED
&& allow_delete_child
)
680 access_req
|= FILE_DELETE_CHILD
;
682 if (access_type
== ACCESS_ALLOWED
&& !access_req
)
683 access_req
= SET_MINIMUM_RIGHTS
;
684 else if (access_type
== ACCESS_DENIED
)
685 access_req
&= ~SET_MINIMUM_RIGHTS
;
687 pntace
->access_req
= cpu_to_le32(access_req
);
689 pntace
->sid
.revision
= psid
->revision
;
690 pntace
->sid
.num_subauth
= psid
->num_subauth
;
691 for (i
= 0; i
< NUM_AUTHS
; i
++)
692 pntace
->sid
.authority
[i
] = psid
->authority
[i
];
693 for (i
= 0; i
< psid
->num_subauth
; i
++)
694 pntace
->sid
.sub_auth
[i
] = psid
->sub_auth
[i
];
696 size
= 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid
->num_subauth
* 4);
697 pntace
->size
= cpu_to_le16(size
);
703 #ifdef CONFIG_CIFS_DEBUG2
704 static void dump_ace(struct cifs_ace
*pace
, char *end_of_acl
)
708 /* validate that we do not go past end of acl */
710 if (le16_to_cpu(pace
->size
) < 16) {
711 cifs_dbg(VFS
, "ACE too small %d\n", le16_to_cpu(pace
->size
));
715 if (end_of_acl
< (char *)pace
+ le16_to_cpu(pace
->size
)) {
716 cifs_dbg(VFS
, "ACL too small to parse ACE\n");
720 num_subauth
= pace
->sid
.num_subauth
;
723 cifs_dbg(FYI
, "ACE revision %d num_auth %d type %d flags %d size %d\n",
724 pace
->sid
.revision
, pace
->sid
.num_subauth
, pace
->type
,
725 pace
->flags
, le16_to_cpu(pace
->size
));
726 for (i
= 0; i
< num_subauth
; ++i
) {
727 cifs_dbg(FYI
, "ACE sub_auth[%d]: 0x%x\n",
728 i
, le32_to_cpu(pace
->sid
.sub_auth
[i
]));
731 /* BB add length check to make sure that we do not have huge
732 num auths and therefore go off the end */
739 static void parse_dacl(struct cifs_acl
*pdacl
, char *end_of_acl
,
740 struct cifs_sid
*pownersid
, struct cifs_sid
*pgrpsid
,
741 struct cifs_fattr
*fattr
, bool mode_from_special_sid
)
747 struct cifs_ace
**ppace
;
749 /* BB need to add parm so we can store the SID BB */
752 /* no DACL in the security descriptor, set
753 all the permissions for user/group/other */
754 fattr
->cf_mode
|= 0777;
758 /* validate that we do not go past end of acl */
759 if (end_of_acl
< (char *)pdacl
+ le16_to_cpu(pdacl
->size
)) {
760 cifs_dbg(VFS
, "ACL too small to parse DACL\n");
764 cifs_dbg(NOISY
, "DACL revision %d size %d num aces %d\n",
765 le16_to_cpu(pdacl
->revision
), le16_to_cpu(pdacl
->size
),
766 le32_to_cpu(pdacl
->num_aces
));
768 /* reset rwx permissions for user/group/other.
769 Also, if num_aces is 0 i.e. DACL has no ACEs,
770 user/group/other have no permissions */
771 fattr
->cf_mode
&= ~(0777);
773 acl_base
= (char *)pdacl
;
774 acl_size
= sizeof(struct cifs_acl
);
776 num_aces
= le32_to_cpu(pdacl
->num_aces
);
778 umode_t denied_mode
= 0;
780 if (num_aces
> ULONG_MAX
/ sizeof(struct cifs_ace
*))
782 ppace
= kmalloc_array(num_aces
, sizeof(struct cifs_ace
*),
787 for (i
= 0; i
< num_aces
; ++i
) {
788 ppace
[i
] = (struct cifs_ace
*) (acl_base
+ acl_size
);
789 #ifdef CONFIG_CIFS_DEBUG2
790 dump_ace(ppace
[i
], end_of_acl
);
792 if (mode_from_special_sid
&&
793 (compare_sids(&(ppace
[i
]->sid
),
794 &sid_unix_NFS_mode
) == 0)) {
796 * Full permissions are:
797 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
798 * S_IRWXU | S_IRWXG | S_IRWXO
800 fattr
->cf_mode
&= ~07777;
802 le32_to_cpu(ppace
[i
]->sid
.sub_auth
[2]);
805 if (compare_sids(&(ppace
[i
]->sid
), pownersid
) == 0) {
806 access_flags_to_mode(ppace
[i
]->access_req
,
811 } else if (compare_sids(&(ppace
[i
]->sid
), pgrpsid
) == 0) {
812 access_flags_to_mode(ppace
[i
]->access_req
,
817 } else if ((compare_sids(&(ppace
[i
]->sid
), &sid_everyone
) == 0) ||
818 (compare_sids(&(ppace
[i
]->sid
), &sid_authusers
) == 0)) {
819 access_flags_to_mode(ppace
[i
]->access_req
,
828 /* memcpy((void *)(&(cifscred->aces[i])),
830 sizeof(struct cifs_ace)); */
832 acl_base
= (char *)ppace
[i
];
833 acl_size
= le16_to_cpu(ppace
[i
]->size
);
842 unsigned int setup_authusers_ACE(struct cifs_ace
*pntace
)
845 unsigned int ace_size
= 20;
847 pntace
->type
= ACCESS_ALLOWED_ACE_TYPE
;
849 pntace
->access_req
= cpu_to_le32(GENERIC_ALL
);
850 pntace
->sid
.num_subauth
= 1;
851 pntace
->sid
.revision
= 1;
852 for (i
= 0; i
< NUM_AUTHS
; i
++)
853 pntace
->sid
.authority
[i
] = sid_authusers
.authority
[i
];
855 pntace
->sid
.sub_auth
[0] = sid_authusers
.sub_auth
[0];
857 /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
858 pntace
->size
= cpu_to_le16(ace_size
);
863 * Fill in the special SID based on the mode. See
864 * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
866 unsigned int setup_special_mode_ACE(struct cifs_ace
*pntace
, __u64 nmode
)
869 unsigned int ace_size
= 28;
871 pntace
->type
= ACCESS_DENIED_ACE_TYPE
;
873 pntace
->access_req
= 0;
874 pntace
->sid
.num_subauth
= 3;
875 pntace
->sid
.revision
= 1;
876 for (i
= 0; i
< NUM_AUTHS
; i
++)
877 pntace
->sid
.authority
[i
] = sid_unix_NFS_mode
.authority
[i
];
879 pntace
->sid
.sub_auth
[0] = sid_unix_NFS_mode
.sub_auth
[0];
880 pntace
->sid
.sub_auth
[1] = sid_unix_NFS_mode
.sub_auth
[1];
881 pntace
->sid
.sub_auth
[2] = cpu_to_le32(nmode
& 07777);
883 /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
884 pntace
->size
= cpu_to_le16(ace_size
);
888 unsigned int setup_special_user_owner_ACE(struct cifs_ace
*pntace
)
891 unsigned int ace_size
= 28;
893 pntace
->type
= ACCESS_ALLOWED_ACE_TYPE
;
895 pntace
->access_req
= cpu_to_le32(GENERIC_ALL
);
896 pntace
->sid
.num_subauth
= 3;
897 pntace
->sid
.revision
= 1;
898 for (i
= 0; i
< NUM_AUTHS
; i
++)
899 pntace
->sid
.authority
[i
] = sid_unix_NFS_users
.authority
[i
];
901 pntace
->sid
.sub_auth
[0] = sid_unix_NFS_users
.sub_auth
[0];
902 pntace
->sid
.sub_auth
[1] = sid_unix_NFS_users
.sub_auth
[1];
903 pntace
->sid
.sub_auth
[2] = cpu_to_le32(current_fsgid().val
);
905 /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
906 pntace
->size
= cpu_to_le16(ace_size
);
910 static int set_chmod_dacl(struct cifs_acl
*pndacl
, struct cifs_sid
*pownersid
,
911 struct cifs_sid
*pgrpsid
, __u64
*pnmode
, bool modefromsid
)
915 struct cifs_acl
*pnndacl
;
920 __u64 deny_user_mode
= 0;
921 __u64 deny_group_mode
= 0;
922 bool sticky_set
= false;
924 pnndacl
= (struct cifs_acl
*)((char *)pndacl
+ sizeof(struct cifs_acl
));
929 struct cifs_ace
*pntace
=
930 (struct cifs_ace
*)((char *)pnndacl
+ size
);
932 size
+= setup_special_mode_ACE(pntace
, nmode
);
938 * We'll try to keep the mode as requested by the user.
939 * But in cases where we cannot meaningfully convert that
940 * into ACL, return back the updated mode, so that it is
941 * updated in the inode.
944 if (!memcmp(pownersid
, pgrpsid
, sizeof(struct cifs_sid
))) {
946 * Case when owner and group SIDs are the same.
947 * Set the more restrictive of the two modes.
949 user_mode
= nmode
& (nmode
<< 3) & 0700;
950 group_mode
= nmode
& (nmode
>> 3) & 0070;
952 user_mode
= nmode
& 0700;
953 group_mode
= nmode
& 0070;
956 other_mode
= nmode
& 0007;
958 /* We need DENY ACE when the perm is more restrictive than the next sets. */
959 deny_user_mode
= ~(user_mode
) & ((group_mode
<< 3) | (other_mode
<< 6)) & 0700;
960 deny_group_mode
= ~(group_mode
) & (other_mode
<< 3) & 0070;
962 *pnmode
= user_mode
| group_mode
| other_mode
| (nmode
& ~0777);
964 /* This tells if we should allow delete child for group and everyone. */
968 if (deny_user_mode
) {
969 size
+= fill_ace_for_sid((struct cifs_ace
*)((char *)pnndacl
+ size
),
970 pownersid
, deny_user_mode
, 0700, ACCESS_DENIED
, false);
973 /* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/
974 if (deny_group_mode
&& !(deny_group_mode
& (user_mode
>> 3))) {
975 size
+= fill_ace_for_sid((struct cifs_ace
*)((char *)pnndacl
+ size
),
976 pgrpsid
, deny_group_mode
, 0070, ACCESS_DENIED
, false);
979 size
+= fill_ace_for_sid((struct cifs_ace
*) ((char *)pnndacl
+ size
),
980 pownersid
, user_mode
, 0700, ACCESS_ALLOWED
, true);
982 /* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */
983 if (deny_group_mode
&& (deny_group_mode
& (user_mode
>> 3))) {
984 size
+= fill_ace_for_sid((struct cifs_ace
*)((char *)pnndacl
+ size
),
985 pgrpsid
, deny_group_mode
, 0070, ACCESS_DENIED
, false);
988 size
+= fill_ace_for_sid((struct cifs_ace
*)((char *)pnndacl
+ size
),
989 pgrpsid
, group_mode
, 0070, ACCESS_ALLOWED
, !sticky_set
);
991 size
+= fill_ace_for_sid((struct cifs_ace
*)((char *)pnndacl
+ size
),
992 &sid_everyone
, other_mode
, 0007, ACCESS_ALLOWED
, !sticky_set
);
996 pndacl
->num_aces
= cpu_to_le32(num_aces
);
997 pndacl
->size
= cpu_to_le16(size
+ sizeof(struct cifs_acl
));
1003 static int parse_sid(struct cifs_sid
*psid
, char *end_of_acl
)
1005 /* BB need to add parm so we can store the SID BB */
1007 /* validate that we do not go past end of ACL - sid must be at least 8
1008 bytes long (assuming no sub-auths - e.g. the null SID */
1009 if (end_of_acl
< (char *)psid
+ 8) {
1010 cifs_dbg(VFS
, "ACL too small to parse SID %p\n", psid
);
1014 #ifdef CONFIG_CIFS_DEBUG2
1015 if (psid
->num_subauth
) {
1017 cifs_dbg(FYI
, "SID revision %d num_auth %d\n",
1018 psid
->revision
, psid
->num_subauth
);
1020 for (i
= 0; i
< psid
->num_subauth
; i
++) {
1021 cifs_dbg(FYI
, "SID sub_auth[%d]: 0x%x\n",
1022 i
, le32_to_cpu(psid
->sub_auth
[i
]));
1025 /* BB add length check to make sure that we do not have huge
1026 num auths and therefore go off the end */
1027 cifs_dbg(FYI
, "RID 0x%x\n",
1028 le32_to_cpu(psid
->sub_auth
[psid
->num_subauth
-1]));
1036 /* Convert CIFS ACL to POSIX form */
1037 static int parse_sec_desc(struct cifs_sb_info
*cifs_sb
,
1038 struct cifs_ntsd
*pntsd
, int acl_len
, struct cifs_fattr
*fattr
,
1039 bool get_mode_from_special_sid
)
1042 struct cifs_sid
*owner_sid_ptr
, *group_sid_ptr
;
1043 struct cifs_acl
*dacl_ptr
; /* no need for SACL ptr */
1044 char *end_of_acl
= ((char *)pntsd
) + acl_len
;
1050 owner_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
1051 le32_to_cpu(pntsd
->osidoffset
));
1052 group_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
1053 le32_to_cpu(pntsd
->gsidoffset
));
1054 dacloffset
= le32_to_cpu(pntsd
->dacloffset
);
1055 dacl_ptr
= (struct cifs_acl
*)((char *)pntsd
+ dacloffset
);
1056 cifs_dbg(NOISY
, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1057 pntsd
->revision
, pntsd
->type
, le32_to_cpu(pntsd
->osidoffset
),
1058 le32_to_cpu(pntsd
->gsidoffset
),
1059 le32_to_cpu(pntsd
->sacloffset
), dacloffset
);
1060 /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1061 rc
= parse_sid(owner_sid_ptr
, end_of_acl
);
1063 cifs_dbg(FYI
, "%s: Error %d parsing Owner SID\n", __func__
, rc
);
1066 rc
= sid_to_id(cifs_sb
, owner_sid_ptr
, fattr
, SIDOWNER
);
1068 cifs_dbg(FYI
, "%s: Error %d mapping Owner SID to uid\n",
1073 rc
= parse_sid(group_sid_ptr
, end_of_acl
);
1075 cifs_dbg(FYI
, "%s: Error %d mapping Owner SID to gid\n",
1079 rc
= sid_to_id(cifs_sb
, group_sid_ptr
, fattr
, SIDGROUP
);
1081 cifs_dbg(FYI
, "%s: Error %d mapping Group SID to gid\n",
1087 parse_dacl(dacl_ptr
, end_of_acl
, owner_sid_ptr
,
1088 group_sid_ptr
, fattr
, get_mode_from_special_sid
);
1090 cifs_dbg(FYI
, "no ACL\n"); /* BB grant all or default perms? */
1095 /* Convert permission bits from mode to equivalent CIFS ACL */
1096 static int build_sec_desc(struct cifs_ntsd
*pntsd
, struct cifs_ntsd
*pnntsd
,
1097 __u32 secdesclen
, __u64
*pnmode
, kuid_t uid
, kgid_t gid
,
1098 bool mode_from_sid
, bool id_from_sid
, int *aclflag
)
1104 struct cifs_sid
*owner_sid_ptr
, *group_sid_ptr
;
1105 struct cifs_sid
*nowner_sid_ptr
, *ngroup_sid_ptr
;
1106 struct cifs_acl
*dacl_ptr
= NULL
; /* no need for SACL ptr */
1107 struct cifs_acl
*ndacl_ptr
= NULL
; /* no need for SACL ptr */
1109 if (pnmode
&& *pnmode
!= NO_CHANGE_64
) { /* chmod */
1110 owner_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
1111 le32_to_cpu(pntsd
->osidoffset
));
1112 group_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
1113 le32_to_cpu(pntsd
->gsidoffset
));
1114 dacloffset
= le32_to_cpu(pntsd
->dacloffset
);
1115 dacl_ptr
= (struct cifs_acl
*)((char *)pntsd
+ dacloffset
);
1116 ndacloffset
= sizeof(struct cifs_ntsd
);
1117 ndacl_ptr
= (struct cifs_acl
*)((char *)pnntsd
+ ndacloffset
);
1118 ndacl_ptr
->revision
= dacl_ptr
->revision
;
1119 ndacl_ptr
->size
= 0;
1120 ndacl_ptr
->num_aces
= 0;
1122 rc
= set_chmod_dacl(ndacl_ptr
, owner_sid_ptr
, group_sid_ptr
,
1123 pnmode
, mode_from_sid
);
1124 sidsoffset
= ndacloffset
+ le16_to_cpu(ndacl_ptr
->size
);
1125 /* copy sec desc control portion & owner and group sids */
1126 copy_sec_desc(pntsd
, pnntsd
, sidsoffset
);
1127 *aclflag
= CIFS_ACL_DACL
;
1129 memcpy(pnntsd
, pntsd
, secdesclen
);
1130 if (uid_valid(uid
)) { /* chown */
1132 owner_sid_ptr
= (struct cifs_sid
*)((char *)pnntsd
+
1133 le32_to_cpu(pnntsd
->osidoffset
));
1134 nowner_sid_ptr
= kmalloc(sizeof(struct cifs_sid
),
1136 if (!nowner_sid_ptr
)
1138 id
= from_kuid(&init_user_ns
, uid
);
1140 struct owner_sid
*osid
= (struct owner_sid
*)nowner_sid_ptr
;
1141 /* Populate the user ownership fields S-1-5-88-1 */
1144 osid
->Authority
[5] = 5;
1145 osid
->SubAuthorities
[0] = cpu_to_le32(88);
1146 osid
->SubAuthorities
[1] = cpu_to_le32(1);
1147 osid
->SubAuthorities
[2] = cpu_to_le32(id
);
1148 } else { /* lookup sid with upcall */
1149 rc
= id_to_sid(id
, SIDOWNER
, nowner_sid_ptr
);
1151 cifs_dbg(FYI
, "%s: Mapping error %d for owner id %d\n",
1153 kfree(nowner_sid_ptr
);
1157 cifs_copy_sid(owner_sid_ptr
, nowner_sid_ptr
);
1158 kfree(nowner_sid_ptr
);
1159 *aclflag
= CIFS_ACL_OWNER
;
1161 if (gid_valid(gid
)) { /* chgrp */
1163 group_sid_ptr
= (struct cifs_sid
*)((char *)pnntsd
+
1164 le32_to_cpu(pnntsd
->gsidoffset
));
1165 ngroup_sid_ptr
= kmalloc(sizeof(struct cifs_sid
),
1167 if (!ngroup_sid_ptr
)
1169 id
= from_kgid(&init_user_ns
, gid
);
1171 struct owner_sid
*gsid
= (struct owner_sid
*)ngroup_sid_ptr
;
1172 /* Populate the group ownership fields S-1-5-88-2 */
1175 gsid
->Authority
[5] = 5;
1176 gsid
->SubAuthorities
[0] = cpu_to_le32(88);
1177 gsid
->SubAuthorities
[1] = cpu_to_le32(2);
1178 gsid
->SubAuthorities
[2] = cpu_to_le32(id
);
1179 } else { /* lookup sid with upcall */
1180 rc
= id_to_sid(id
, SIDGROUP
, ngroup_sid_ptr
);
1182 cifs_dbg(FYI
, "%s: Mapping error %d for group id %d\n",
1184 kfree(ngroup_sid_ptr
);
1188 cifs_copy_sid(group_sid_ptr
, ngroup_sid_ptr
);
1189 kfree(ngroup_sid_ptr
);
1190 *aclflag
= CIFS_ACL_GROUP
;
1197 struct cifs_ntsd
*get_cifs_acl_by_fid(struct cifs_sb_info
*cifs_sb
,
1198 const struct cifs_fid
*cifsfid
, u32
*pacllen
,
1199 u32 __maybe_unused unused
)
1201 struct cifs_ntsd
*pntsd
= NULL
;
1204 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
1207 return ERR_CAST(tlink
);
1210 rc
= CIFSSMBGetCIFSACL(xid
, tlink_tcon(tlink
), cifsfid
->netfid
, &pntsd
,
1214 cifs_put_tlink(tlink
);
1216 cifs_dbg(FYI
, "%s: rc = %d ACL len %d\n", __func__
, rc
, *pacllen
);
1222 static struct cifs_ntsd
*get_cifs_acl_by_path(struct cifs_sb_info
*cifs_sb
,
1223 const char *path
, u32
*pacllen
)
1225 struct cifs_ntsd
*pntsd
= NULL
;
1229 struct cifs_tcon
*tcon
;
1230 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
1231 struct cifs_fid fid
;
1232 struct cifs_open_parms oparms
;
1235 return ERR_CAST(tlink
);
1237 tcon
= tlink_tcon(tlink
);
1241 oparms
.cifs_sb
= cifs_sb
;
1242 oparms
.desired_access
= READ_CONTROL
;
1243 oparms
.create_options
= cifs_create_options(cifs_sb
, 0);
1244 oparms
.disposition
= FILE_OPEN
;
1247 oparms
.reconnect
= false;
1249 rc
= CIFS_open(xid
, &oparms
, &oplock
, NULL
);
1251 rc
= CIFSSMBGetCIFSACL(xid
, tcon
, fid
.netfid
, &pntsd
, pacllen
);
1252 CIFSSMBClose(xid
, tcon
, fid
.netfid
);
1255 cifs_put_tlink(tlink
);
1258 cifs_dbg(FYI
, "%s: rc = %d ACL len %d\n", __func__
, rc
, *pacllen
);
1264 /* Retrieve an ACL from the server */
1265 struct cifs_ntsd
*get_cifs_acl(struct cifs_sb_info
*cifs_sb
,
1266 struct inode
*inode
, const char *path
,
1267 u32
*pacllen
, u32 info
)
1269 struct cifs_ntsd
*pntsd
= NULL
;
1270 struct cifsFileInfo
*open_file
= NULL
;
1273 open_file
= find_readable_file(CIFS_I(inode
), true);
1275 return get_cifs_acl_by_path(cifs_sb
, path
, pacllen
);
1277 pntsd
= get_cifs_acl_by_fid(cifs_sb
, &open_file
->fid
, pacllen
, info
);
1278 cifsFileInfo_put(open_file
);
1282 /* Set an ACL on the server */
1283 int set_cifs_acl(struct cifs_ntsd
*pnntsd
, __u32 acllen
,
1284 struct inode
*inode
, const char *path
, int aclflag
)
1288 int rc
, access_flags
;
1289 struct cifs_tcon
*tcon
;
1290 struct cifs_sb_info
*cifs_sb
= CIFS_SB(inode
->i_sb
);
1291 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
1292 struct cifs_fid fid
;
1293 struct cifs_open_parms oparms
;
1296 return PTR_ERR(tlink
);
1298 tcon
= tlink_tcon(tlink
);
1301 if (aclflag
== CIFS_ACL_OWNER
|| aclflag
== CIFS_ACL_GROUP
)
1302 access_flags
= WRITE_OWNER
;
1304 access_flags
= WRITE_DAC
;
1307 oparms
.cifs_sb
= cifs_sb
;
1308 oparms
.desired_access
= access_flags
;
1309 oparms
.create_options
= cifs_create_options(cifs_sb
, 0);
1310 oparms
.disposition
= FILE_OPEN
;
1313 oparms
.reconnect
= false;
1315 rc
= CIFS_open(xid
, &oparms
, &oplock
, NULL
);
1317 cifs_dbg(VFS
, "Unable to open file to set ACL\n");
1321 rc
= CIFSSMBSetCIFSACL(xid
, tcon
, fid
.netfid
, pnntsd
, acllen
, aclflag
);
1322 cifs_dbg(NOISY
, "SetCIFSACL rc = %d\n", rc
);
1324 CIFSSMBClose(xid
, tcon
, fid
.netfid
);
1327 cifs_put_tlink(tlink
);
1331 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1333 cifs_acl_to_fattr(struct cifs_sb_info
*cifs_sb
, struct cifs_fattr
*fattr
,
1334 struct inode
*inode
, bool mode_from_special_sid
,
1335 const char *path
, const struct cifs_fid
*pfid
)
1337 struct cifs_ntsd
*pntsd
= NULL
;
1340 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
1341 struct smb_version_operations
*ops
;
1344 cifs_dbg(NOISY
, "converting ACL to mode for %s\n", path
);
1347 return PTR_ERR(tlink
);
1349 ops
= tlink_tcon(tlink
)->ses
->server
->ops
;
1351 if (pfid
&& (ops
->get_acl_by_fid
))
1352 pntsd
= ops
->get_acl_by_fid(cifs_sb
, pfid
, &acllen
, info
);
1353 else if (ops
->get_acl
)
1354 pntsd
= ops
->get_acl(cifs_sb
, inode
, path
, &acllen
, info
);
1356 cifs_put_tlink(tlink
);
1359 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1360 if (IS_ERR(pntsd
)) {
1361 rc
= PTR_ERR(pntsd
);
1362 cifs_dbg(VFS
, "%s: error %d getting sec desc\n", __func__
, rc
);
1363 } else if (mode_from_special_sid
) {
1364 rc
= parse_sec_desc(cifs_sb
, pntsd
, acllen
, fattr
, true);
1367 /* get approximated mode from ACL */
1368 rc
= parse_sec_desc(cifs_sb
, pntsd
, acllen
, fattr
, false);
1371 cifs_dbg(VFS
, "parse sec desc failed rc = %d\n", rc
);
1374 cifs_put_tlink(tlink
);
1379 /* Convert mode bits to an ACL so we can update the ACL on the server */
1381 id_mode_to_cifs_acl(struct inode
*inode
, const char *path
, __u64
*pnmode
,
1382 kuid_t uid
, kgid_t gid
)
1385 int aclflag
= CIFS_ACL_DACL
; /* default flag to set */
1386 __u32 secdesclen
= 0;
1387 struct cifs_ntsd
*pntsd
= NULL
; /* acl obtained from server */
1388 struct cifs_ntsd
*pnntsd
= NULL
; /* modified acl to be sent to server */
1389 struct cifs_sb_info
*cifs_sb
= CIFS_SB(inode
->i_sb
);
1390 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
1391 struct smb_version_operations
*ops
;
1392 bool mode_from_sid
, id_from_sid
;
1396 return PTR_ERR(tlink
);
1398 ops
= tlink_tcon(tlink
)->ses
->server
->ops
;
1400 cifs_dbg(NOISY
, "set ACL from mode for %s\n", path
);
1402 /* Get the security descriptor */
1404 if (ops
->get_acl
== NULL
) {
1405 cifs_put_tlink(tlink
);
1409 pntsd
= ops
->get_acl(cifs_sb
, inode
, path
, &secdesclen
, info
);
1410 if (IS_ERR(pntsd
)) {
1411 rc
= PTR_ERR(pntsd
);
1412 cifs_dbg(VFS
, "%s: error %d getting sec desc\n", __func__
, rc
);
1413 cifs_put_tlink(tlink
);
1418 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1419 * as chmod disables ACEs and set the security descriptor. Allocate
1420 * memory for the smb header, set security descriptor request security
1421 * descriptor parameters, and secuirty descriptor itself
1423 secdesclen
= max_t(u32
, secdesclen
, DEFAULT_SEC_DESC_LEN
);
1424 pnntsd
= kmalloc(secdesclen
, GFP_KERNEL
);
1427 cifs_put_tlink(tlink
);
1431 if (cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MODE_FROM_SID
)
1432 mode_from_sid
= true;
1434 mode_from_sid
= false;
1436 if (cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_UID_FROM_ACL
)
1439 id_from_sid
= false;
1441 rc
= build_sec_desc(pntsd
, pnntsd
, secdesclen
, pnmode
, uid
, gid
,
1442 mode_from_sid
, id_from_sid
, &aclflag
);
1444 cifs_dbg(NOISY
, "build_sec_desc rc: %d\n", rc
);
1446 if (ops
->set_acl
== NULL
)
1450 /* Set the security descriptor */
1451 rc
= ops
->set_acl(pnntsd
, secdesclen
, inode
, path
, aclflag
);
1452 cifs_dbg(NOISY
, "set_cifs_acl rc: %d\n", rc
);
1454 cifs_put_tlink(tlink
);