xref: /kernel/linux/linux-5.10/fs/cifs/cifsacl.c (revision 8c2ecf20)
1/*
2 *   fs/cifs/cifsacl.c
3 *
4 *   Copyright (C) International Business Machines  Corp., 2007,2008
5 *   Author(s): Steve French (sfrench@us.ibm.com)
6 *
7 *   Contains the routines for mapping CIFS/NTFS ACLs
8 *
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.
13 *
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.
18 *
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
22 */
23
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
36/* security id for everyone/world system group */
37static const struct cifs_sid sid_everyone = {
38	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
39/* security id for Authenticated Users system group */
40static const struct cifs_sid sid_authusers = {
41	1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
42
43/* S-1-22-1 Unmapped Unix users */
44static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
45		{cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
46
47/* S-1-22-2 Unmapped Unix groups */
48static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
49		{cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
50
51/*
52 * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
53 */
54
55/* S-1-5-88 MS NFS and Apple style UID/GID/mode */
56
57/* S-1-5-88-1 Unix uid */
58static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
59	{cpu_to_le32(88),
60	 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
61
62/* S-1-5-88-2 Unix gid */
63static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
64	{cpu_to_le32(88),
65	 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
66
67/* S-1-5-88-3 Unix mode */
68static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
69	{cpu_to_le32(88),
70	 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
71
72static const struct cred *root_cred;
73
74static int
75cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
76{
77	char *payload;
78
79	/*
80	 * If the payload is less than or equal to the size of a pointer, then
81	 * an allocation here is wasteful. Just copy the data directly to the
82	 * payload.value union member instead.
83	 *
84	 * With this however, you must check the datalen before trying to
85	 * dereference payload.data!
86	 */
87	if (prep->datalen <= sizeof(key->payload)) {
88		key->payload.data[0] = NULL;
89		memcpy(&key->payload, prep->data, prep->datalen);
90	} else {
91		payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
92		if (!payload)
93			return -ENOMEM;
94		key->payload.data[0] = payload;
95	}
96
97	key->datalen = prep->datalen;
98	return 0;
99}
100
101static inline void
102cifs_idmap_key_destroy(struct key *key)
103{
104	if (key->datalen > sizeof(key->payload))
105		kfree(key->payload.data[0]);
106}
107
108static struct key_type cifs_idmap_key_type = {
109	.name        = "cifs.idmap",
110	.instantiate = cifs_idmap_key_instantiate,
111	.destroy     = cifs_idmap_key_destroy,
112	.describe    = user_describe,
113};
114
115static char *
116sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
117{
118	int i, len;
119	unsigned int saval;
120	char *sidstr, *strptr;
121	unsigned long long id_auth_val;
122
123	/* 3 bytes for prefix */
124	sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
125			 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
126			 GFP_KERNEL);
127	if (!sidstr)
128		return sidstr;
129
130	strptr = sidstr;
131	len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
132			sidptr->revision);
133	strptr += len;
134
135	/* The authority field is a single 48-bit number */
136	id_auth_val = (unsigned long long)sidptr->authority[5];
137	id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
138	id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
139	id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
140	id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
141	id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
142
143	/*
144	 * MS-DTYP states that if the authority is >= 2^32, then it should be
145	 * expressed as a hex value.
146	 */
147	if (id_auth_val <= UINT_MAX)
148		len = sprintf(strptr, "-%llu", id_auth_val);
149	else
150		len = sprintf(strptr, "-0x%llx", id_auth_val);
151
152	strptr += len;
153
154	for (i = 0; i < sidptr->num_subauth; ++i) {
155		saval = le32_to_cpu(sidptr->sub_auth[i]);
156		len = sprintf(strptr, "-%u", saval);
157		strptr += len;
158	}
159
160	return sidstr;
161}
162
163/*
164 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
165 * the same returns zero, if they do not match returns non-zero.
166 */
167static int
168compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
169{
170	int i;
171	int num_subauth, num_sat, num_saw;
172
173	if ((!ctsid) || (!cwsid))
174		return 1;
175
176	/* compare the revision */
177	if (ctsid->revision != cwsid->revision) {
178		if (ctsid->revision > cwsid->revision)
179			return 1;
180		else
181			return -1;
182	}
183
184	/* compare all of the six auth values */
185	for (i = 0; i < NUM_AUTHS; ++i) {
186		if (ctsid->authority[i] != cwsid->authority[i]) {
187			if (ctsid->authority[i] > cwsid->authority[i])
188				return 1;
189			else
190				return -1;
191		}
192	}
193
194	/* compare all of the subauth values if any */
195	num_sat = ctsid->num_subauth;
196	num_saw = cwsid->num_subauth;
197	num_subauth = num_sat < num_saw ? num_sat : num_saw;
198	if (num_subauth) {
199		for (i = 0; i < num_subauth; ++i) {
200			if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
201				if (le32_to_cpu(ctsid->sub_auth[i]) >
202					le32_to_cpu(cwsid->sub_auth[i]))
203					return 1;
204				else
205					return -1;
206			}
207		}
208	}
209
210	return 0; /* sids compare/match */
211}
212
213static bool
214is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
215{
216	int i;
217	int num_subauth;
218	const struct cifs_sid *pwell_known_sid;
219
220	if (!psid || (puid == NULL))
221		return false;
222
223	num_subauth = psid->num_subauth;
224
225	/* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
226	if (num_subauth == 2) {
227		if (is_group)
228			pwell_known_sid = &sid_unix_groups;
229		else
230			pwell_known_sid = &sid_unix_users;
231	} else if (num_subauth == 3) {
232		if (is_group)
233			pwell_known_sid = &sid_unix_NFS_groups;
234		else
235			pwell_known_sid = &sid_unix_NFS_users;
236	} else
237		return false;
238
239	/* compare the revision */
240	if (psid->revision != pwell_known_sid->revision)
241		return false;
242
243	/* compare all of the six auth values */
244	for (i = 0; i < NUM_AUTHS; ++i) {
245		if (psid->authority[i] != pwell_known_sid->authority[i]) {
246			cifs_dbg(FYI, "auth %d did not match\n", i);
247			return false;
248		}
249	}
250
251	if (num_subauth == 2) {
252		if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
253			return false;
254
255		*puid = le32_to_cpu(psid->sub_auth[1]);
256	} else /* 3 subauths, ie Windows/Mac style */ {
257		*puid = le32_to_cpu(psid->sub_auth[0]);
258		if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
259		    (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
260			return false;
261
262		*puid = le32_to_cpu(psid->sub_auth[2]);
263	}
264
265	cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
266	return true; /* well known sid found, uid returned */
267}
268
269static void
270cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
271{
272	int i;
273
274	dst->revision = src->revision;
275	dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
276	for (i = 0; i < NUM_AUTHS; ++i)
277		dst->authority[i] = src->authority[i];
278	for (i = 0; i < dst->num_subauth; ++i)
279		dst->sub_auth[i] = src->sub_auth[i];
280}
281
282static int
283id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
284{
285	int rc;
286	struct key *sidkey;
287	struct cifs_sid *ksid;
288	unsigned int ksid_size;
289	char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
290	const struct cred *saved_cred;
291
292	rc = snprintf(desc, sizeof(desc), "%ci:%u",
293			sidtype == SIDOWNER ? 'o' : 'g', cid);
294	if (rc >= sizeof(desc))
295		return -EINVAL;
296
297	rc = 0;
298	saved_cred = override_creds(root_cred);
299	sidkey = request_key(&cifs_idmap_key_type, desc, "");
300	if (IS_ERR(sidkey)) {
301		rc = -EINVAL;
302		cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
303			 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
304		goto out_revert_creds;
305	} else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
306		rc = -EIO;
307		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
308			 __func__, sidkey->datalen);
309		goto invalidate_key;
310	}
311
312	/*
313	 * A sid is usually too large to be embedded in payload.value, but if
314	 * there are no subauthorities and the host has 8-byte pointers, then
315	 * it could be.
316	 */
317	ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
318		(struct cifs_sid *)&sidkey->payload :
319		(struct cifs_sid *)sidkey->payload.data[0];
320
321	ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
322	if (ksid_size > sidkey->datalen) {
323		rc = -EIO;
324		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
325			 __func__, sidkey->datalen, ksid_size);
326		goto invalidate_key;
327	}
328
329	cifs_copy_sid(ssid, ksid);
330out_key_put:
331	key_put(sidkey);
332out_revert_creds:
333	revert_creds(saved_cred);
334	return rc;
335
336invalidate_key:
337	key_invalidate(sidkey);
338	goto out_key_put;
339}
340
341int
342sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
343		struct cifs_fattr *fattr, uint sidtype)
344{
345	int rc = 0;
346	struct key *sidkey;
347	char *sidstr;
348	const struct cred *saved_cred;
349	kuid_t fuid = cifs_sb->mnt_uid;
350	kgid_t fgid = cifs_sb->mnt_gid;
351
352	/*
353	 * If we have too many subauthorities, then something is really wrong.
354	 * Just return an error.
355	 */
356	if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
357		cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
358			 __func__, psid->num_subauth);
359		return -EIO;
360	}
361
362	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
363	    (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
364		uint32_t unix_id;
365		bool is_group;
366
367		if (sidtype != SIDOWNER)
368			is_group = true;
369		else
370			is_group = false;
371
372		if (is_well_known_sid(psid, &unix_id, is_group) == false)
373			goto try_upcall_to_get_id;
374
375		if (is_group) {
376			kgid_t gid;
377			gid_t id;
378
379			id = (gid_t)unix_id;
380			gid = make_kgid(&init_user_ns, id);
381			if (gid_valid(gid)) {
382				fgid = gid;
383				goto got_valid_id;
384			}
385		} else {
386			kuid_t uid;
387			uid_t id;
388
389			id = (uid_t)unix_id;
390			uid = make_kuid(&init_user_ns, id);
391			if (uid_valid(uid)) {
392				fuid = uid;
393				goto got_valid_id;
394			}
395		}
396		/* If unable to find uid/gid easily from SID try via upcall */
397	}
398
399try_upcall_to_get_id:
400	sidstr = sid_to_key_str(psid, sidtype);
401	if (!sidstr)
402		return -ENOMEM;
403
404	saved_cred = override_creds(root_cred);
405	sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
406	if (IS_ERR(sidkey)) {
407		rc = -EINVAL;
408		cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
409			 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
410		goto out_revert_creds;
411	}
412
413	/*
414	 * FIXME: Here we assume that uid_t and gid_t are same size. It's
415	 * probably a safe assumption but might be better to check based on
416	 * sidtype.
417	 */
418	BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
419	if (sidkey->datalen != sizeof(uid_t)) {
420		rc = -EIO;
421		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
422			 __func__, sidkey->datalen);
423		key_invalidate(sidkey);
424		goto out_key_put;
425	}
426
427	if (sidtype == SIDOWNER) {
428		kuid_t uid;
429		uid_t id;
430		memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
431		uid = make_kuid(&init_user_ns, id);
432		if (uid_valid(uid))
433			fuid = uid;
434	} else {
435		kgid_t gid;
436		gid_t id;
437		memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
438		gid = make_kgid(&init_user_ns, id);
439		if (gid_valid(gid))
440			fgid = gid;
441	}
442
443out_key_put:
444	key_put(sidkey);
445out_revert_creds:
446	revert_creds(saved_cred);
447	kfree(sidstr);
448
449	/*
450	 * Note that we return 0 here unconditionally. If the mapping
451	 * fails then we just fall back to using the mnt_uid/mnt_gid.
452	 */
453got_valid_id:
454	rc = 0;
455	if (sidtype == SIDOWNER)
456		fattr->cf_uid = fuid;
457	else
458		fattr->cf_gid = fgid;
459	return rc;
460}
461
462int
463init_cifs_idmap(void)
464{
465	struct cred *cred;
466	struct key *keyring;
467	int ret;
468
469	cifs_dbg(FYI, "Registering the %s key type\n",
470		 cifs_idmap_key_type.name);
471
472	/* create an override credential set with a special thread keyring in
473	 * which requests are cached
474	 *
475	 * this is used to prevent malicious redirections from being installed
476	 * with add_key().
477	 */
478	cred = prepare_kernel_cred(NULL);
479	if (!cred)
480		return -ENOMEM;
481
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;
490	}
491
492	ret = register_key_type(&cifs_idmap_key_type);
493	if (ret < 0)
494		goto failed_put_key;
495
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;
501	root_cred = cred;
502
503	cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
504	return 0;
505
506failed_put_key:
507	key_put(keyring);
508failed_put_cred:
509	put_cred(cred);
510	return ret;
511}
512
513void
514exit_cifs_idmap(void)
515{
516	key_revoke(root_cred->thread_keyring);
517	unregister_key_type(&cifs_idmap_key_type);
518	put_cred(root_cred);
519	cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
520}
521
522/* copy ntsd, owner sid, and group sid from a security descriptor to another */
523static void copy_sec_desc(const struct cifs_ntsd *pntsd,
524				struct cifs_ntsd *pnntsd, __u32 sidsoffset)
525{
526	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
527	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
528
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));
536
537	/* copy owner 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);
542
543	/* copy group sid */
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);
549
550	return;
551}
552
553
554/*
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
558*/
559static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
560				 umode_t *pbits_to_set)
561{
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 */
568
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;
574
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;
584		return;
585	} else if (type != ACCESS_ALLOWED) {
586		cifs_dbg(VFS, "unknown access control type %d\n", type);
587		return;
588	}
589	/* else ACCESS_ALLOWED type */
590
591	if (flags & GENERIC_ALL) {
592		*pmode |= (S_IRWXUGO & (*pbits_to_set));
593		cifs_dbg(NOISY, "all perms\n");
594		return;
595	}
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));
605
606	cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
607	return;
608}
609
610/*
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.
614*/
615
616static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
617				__u32 *pace_flags)
618{
619	/* reset access mask */
620	*pace_flags = 0x0;
621
622	/* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
623	mode &= bits_to_use;
624
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 */
628	if (mode & S_IRUGO)
629		*pace_flags |= SET_FILE_READ_RIGHTS;
630	if (mode & S_IWUGO)
631		*pace_flags |= SET_FILE_WRITE_RIGHTS;
632	if (mode & S_IXUGO)
633		*pace_flags |= SET_FILE_EXEC_RIGHTS;
634
635	cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
636		 mode, *pace_flags);
637	return;
638}
639
640static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
641			const struct cifs_sid *psid, __u64 nmode, umode_t bits)
642{
643	int i;
644	__u16 size = 0;
645	__u32 access_req = 0;
646
647	pntace->type = ACCESS_ALLOWED;
648	pntace->flags = 0x0;
649	mode_to_access_flags(nmode, bits, &access_req);
650	if (!access_req)
651		access_req = SET_MINIMUM_RIGHTS;
652	pntace->access_req = cpu_to_le32(access_req);
653
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];
660
661	size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
662	pntace->size = cpu_to_le16(size);
663
664	return size;
665}
666
667
668#ifdef CONFIG_CIFS_DEBUG2
669static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
670{
671	int num_subauth;
672
673	/* validate that we do not go past end of acl */
674
675	if (le16_to_cpu(pace->size) < 16) {
676		cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
677		return;
678	}
679
680	if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
681		cifs_dbg(VFS, "ACL too small to parse ACE\n");
682		return;
683	}
684
685	num_subauth = pace->sid.num_subauth;
686	if (num_subauth) {
687		int i;
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]));
694		}
695
696		/* BB add length check to make sure that we do not have huge
697			num auths and therefore go off the end */
698	}
699
700	return;
701}
702#endif
703
704static 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)
707{
708	int i;
709	int num_aces = 0;
710	int acl_size;
711	char *acl_base;
712	struct cifs_ace **ppace;
713
714	/* BB need to add parm so we can store the SID BB */
715
716	if (!pdacl) {
717		/* no DACL in the security descriptor, set
718		   all the permissions for user/group/other */
719		fattr->cf_mode |= S_IRWXUGO;
720		return;
721	}
722
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");
726		return;
727	}
728
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));
732
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);
737
738	acl_base = (char *)pdacl;
739	acl_size = sizeof(struct cifs_acl);
740
741	num_aces = le32_to_cpu(pdacl->num_aces);
742	if (num_aces > 0) {
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;
746
747		if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
748			return;
749		ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
750				      GFP_KERNEL);
751		if (!ppace)
752			return;
753
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);
758#endif
759			if (mode_from_special_sid &&
760			    (compare_sids(&(ppace[i]->sid),
761					  &sid_unix_NFS_mode) == 0)) {
762				/*
763				 * Full permissions are:
764				 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
765				 *         S_IRWXU | S_IRWXG | S_IRWXO
766				 */
767				fattr->cf_mode &= ~07777;
768				fattr->cf_mode |=
769					le32_to_cpu(ppace[i]->sid.sub_auth[2]);
770				break;
771			} else if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
772				access_flags_to_mode(ppace[i]->access_req,
773						     ppace[i]->type,
774						     &fattr->cf_mode,
775						     &user_mask);
776			else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
777				access_flags_to_mode(ppace[i]->access_req,
778						     ppace[i]->type,
779						     &fattr->cf_mode,
780						     &group_mask);
781			else if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
782				access_flags_to_mode(ppace[i]->access_req,
783						     ppace[i]->type,
784						     &fattr->cf_mode,
785						     &other_mask);
786			else if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
787				access_flags_to_mode(ppace[i]->access_req,
788						     ppace[i]->type,
789						     &fattr->cf_mode,
790						     &other_mask);
791
792
793/*			memcpy((void *)(&(cifscred->aces[i])),
794				(void *)ppace[i],
795				sizeof(struct cifs_ace)); */
796
797			acl_base = (char *)ppace[i];
798			acl_size = le16_to_cpu(ppace[i]->size);
799		}
800
801		kfree(ppace);
802	}
803
804	return;
805}
806
807unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
808{
809	int i;
810	unsigned int ace_size = 20;
811
812	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
813	pntace->flags = 0x0;
814	pntace->access_req = cpu_to_le32(GENERIC_ALL);
815	pntace->sid.num_subauth = 1;
816	pntace->sid.revision = 1;
817	for (i = 0; i < NUM_AUTHS; i++)
818		pntace->sid.authority[i] =  sid_authusers.authority[i];
819
820	pntace->sid.sub_auth[0] =  sid_authusers.sub_auth[0];
821
822	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
823	pntace->size = cpu_to_le16(ace_size);
824	return ace_size;
825}
826
827/*
828 * Fill in the special SID based on the mode. See
829 * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
830 */
831unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
832{
833	int i;
834	unsigned int ace_size = 28;
835
836	pntace->type = ACCESS_DENIED_ACE_TYPE;
837	pntace->flags = 0x0;
838	pntace->access_req = 0;
839	pntace->sid.num_subauth = 3;
840	pntace->sid.revision = 1;
841	for (i = 0; i < NUM_AUTHS; i++)
842		pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
843
844	pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
845	pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
846	pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
847
848	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
849	pntace->size = cpu_to_le16(ace_size);
850	return ace_size;
851}
852
853unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
854{
855	int i;
856	unsigned int ace_size = 28;
857
858	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
859	pntace->flags = 0x0;
860	pntace->access_req = cpu_to_le32(GENERIC_ALL);
861	pntace->sid.num_subauth = 3;
862	pntace->sid.revision = 1;
863	for (i = 0; i < NUM_AUTHS; i++)
864		pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
865
866	pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
867	pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
868	pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
869
870	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
871	pntace->size = cpu_to_le16(ace_size);
872	return ace_size;
873}
874
875static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
876			struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
877{
878	u16 size = 0;
879	u32 num_aces = 0;
880	struct cifs_acl *pnndacl;
881
882	pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
883
884	if (modefromsid) {
885		struct cifs_ace *pntace =
886			(struct cifs_ace *)((char *)pnndacl + size);
887
888		size += setup_special_mode_ACE(pntace, nmode);
889		num_aces++;
890	}
891
892	size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
893					pownersid, nmode, S_IRWXU);
894	num_aces++;
895	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
896					pgrpsid, nmode, S_IRWXG);
897	num_aces++;
898	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
899					 &sid_everyone, nmode, S_IRWXO);
900	num_aces++;
901
902	pndacl->num_aces = cpu_to_le32(num_aces);
903	pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
904
905	return 0;
906}
907
908
909static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
910{
911	/* BB need to add parm so we can store the SID BB */
912
913	/* validate that we do not go past end of ACL - sid must be at least 8
914	   bytes long (assuming no sub-auths - e.g. the null SID */
915	if (end_of_acl < (char *)psid + 8) {
916		cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
917		return -EINVAL;
918	}
919
920#ifdef CONFIG_CIFS_DEBUG2
921	if (psid->num_subauth) {
922		int i;
923		cifs_dbg(FYI, "SID revision %d num_auth %d\n",
924			 psid->revision, psid->num_subauth);
925
926		for (i = 0; i < psid->num_subauth; i++) {
927			cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
928				 i, le32_to_cpu(psid->sub_auth[i]));
929		}
930
931		/* BB add length check to make sure that we do not have huge
932			num auths and therefore go off the end */
933		cifs_dbg(FYI, "RID 0x%x\n",
934			 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
935	}
936#endif
937
938	return 0;
939}
940
941
942/* Convert CIFS ACL to POSIX form */
943static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
944		struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
945		bool get_mode_from_special_sid)
946{
947	int rc = 0;
948	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
949	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
950	char *end_of_acl = ((char *)pntsd) + acl_len;
951	__u32 dacloffset;
952
953	if (pntsd == NULL)
954		return -EIO;
955
956	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
957				le32_to_cpu(pntsd->osidoffset));
958	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
959				le32_to_cpu(pntsd->gsidoffset));
960	dacloffset = le32_to_cpu(pntsd->dacloffset);
961	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
962	cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
963		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
964		 le32_to_cpu(pntsd->gsidoffset),
965		 le32_to_cpu(pntsd->sacloffset), dacloffset);
966/*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
967	rc = parse_sid(owner_sid_ptr, end_of_acl);
968	if (rc) {
969		cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
970		return rc;
971	}
972	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
973	if (rc) {
974		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
975			 __func__, rc);
976		return rc;
977	}
978
979	rc = parse_sid(group_sid_ptr, end_of_acl);
980	if (rc) {
981		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
982			 __func__, rc);
983		return rc;
984	}
985	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
986	if (rc) {
987		cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
988			 __func__, rc);
989		return rc;
990	}
991
992	if (dacloffset)
993		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
994			   group_sid_ptr, fattr, get_mode_from_special_sid);
995	else
996		cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
997
998	return rc;
999}
1000
1001/* Convert permission bits from mode to equivalent CIFS ACL */
1002static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1003	__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid,
1004	bool mode_from_sid, bool id_from_sid, int *aclflag)
1005{
1006	int rc = 0;
1007	__u32 dacloffset;
1008	__u32 ndacloffset;
1009	__u32 sidsoffset;
1010	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1011	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
1012	struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
1013	struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1014
1015	if (nmode != NO_CHANGE_64) { /* chmod */
1016		owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1017				le32_to_cpu(pntsd->osidoffset));
1018		group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1019				le32_to_cpu(pntsd->gsidoffset));
1020		dacloffset = le32_to_cpu(pntsd->dacloffset);
1021		dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1022		ndacloffset = sizeof(struct cifs_ntsd);
1023		ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1024		ndacl_ptr->revision = dacl_ptr->revision;
1025		ndacl_ptr->size = 0;
1026		ndacl_ptr->num_aces = 0;
1027
1028		rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1029				    nmode, mode_from_sid);
1030		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1031		/* copy sec desc control portion & owner and group sids */
1032		copy_sec_desc(pntsd, pnntsd, sidsoffset);
1033		*aclflag = CIFS_ACL_DACL;
1034	} else {
1035		memcpy(pnntsd, pntsd, secdesclen);
1036		if (uid_valid(uid)) { /* chown */
1037			uid_t id;
1038			owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1039					le32_to_cpu(pnntsd->osidoffset));
1040			nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1041								GFP_KERNEL);
1042			if (!nowner_sid_ptr)
1043				return -ENOMEM;
1044			id = from_kuid(&init_user_ns, uid);
1045			if (id_from_sid) {
1046				struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1047				/* Populate the user ownership fields S-1-5-88-1 */
1048				osid->Revision = 1;
1049				osid->NumAuth = 3;
1050				osid->Authority[5] = 5;
1051				osid->SubAuthorities[0] = cpu_to_le32(88);
1052				osid->SubAuthorities[1] = cpu_to_le32(1);
1053				osid->SubAuthorities[2] = cpu_to_le32(id);
1054			} else { /* lookup sid with upcall */
1055				rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1056				if (rc) {
1057					cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1058						 __func__, rc, id);
1059					kfree(nowner_sid_ptr);
1060					return rc;
1061				}
1062			}
1063			cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
1064			kfree(nowner_sid_ptr);
1065			*aclflag = CIFS_ACL_OWNER;
1066		}
1067		if (gid_valid(gid)) { /* chgrp */
1068			gid_t id;
1069			group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1070					le32_to_cpu(pnntsd->gsidoffset));
1071			ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1072								GFP_KERNEL);
1073			if (!ngroup_sid_ptr)
1074				return -ENOMEM;
1075			id = from_kgid(&init_user_ns, gid);
1076			if (id_from_sid) {
1077				struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1078				/* Populate the group ownership fields S-1-5-88-2 */
1079				gsid->Revision = 1;
1080				gsid->NumAuth = 3;
1081				gsid->Authority[5] = 5;
1082				gsid->SubAuthorities[0] = cpu_to_le32(88);
1083				gsid->SubAuthorities[1] = cpu_to_le32(2);
1084				gsid->SubAuthorities[2] = cpu_to_le32(id);
1085			} else { /* lookup sid with upcall */
1086				rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1087				if (rc) {
1088					cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1089						 __func__, rc, id);
1090					kfree(ngroup_sid_ptr);
1091					return rc;
1092				}
1093			}
1094			cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
1095			kfree(ngroup_sid_ptr);
1096			*aclflag = CIFS_ACL_GROUP;
1097		}
1098	}
1099
1100	return rc;
1101}
1102
1103struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1104		const struct cifs_fid *cifsfid, u32 *pacllen)
1105{
1106	struct cifs_ntsd *pntsd = NULL;
1107	unsigned int xid;
1108	int rc;
1109	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1110
1111	if (IS_ERR(tlink))
1112		return ERR_CAST(tlink);
1113
1114	xid = get_xid();
1115	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1116				pacllen);
1117	free_xid(xid);
1118
1119	cifs_put_tlink(tlink);
1120
1121	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1122	if (rc)
1123		return ERR_PTR(rc);
1124	return pntsd;
1125}
1126
1127static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1128		const char *path, u32 *pacllen)
1129{
1130	struct cifs_ntsd *pntsd = NULL;
1131	int oplock = 0;
1132	unsigned int xid;
1133	int rc;
1134	struct cifs_tcon *tcon;
1135	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1136	struct cifs_fid fid;
1137	struct cifs_open_parms oparms;
1138
1139	if (IS_ERR(tlink))
1140		return ERR_CAST(tlink);
1141
1142	tcon = tlink_tcon(tlink);
1143	xid = get_xid();
1144
1145	oparms.tcon = tcon;
1146	oparms.cifs_sb = cifs_sb;
1147	oparms.desired_access = READ_CONTROL;
1148	oparms.create_options = cifs_create_options(cifs_sb, 0);
1149	oparms.disposition = FILE_OPEN;
1150	oparms.path = path;
1151	oparms.fid = &fid;
1152	oparms.reconnect = false;
1153
1154	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1155	if (!rc) {
1156		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1157		CIFSSMBClose(xid, tcon, fid.netfid);
1158	}
1159
1160	cifs_put_tlink(tlink);
1161	free_xid(xid);
1162
1163	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1164	if (rc)
1165		return ERR_PTR(rc);
1166	return pntsd;
1167}
1168
1169/* Retrieve an ACL from the server */
1170struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1171				      struct inode *inode, const char *path,
1172				      u32 *pacllen)
1173{
1174	struct cifs_ntsd *pntsd = NULL;
1175	struct cifsFileInfo *open_file = NULL;
1176
1177	if (inode)
1178		open_file = find_readable_file(CIFS_I(inode), true);
1179	if (!open_file)
1180		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1181
1182	pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
1183	cifsFileInfo_put(open_file);
1184	return pntsd;
1185}
1186
1187 /* Set an ACL on the server */
1188int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1189			struct inode *inode, const char *path, int aclflag)
1190{
1191	int oplock = 0;
1192	unsigned int xid;
1193	int rc, access_flags;
1194	struct cifs_tcon *tcon;
1195	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1196	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1197	struct cifs_fid fid;
1198	struct cifs_open_parms oparms;
1199
1200	if (IS_ERR(tlink))
1201		return PTR_ERR(tlink);
1202
1203	tcon = tlink_tcon(tlink);
1204	xid = get_xid();
1205
1206	if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1207		access_flags = WRITE_OWNER;
1208	else
1209		access_flags = WRITE_DAC;
1210
1211	oparms.tcon = tcon;
1212	oparms.cifs_sb = cifs_sb;
1213	oparms.desired_access = access_flags;
1214	oparms.create_options = cifs_create_options(cifs_sb, 0);
1215	oparms.disposition = FILE_OPEN;
1216	oparms.path = path;
1217	oparms.fid = &fid;
1218	oparms.reconnect = false;
1219
1220	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1221	if (rc) {
1222		cifs_dbg(VFS, "Unable to open file to set ACL\n");
1223		goto out;
1224	}
1225
1226	rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1227	cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1228
1229	CIFSSMBClose(xid, tcon, fid.netfid);
1230out:
1231	free_xid(xid);
1232	cifs_put_tlink(tlink);
1233	return rc;
1234}
1235
1236/* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1237int
1238cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1239		  struct inode *inode, bool mode_from_special_sid,
1240		  const char *path, const struct cifs_fid *pfid)
1241{
1242	struct cifs_ntsd *pntsd = NULL;
1243	u32 acllen = 0;
1244	int rc = 0;
1245	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1246	struct smb_version_operations *ops;
1247
1248	cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1249
1250	if (IS_ERR(tlink))
1251		return PTR_ERR(tlink);
1252
1253	ops = tlink_tcon(tlink)->ses->server->ops;
1254
1255	if (pfid && (ops->get_acl_by_fid))
1256		pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
1257	else if (ops->get_acl)
1258		pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
1259	else {
1260		cifs_put_tlink(tlink);
1261		return -EOPNOTSUPP;
1262	}
1263	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1264	if (IS_ERR(pntsd)) {
1265		rc = PTR_ERR(pntsd);
1266		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1267	} else if (mode_from_special_sid) {
1268		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1269		kfree(pntsd);
1270	} else {
1271		/* get approximated mode from ACL */
1272		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1273		kfree(pntsd);
1274		if (rc)
1275			cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1276	}
1277
1278	cifs_put_tlink(tlink);
1279
1280	return rc;
1281}
1282
1283/* Convert mode bits to an ACL so we can update the ACL on the server */
1284int
1285id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1286			kuid_t uid, kgid_t gid)
1287{
1288	int rc = 0;
1289	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1290	__u32 secdesclen = 0;
1291	struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1292	struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1293	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1294	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1295	struct smb_version_operations *ops;
1296	bool mode_from_sid, id_from_sid;
1297
1298	if (IS_ERR(tlink))
1299		return PTR_ERR(tlink);
1300
1301	ops = tlink_tcon(tlink)->ses->server->ops;
1302
1303	cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1304
1305	/* Get the security descriptor */
1306
1307	if (ops->get_acl == NULL) {
1308		cifs_put_tlink(tlink);
1309		return -EOPNOTSUPP;
1310	}
1311
1312	pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
1313	if (IS_ERR(pntsd)) {
1314		rc = PTR_ERR(pntsd);
1315		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1316		cifs_put_tlink(tlink);
1317		return rc;
1318	}
1319
1320	/*
1321	 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1322	 * as chmod disables ACEs and set the security descriptor. Allocate
1323	 * memory for the smb header, set security descriptor request security
1324	 * descriptor parameters, and secuirty descriptor itself
1325	 */
1326	secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1327	pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1328	if (!pnntsd) {
1329		kfree(pntsd);
1330		cifs_put_tlink(tlink);
1331		return -ENOMEM;
1332	}
1333
1334	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1335		mode_from_sid = true;
1336	else
1337		mode_from_sid = false;
1338
1339	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1340		id_from_sid = true;
1341	else
1342		id_from_sid = false;
1343
1344	rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1345			    mode_from_sid, id_from_sid, &aclflag);
1346
1347	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1348
1349	if (ops->set_acl == NULL)
1350		rc = -EOPNOTSUPP;
1351
1352	if (!rc) {
1353		/* Set the security descriptor */
1354		rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
1355		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1356	}
1357	cifs_put_tlink(tlink);
1358
1359	kfree(pnntsd);
1360	kfree(pntsd);
1361	return rc;
1362}
1363