Merge tag 'regmap-fix-v5.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux/fpc-iii.git] / fs / cifs / cifsacl.c
blob562913e2b3f2e21d9718ed3aa8e9976d2982657b
1 /*
2 * fs/cifs/cifsacl.c
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
24 #include <linux/fs.h>
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>
30 #include "cifspdu.h"
31 #include "cifsglob.h"
32 #include "cifsacl.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},
60 {cpu_to_le32(88),
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},
65 {cpu_to_le32(88),
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},
70 {cpu_to_le32(88),
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;
75 static int
76 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
78 char *payload;
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);
91 } else {
92 payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
93 if (!payload)
94 return -ENOMEM;
95 key->payload.data[0] = payload;
98 key->datalen = prep->datalen;
99 return 0;
102 static inline void
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,
116 static char *
117 sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
119 int i, len;
120 unsigned int saval;
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),
127 GFP_KERNEL);
128 if (!sidstr)
129 return sidstr;
131 strptr = sidstr;
132 len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
133 sidptr->revision);
134 strptr += len;
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);
150 else
151 len = sprintf(strptr, "-0x%llx", id_auth_val);
153 strptr += len;
155 for (i = 0; i < sidptr->num_subauth; ++i) {
156 saval = le32_to_cpu(sidptr->sub_auth[i]);
157 len = sprintf(strptr, "-%u", saval);
158 strptr += len;
161 return sidstr;
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.
168 static int
169 compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
171 int i;
172 int num_subauth, num_sat, num_saw;
174 if ((!ctsid) || (!cwsid))
175 return 1;
177 /* compare the revision */
178 if (ctsid->revision != cwsid->revision) {
179 if (ctsid->revision > cwsid->revision)
180 return 1;
181 else
182 return -1;
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])
189 return 1;
190 else
191 return -1;
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;
199 if (num_subauth) {
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]))
204 return 1;
205 else
206 return -1;
211 return 0; /* sids compare/match */
214 static bool
215 is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
217 int i;
218 int num_subauth;
219 const struct cifs_sid *pwell_known_sid;
221 if (!psid || (puid == NULL))
222 return false;
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) {
228 if (is_group)
229 pwell_known_sid = &sid_unix_groups;
230 else
231 pwell_known_sid = &sid_unix_users;
232 } else if (num_subauth == 3) {
233 if (is_group)
234 pwell_known_sid = &sid_unix_NFS_groups;
235 else
236 pwell_known_sid = &sid_unix_NFS_users;
237 } else
238 return false;
240 /* compare the revision */
241 if (psid->revision != pwell_known_sid->revision)
242 return false;
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);
248 return false;
252 if (num_subauth == 2) {
253 if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
254 return false;
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]))
261 return false;
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 */
270 static void
271 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
273 int i;
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];
283 static int
284 id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
286 int rc;
287 struct key *sidkey;
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))
296 return -EINVAL;
298 rc = 0;
299 saved_cred = override_creds(root_cred);
300 sidkey = request_key(&cifs_idmap_key_type, desc, "");
301 if (IS_ERR(sidkey)) {
302 rc = -EINVAL;
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) {
307 rc = -EIO;
308 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
309 __func__, sidkey->datalen);
310 goto invalidate_key;
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
316 * it could be.
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) {
324 rc = -EIO;
325 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
326 __func__, sidkey->datalen, ksid_size);
327 goto invalidate_key;
330 cifs_copy_sid(ssid, ksid);
331 out_key_put:
332 key_put(sidkey);
333 out_revert_creds:
334 revert_creds(saved_cred);
335 return rc;
337 invalidate_key:
338 key_invalidate(sidkey);
339 goto out_key_put;
343 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
344 struct cifs_fattr *fattr, uint sidtype)
346 int rc = 0;
347 struct key *sidkey;
348 char *sidstr;
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);
360 return -EIO;
363 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
364 (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
365 uint32_t unix_id;
366 bool is_group;
368 if (sidtype != SIDOWNER)
369 is_group = true;
370 else
371 is_group = false;
373 if (is_well_known_sid(psid, &unix_id, is_group) == false)
374 goto try_upcall_to_get_id;
376 if (is_group) {
377 kgid_t gid;
378 gid_t id;
380 id = (gid_t)unix_id;
381 gid = make_kgid(&init_user_ns, id);
382 if (gid_valid(gid)) {
383 fgid = gid;
384 goto got_valid_id;
386 } else {
387 kuid_t uid;
388 uid_t id;
390 id = (uid_t)unix_id;
391 uid = make_kuid(&init_user_ns, id);
392 if (uid_valid(uid)) {
393 fuid = uid;
394 goto got_valid_id;
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);
402 if (!sidstr)
403 return -ENOMEM;
405 saved_cred = override_creds(root_cred);
406 sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
407 if (IS_ERR(sidkey)) {
408 rc = -EINVAL;
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
417 * sidtype.
419 BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
420 if (sidkey->datalen != sizeof(uid_t)) {
421 rc = -EIO;
422 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
423 __func__, sidkey->datalen);
424 key_invalidate(sidkey);
425 goto out_key_put;
428 if (sidtype == SIDOWNER) {
429 kuid_t uid;
430 uid_t id;
431 memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
432 uid = make_kuid(&init_user_ns, id);
433 if (uid_valid(uid))
434 fuid = uid;
435 } else {
436 kgid_t gid;
437 gid_t id;
438 memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
439 gid = make_kgid(&init_user_ns, id);
440 if (gid_valid(gid))
441 fgid = gid;
444 out_key_put:
445 key_put(sidkey);
446 out_revert_creds:
447 revert_creds(saved_cred);
448 kfree(sidstr);
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.
454 got_valid_id:
455 rc = 0;
456 if (sidtype == SIDOWNER)
457 fattr->cf_uid = fuid;
458 else
459 fattr->cf_gid = fgid;
460 return rc;
464 init_cifs_idmap(void)
466 struct cred *cred;
467 struct key *keyring;
468 int ret;
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
477 * with add_key().
479 cred = prepare_kernel_cred(NULL);
480 if (!cred)
481 return -ENOMEM;
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);
494 if (ret < 0)
495 goto failed_put_key;
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;
502 root_cred = cred;
504 cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
505 return 0;
507 failed_put_key:
508 key_put(keyring);
509 failed_put_cred:
510 put_cred(cred);
511 return ret;
514 void
515 exit_cifs_idmap(void)
517 key_revoke(root_cred->thread_keyring);
518 unregister_key_type(&cifs_idmap_key_type);
519 put_cred(root_cred);
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));
538 /* copy owner 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);
544 /* copy group sid */
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);
551 return;
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;
592 return;
593 } else if (type != ACCESS_ALLOWED) {
594 cifs_dbg(VFS, "unknown access control type %d\n", type);
595 return;
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");
603 return;
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))
625 *pmode |= 01000;
626 } else if (!(*pdenied & 01000)) {
627 *pmode &= ~01000;
628 *pdenied |= 01000;
632 cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
633 return;
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,
643 __u32 *pace_flags)
645 /* reset access mask */
646 *pace_flags = 0x0;
648 /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
649 mode &= bits_to_use;
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 */
654 if (mode & S_IRUGO)
655 *pace_flags |= SET_FILE_READ_RIGHTS;
656 if (mode & S_IWUGO)
657 *pace_flags |= SET_FILE_WRITE_RIGHTS;
658 if (mode & S_IXUGO)
659 *pace_flags |= SET_FILE_EXEC_RIGHTS;
661 cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
662 mode, *pace_flags);
663 return;
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)
671 int i;
672 __u16 size = 0;
673 __u32 access_req = 0;
675 pntace->type = access_type;
676 pntace->flags = 0x0;
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);
699 return size;
703 #ifdef CONFIG_CIFS_DEBUG2
704 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
706 int num_subauth;
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));
712 return;
715 if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
716 cifs_dbg(VFS, "ACL too small to parse ACE\n");
717 return;
720 num_subauth = pace->sid.num_subauth;
721 if (num_subauth) {
722 int i;
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 */
735 return;
737 #endif
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)
743 int i;
744 int num_aces = 0;
745 int acl_size;
746 char *acl_base;
747 struct cifs_ace **ppace;
749 /* BB need to add parm so we can store the SID BB */
751 if (!pdacl) {
752 /* no DACL in the security descriptor, set
753 all the permissions for user/group/other */
754 fattr->cf_mode |= 0777;
755 return;
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");
761 return;
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);
777 if (num_aces > 0) {
778 umode_t denied_mode = 0;
780 if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
781 return;
782 ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
783 GFP_KERNEL);
784 if (!ppace)
785 return;
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);
791 #endif
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;
801 fattr->cf_mode |=
802 le32_to_cpu(ppace[i]->sid.sub_auth[2]);
803 break;
804 } else {
805 if (compare_sids(&(ppace[i]->sid), pownersid) == 0) {
806 access_flags_to_mode(ppace[i]->access_req,
807 ppace[i]->type,
808 &fattr->cf_mode,
809 &denied_mode,
810 ACL_OWNER_MASK);
811 } else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) {
812 access_flags_to_mode(ppace[i]->access_req,
813 ppace[i]->type,
814 &fattr->cf_mode,
815 &denied_mode,
816 ACL_GROUP_MASK);
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,
820 ppace[i]->type,
821 &fattr->cf_mode,
822 &denied_mode,
823 ACL_EVERYONE_MASK);
828 /* memcpy((void *)(&(cifscred->aces[i])),
829 (void *)ppace[i],
830 sizeof(struct cifs_ace)); */
832 acl_base = (char *)ppace[i];
833 acl_size = le16_to_cpu(ppace[i]->size);
836 kfree(ppace);
839 return;
842 unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
844 int i;
845 unsigned int ace_size = 20;
847 pntace->type = ACCESS_ALLOWED_ACE_TYPE;
848 pntace->flags = 0x0;
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);
859 return 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)
868 int i;
869 unsigned int ace_size = 28;
871 pntace->type = ACCESS_DENIED_ACE_TYPE;
872 pntace->flags = 0x0;
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);
885 return ace_size;
888 unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
890 int i;
891 unsigned int ace_size = 28;
893 pntace->type = ACCESS_ALLOWED_ACE_TYPE;
894 pntace->flags = 0x0;
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);
907 return 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)
913 u16 size = 0;
914 u32 num_aces = 0;
915 struct cifs_acl *pnndacl;
916 __u64 nmode;
917 __u64 user_mode;
918 __u64 group_mode;
919 __u64 other_mode;
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));
926 nmode = *pnmode;
928 if (modefromsid) {
929 struct cifs_ace *pntace =
930 (struct cifs_ace *)((char *)pnndacl + size);
932 size += setup_special_mode_ACE(pntace, nmode);
933 num_aces++;
934 goto set_size;
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;
951 } else {
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. */
965 if (nmode & 01000)
966 sticky_set = true;
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);
971 num_aces++;
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);
977 num_aces++;
979 size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
980 pownersid, user_mode, 0700, ACCESS_ALLOWED, true);
981 num_aces++;
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);
986 num_aces++;
988 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
989 pgrpsid, group_mode, 0070, ACCESS_ALLOWED, !sticky_set);
990 num_aces++;
991 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
992 &sid_everyone, other_mode, 0007, ACCESS_ALLOWED, !sticky_set);
993 num_aces++;
995 set_size:
996 pndacl->num_aces = cpu_to_le32(num_aces);
997 pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
999 return 0;
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);
1011 return -EINVAL;
1014 #ifdef CONFIG_CIFS_DEBUG2
1015 if (psid->num_subauth) {
1016 int i;
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]));
1030 #endif
1032 return 0;
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)
1041 int rc = 0;
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;
1045 __u32 dacloffset;
1047 if (pntsd == NULL)
1048 return -EIO;
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);
1062 if (rc) {
1063 cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1064 return rc;
1066 rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1067 if (rc) {
1068 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1069 __func__, rc);
1070 return rc;
1073 rc = parse_sid(group_sid_ptr, end_of_acl);
1074 if (rc) {
1075 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
1076 __func__, rc);
1077 return rc;
1079 rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1080 if (rc) {
1081 cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1082 __func__, rc);
1083 return rc;
1086 if (dacloffset)
1087 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1088 group_sid_ptr, fattr, get_mode_from_special_sid);
1089 else
1090 cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
1092 return rc;
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)
1100 int rc = 0;
1101 __u32 dacloffset;
1102 __u32 ndacloffset;
1103 __u32 sidsoffset;
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;
1128 } else {
1129 memcpy(pnntsd, pntsd, secdesclen);
1130 if (uid_valid(uid)) { /* chown */
1131 uid_t id;
1132 owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1133 le32_to_cpu(pnntsd->osidoffset));
1134 nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1135 GFP_KERNEL);
1136 if (!nowner_sid_ptr)
1137 return -ENOMEM;
1138 id = from_kuid(&init_user_ns, uid);
1139 if (id_from_sid) {
1140 struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1141 /* Populate the user ownership fields S-1-5-88-1 */
1142 osid->Revision = 1;
1143 osid->NumAuth = 3;
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);
1150 if (rc) {
1151 cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1152 __func__, rc, id);
1153 kfree(nowner_sid_ptr);
1154 return rc;
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 */
1162 gid_t id;
1163 group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1164 le32_to_cpu(pnntsd->gsidoffset));
1165 ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1166 GFP_KERNEL);
1167 if (!ngroup_sid_ptr)
1168 return -ENOMEM;
1169 id = from_kgid(&init_user_ns, gid);
1170 if (id_from_sid) {
1171 struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1172 /* Populate the group ownership fields S-1-5-88-2 */
1173 gsid->Revision = 1;
1174 gsid->NumAuth = 3;
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);
1181 if (rc) {
1182 cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1183 __func__, rc, id);
1184 kfree(ngroup_sid_ptr);
1185 return rc;
1188 cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
1189 kfree(ngroup_sid_ptr);
1190 *aclflag = CIFS_ACL_GROUP;
1194 return rc;
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;
1202 unsigned int xid;
1203 int rc;
1204 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1206 if (IS_ERR(tlink))
1207 return ERR_CAST(tlink);
1209 xid = get_xid();
1210 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1211 pacllen);
1212 free_xid(xid);
1214 cifs_put_tlink(tlink);
1216 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1217 if (rc)
1218 return ERR_PTR(rc);
1219 return pntsd;
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;
1226 int oplock = 0;
1227 unsigned int xid;
1228 int rc;
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;
1234 if (IS_ERR(tlink))
1235 return ERR_CAST(tlink);
1237 tcon = tlink_tcon(tlink);
1238 xid = get_xid();
1240 oparms.tcon = tcon;
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;
1245 oparms.path = path;
1246 oparms.fid = &fid;
1247 oparms.reconnect = false;
1249 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1250 if (!rc) {
1251 rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1252 CIFSSMBClose(xid, tcon, fid.netfid);
1255 cifs_put_tlink(tlink);
1256 free_xid(xid);
1258 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1259 if (rc)
1260 return ERR_PTR(rc);
1261 return pntsd;
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;
1272 if (inode)
1273 open_file = find_readable_file(CIFS_I(inode), true);
1274 if (!open_file)
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);
1279 return pntsd;
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)
1286 int oplock = 0;
1287 unsigned int xid;
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;
1295 if (IS_ERR(tlink))
1296 return PTR_ERR(tlink);
1298 tcon = tlink_tcon(tlink);
1299 xid = get_xid();
1301 if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1302 access_flags = WRITE_OWNER;
1303 else
1304 access_flags = WRITE_DAC;
1306 oparms.tcon = tcon;
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;
1311 oparms.path = path;
1312 oparms.fid = &fid;
1313 oparms.reconnect = false;
1315 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1316 if (rc) {
1317 cifs_dbg(VFS, "Unable to open file to set ACL\n");
1318 goto out;
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);
1325 out:
1326 free_xid(xid);
1327 cifs_put_tlink(tlink);
1328 return rc;
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;
1338 u32 acllen = 0;
1339 int rc = 0;
1340 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1341 struct smb_version_operations *ops;
1342 const u32 info = 0;
1344 cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1346 if (IS_ERR(tlink))
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);
1355 else {
1356 cifs_put_tlink(tlink);
1357 return -EOPNOTSUPP;
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);
1365 kfree(pntsd);
1366 } else {
1367 /* get approximated mode from ACL */
1368 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1369 kfree(pntsd);
1370 if (rc)
1371 cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1374 cifs_put_tlink(tlink);
1376 return rc;
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)
1384 int rc = 0;
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;
1393 const u32 info = 0;
1395 if (IS_ERR(tlink))
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);
1406 return -EOPNOTSUPP;
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);
1414 return rc;
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);
1425 if (!pnntsd) {
1426 kfree(pntsd);
1427 cifs_put_tlink(tlink);
1428 return -ENOMEM;
1431 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1432 mode_from_sid = true;
1433 else
1434 mode_from_sid = false;
1436 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1437 id_from_sid = true;
1438 else
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)
1447 rc = -EOPNOTSUPP;
1449 if (!rc) {
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);
1456 kfree(pnntsd);
1457 kfree(pntsd);
1458 return rc;