xref: /linux/fs/smb/client/cifsacl.c (revision ff124bbbca1d3a07fa1392ffdbbdeece71f68ece)
1 // SPDX-License-Identifier: LGPL-2.1
2 /*
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  */
10 
11 #include <linux/fs.h>
12 #include <linux/slab.h>
13 #include <linux/string.h>
14 #include <linux/keyctl.h>
15 #include <linux/key-type.h>
16 #include <uapi/linux/posix_acl.h>
17 #include <linux/posix_acl.h>
18 #include <linux/posix_acl_xattr.h>
19 #include <keys/user-type.h>
20 #include "cifsglob.h"
21 #include "cifsacl.h"
22 #include "cifsproto.h"
23 #include "cifs_debug.h"
24 #include "fs_context.h"
25 #include "cifs_fs_sb.h"
26 #include "cifs_unicode.h"
27 
28 /* security id for everyone/world system group */
29 static const struct smb_sid sid_everyone = {
30 	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
31 /* security id for Authenticated Users system group */
32 static const struct smb_sid sid_authusers = {
33 	1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
34 
35 /* S-1-22-1 Unmapped Unix users */
36 static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
37 		{cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
38 
39 /* S-1-22-2 Unmapped Unix groups */
40 static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
41 		{cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
42 
43 /*
44  * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
45  */
46 
47 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
48 
49 /* S-1-5-88-1 Unix uid */
50 static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
51 	{cpu_to_le32(88),
52 	 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
53 
54 /* S-1-5-88-2 Unix gid */
55 static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
56 	{cpu_to_le32(88),
57 	 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
58 
59 /* S-1-5-88-3 Unix mode */
60 static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
61 	{cpu_to_le32(88),
62 	 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
63 
64 static const struct cred *root_cred;
65 
66 static int
67 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
68 {
69 	char *payload;
70 
71 	/*
72 	 * If the payload is less than or equal to the size of a pointer, then
73 	 * an allocation here is wasteful. Just copy the data directly to the
74 	 * payload.value union member instead.
75 	 *
76 	 * With this however, you must check the datalen before trying to
77 	 * dereference payload.data!
78 	 */
79 	if (prep->datalen <= sizeof(key->payload)) {
80 		key->payload.data[0] = NULL;
81 		memcpy(&key->payload, prep->data, prep->datalen);
82 	} else {
83 		payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
84 		if (!payload)
85 			return -ENOMEM;
86 		key->payload.data[0] = payload;
87 	}
88 
89 	key->datalen = prep->datalen;
90 	return 0;
91 }
92 
93 static inline void
94 cifs_idmap_key_destroy(struct key *key)
95 {
96 	if (key->datalen > sizeof(key->payload))
97 		kfree(key->payload.data[0]);
98 }
99 
100 static struct key_type cifs_idmap_key_type = {
101 	.name        = "cifs.idmap",
102 	.instantiate = cifs_idmap_key_instantiate,
103 	.destroy     = cifs_idmap_key_destroy,
104 	.describe    = user_describe,
105 };
106 
107 static char *
108 sid_to_key_str(struct smb_sid *sidptr, unsigned int type)
109 {
110 	int i, len;
111 	unsigned int saval;
112 	char *sidstr, *strptr;
113 	unsigned long long id_auth_val;
114 
115 	/* 3 bytes for prefix */
116 	sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
117 			 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
118 			 GFP_KERNEL);
119 	if (!sidstr)
120 		return sidstr;
121 
122 	strptr = sidstr;
123 	len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
124 			sidptr->revision);
125 	strptr += len;
126 
127 	/* The authority field is a single 48-bit number */
128 	id_auth_val = (unsigned long long)sidptr->authority[5];
129 	id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
130 	id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
131 	id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
132 	id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
133 	id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
134 
135 	/*
136 	 * MS-DTYP states that if the authority is >= 2^32, then it should be
137 	 * expressed as a hex value.
138 	 */
139 	if (id_auth_val <= UINT_MAX)
140 		len = sprintf(strptr, "-%llu", id_auth_val);
141 	else
142 		len = sprintf(strptr, "-0x%llx", id_auth_val);
143 
144 	strptr += len;
145 
146 	for (i = 0; i < sidptr->num_subauth; ++i) {
147 		saval = le32_to_cpu(sidptr->sub_auth[i]);
148 		len = sprintf(strptr, "-%u", saval);
149 		strptr += len;
150 	}
151 
152 	return sidstr;
153 }
154 
155 /*
156  * if the two SIDs (roughly equivalent to a UUID for a user or group) are
157  * the same returns zero, if they do not match returns non-zero.
158  */
159 static int
160 compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
161 {
162 	int i;
163 	int num_subauth, num_sat, num_saw;
164 
165 	if ((!ctsid) || (!cwsid))
166 		return 1;
167 
168 	/* compare the revision */
169 	if (ctsid->revision != cwsid->revision) {
170 		if (ctsid->revision > cwsid->revision)
171 			return 1;
172 		else
173 			return -1;
174 	}
175 
176 	/* compare all of the six auth values */
177 	for (i = 0; i < NUM_AUTHS; ++i) {
178 		if (ctsid->authority[i] != cwsid->authority[i]) {
179 			if (ctsid->authority[i] > cwsid->authority[i])
180 				return 1;
181 			else
182 				return -1;
183 		}
184 	}
185 
186 	/* compare all of the subauth values if any */
187 	num_sat = ctsid->num_subauth;
188 	num_saw = cwsid->num_subauth;
189 	num_subauth = min(num_sat, num_saw);
190 	if (num_subauth) {
191 		for (i = 0; i < num_subauth; ++i) {
192 			if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
193 				if (le32_to_cpu(ctsid->sub_auth[i]) >
194 					le32_to_cpu(cwsid->sub_auth[i]))
195 					return 1;
196 				else
197 					return -1;
198 			}
199 		}
200 	}
201 
202 	return 0; /* sids compare/match */
203 }
204 
205 static bool
206 is_well_known_sid(const struct smb_sid *psid, uint32_t *puid, bool is_group)
207 {
208 	int i;
209 	int num_subauth;
210 	const struct smb_sid *pwell_known_sid;
211 
212 	if (!psid || (puid == NULL))
213 		return false;
214 
215 	num_subauth = psid->num_subauth;
216 
217 	/* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
218 	if (num_subauth == 2) {
219 		if (is_group)
220 			pwell_known_sid = &sid_unix_groups;
221 		else
222 			pwell_known_sid = &sid_unix_users;
223 	} else if (num_subauth == 3) {
224 		if (is_group)
225 			pwell_known_sid = &sid_unix_NFS_groups;
226 		else
227 			pwell_known_sid = &sid_unix_NFS_users;
228 	} else
229 		return false;
230 
231 	/* compare the revision */
232 	if (psid->revision != pwell_known_sid->revision)
233 		return false;
234 
235 	/* compare all of the six auth values */
236 	for (i = 0; i < NUM_AUTHS; ++i) {
237 		if (psid->authority[i] != pwell_known_sid->authority[i]) {
238 			cifs_dbg(FYI, "auth %d did not match\n", i);
239 			return false;
240 		}
241 	}
242 
243 	if (num_subauth == 2) {
244 		if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
245 			return false;
246 
247 		*puid = le32_to_cpu(psid->sub_auth[1]);
248 	} else /* 3 subauths, ie Windows/Mac style */ {
249 		*puid = le32_to_cpu(psid->sub_auth[0]);
250 		if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
251 		    (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
252 			return false;
253 
254 		*puid = le32_to_cpu(psid->sub_auth[2]);
255 	}
256 
257 	cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
258 	return true; /* well known sid found, uid returned */
259 }
260 
261 static __u16
262 cifs_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
263 {
264 	int i;
265 	__u16 size = 1 + 1 + 6;
266 
267 	dst->revision = src->revision;
268 	dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
269 	for (i = 0; i < NUM_AUTHS; ++i)
270 		dst->authority[i] = src->authority[i];
271 	for (i = 0; i < dst->num_subauth; ++i)
272 		dst->sub_auth[i] = src->sub_auth[i];
273 	size += (dst->num_subauth * 4);
274 
275 	return size;
276 }
277 
278 static int
279 id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
280 {
281 	int rc;
282 	struct key *sidkey;
283 	struct smb_sid *ksid;
284 	unsigned int ksid_size;
285 	char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
286 	const struct cred *saved_cred;
287 
288 	rc = snprintf(desc, sizeof(desc), "%ci:%u",
289 			sidtype == SIDOWNER ? 'o' : 'g', cid);
290 	if (rc >= sizeof(desc))
291 		return -EINVAL;
292 
293 	rc = 0;
294 	saved_cred = override_creds(root_cred);
295 	sidkey = request_key(&cifs_idmap_key_type, desc, "");
296 	if (IS_ERR(sidkey)) {
297 		rc = -EINVAL;
298 		cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
299 			 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
300 		goto out_revert_creds;
301 	} else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
302 		rc = smb_EIO1(smb_eio_trace_malformed_sid_key, sidkey->datalen);
303 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
304 			 __func__, sidkey->datalen);
305 		goto invalidate_key;
306 	}
307 
308 	/*
309 	 * A sid is usually too large to be embedded in payload.value, but if
310 	 * there are no subauthorities and the host has 8-byte pointers, then
311 	 * it could be.
312 	 */
313 	ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
314 		(struct smb_sid *)&sidkey->payload :
315 		(struct smb_sid *)sidkey->payload.data[0];
316 
317 	ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
318 	if (ksid_size > sidkey->datalen) {
319 		rc = smb_EIO2(smb_eio_trace_malformed_ksid_key,
320 			      ksid_size, sidkey->datalen);
321 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
322 			 __func__, sidkey->datalen, ksid_size);
323 		goto invalidate_key;
324 	}
325 
326 	cifs_copy_sid(ssid, ksid);
327 out_key_put:
328 	key_put(sidkey);
329 out_revert_creds:
330 	revert_creds(saved_cred);
331 	return rc;
332 
333 invalidate_key:
334 	key_invalidate(sidkey);
335 	goto out_key_put;
336 }
337 
338 int
339 sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid,
340 		struct cifs_fattr *fattr, uint sidtype)
341 {
342 	struct key *sidkey;
343 	char *sidstr;
344 	const struct cred *saved_cred;
345 	kuid_t fuid = cifs_sb->ctx->linux_uid;
346 	kgid_t fgid = cifs_sb->ctx->linux_gid;
347 
348 	/*
349 	 * If we have too many subauthorities, then something is really wrong.
350 	 * Just return an error.
351 	 */
352 	if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
353 		cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
354 			 __func__, psid->num_subauth);
355 		return smb_EIO2(smb_eio_trace_sid_too_many_auth,
356 				psid->num_subauth, SID_MAX_SUB_AUTHORITIES);
357 	}
358 
359 	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
360 	    (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
361 		uint32_t unix_id;
362 		bool is_group;
363 
364 		if (sidtype != SIDOWNER)
365 			is_group = true;
366 		else
367 			is_group = false;
368 
369 		if (is_well_known_sid(psid, &unix_id, is_group) == false)
370 			goto try_upcall_to_get_id;
371 
372 		if (is_group) {
373 			kgid_t gid;
374 			gid_t id;
375 
376 			id = (gid_t)unix_id;
377 			gid = make_kgid(&init_user_ns, id);
378 			if (gid_valid(gid)) {
379 				fgid = gid;
380 				goto got_valid_id;
381 			}
382 		} else {
383 			kuid_t uid;
384 			uid_t id;
385 
386 			id = (uid_t)unix_id;
387 			uid = make_kuid(&init_user_ns, id);
388 			if (uid_valid(uid)) {
389 				fuid = uid;
390 				goto got_valid_id;
391 			}
392 		}
393 		/* If unable to find uid/gid easily from SID try via upcall */
394 	}
395 
396 try_upcall_to_get_id:
397 	sidstr = sid_to_key_str(psid, sidtype);
398 	if (!sidstr)
399 		return -ENOMEM;
400 
401 	saved_cred = override_creds(root_cred);
402 	sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
403 	if (IS_ERR(sidkey)) {
404 		cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
405 			 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
406 		goto out_revert_creds;
407 	}
408 
409 	/*
410 	 * FIXME: Here we assume that uid_t and gid_t are same size. It's
411 	 * probably a safe assumption but might be better to check based on
412 	 * sidtype.
413 	 */
414 	BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
415 	if (sidkey->datalen != sizeof(uid_t)) {
416 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
417 			 __func__, sidkey->datalen);
418 		key_invalidate(sidkey);
419 		goto out_key_put;
420 	}
421 
422 	if (sidtype == SIDOWNER) {
423 		kuid_t uid;
424 		uid_t id;
425 		memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
426 		uid = make_kuid(&init_user_ns, id);
427 		if (uid_valid(uid))
428 			fuid = uid;
429 	} else {
430 		kgid_t gid;
431 		gid_t id;
432 		memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
433 		gid = make_kgid(&init_user_ns, id);
434 		if (gid_valid(gid))
435 			fgid = gid;
436 	}
437 
438 out_key_put:
439 	key_put(sidkey);
440 out_revert_creds:
441 	revert_creds(saved_cred);
442 	kfree(sidstr);
443 
444 	/*
445 	 * Note that we return 0 here unconditionally. If the mapping
446 	 * fails then we just fall back to using the ctx->linux_uid/linux_gid.
447 	 */
448 got_valid_id:
449 	if (sidtype == SIDOWNER)
450 		fattr->cf_uid = fuid;
451 	else
452 		fattr->cf_gid = fgid;
453 
454 	return 0;
455 }
456 
457 int
458 init_cifs_idmap(void)
459 {
460 	struct cred *cred;
461 	struct key *keyring;
462 	int ret;
463 
464 	cifs_dbg(FYI, "Registering the %s key type\n",
465 		 cifs_idmap_key_type.name);
466 
467 	/* create an override credential set with a special thread keyring in
468 	 * which requests are cached
469 	 *
470 	 * this is used to prevent malicious redirections from being installed
471 	 * with add_key().
472 	 */
473 	cred = prepare_kernel_cred(&init_task);
474 	if (!cred)
475 		return -ENOMEM;
476 
477 	keyring = keyring_alloc(".cifs_idmap",
478 				GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
479 				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
480 				KEY_USR_VIEW | KEY_USR_READ,
481 				KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
482 	if (IS_ERR(keyring)) {
483 		ret = PTR_ERR(keyring);
484 		goto failed_put_cred;
485 	}
486 
487 	ret = register_key_type(&cifs_idmap_key_type);
488 	if (ret < 0)
489 		goto failed_put_key;
490 
491 	/* instruct request_key() to use this special keyring as a cache for
492 	 * the results it looks up */
493 	set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
494 	cred->thread_keyring = keyring;
495 	cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
496 	root_cred = cred;
497 
498 	cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
499 	return 0;
500 
501 failed_put_key:
502 	key_put(keyring);
503 failed_put_cred:
504 	put_cred(cred);
505 	return ret;
506 }
507 
508 void
509 exit_cifs_idmap(void)
510 {
511 	key_revoke(root_cred->thread_keyring);
512 	unregister_key_type(&cifs_idmap_key_type);
513 	put_cred(root_cred);
514 	cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
515 }
516 
517 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
518 static __u32 copy_sec_desc(const struct smb_ntsd *pntsd,
519 				struct smb_ntsd *pnntsd,
520 				__u32 sidsoffset,
521 				struct smb_sid *pownersid,
522 				struct smb_sid *pgrpsid)
523 {
524 	struct smb_sid *owner_sid_ptr, *group_sid_ptr;
525 	struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr;
526 
527 	/* copy security descriptor control portion */
528 	pnntsd->revision = pntsd->revision;
529 	pnntsd->type = pntsd->type;
530 	pnntsd->dacloffset = cpu_to_le32(sizeof(struct smb_ntsd));
531 	pnntsd->sacloffset = 0;
532 	pnntsd->osidoffset = cpu_to_le32(sidsoffset);
533 	pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct smb_sid));
534 
535 	/* copy owner sid */
536 	if (pownersid)
537 		owner_sid_ptr = pownersid;
538 	else
539 		owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
540 				le32_to_cpu(pntsd->osidoffset));
541 	nowner_sid_ptr = (struct smb_sid *)((char *)pnntsd + sidsoffset);
542 	cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
543 
544 	/* copy group sid */
545 	if (pgrpsid)
546 		group_sid_ptr = pgrpsid;
547 	else
548 		group_sid_ptr = (struct smb_sid *)((char *)pntsd +
549 				le32_to_cpu(pntsd->gsidoffset));
550 	ngroup_sid_ptr = (struct smb_sid *)((char *)pnntsd + sidsoffset +
551 					sizeof(struct smb_sid));
552 	cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
553 
554 	return sidsoffset + (2 * sizeof(struct smb_sid));
555 }
556 
557 
558 /*
559    change posix mode to reflect permissions
560    pmode is the existing mode (we only want to overwrite part of this
561    bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
562 */
563 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
564 				 umode_t *pdenied, umode_t mask)
565 {
566 	__u32 flags = le32_to_cpu(ace_flags);
567 	/*
568 	 * Do not assume "preferred" or "canonical" order.
569 	 * The first DENY or ALLOW ACE which matches perfectly is
570 	 * the permission to be used. Once allowed or denied, same
571 	 * permission in later ACEs do not matter.
572 	 */
573 
574 	/* If not already allowed, deny these bits */
575 	if (type == ACCESS_DENIED) {
576 		if (flags & GENERIC_ALL &&
577 				!(*pmode & mask & 0777))
578 			*pdenied |= mask & 0777;
579 
580 		if (((flags & GENERIC_WRITE) ||
581 				((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
582 				!(*pmode & mask & 0222))
583 			*pdenied |= mask & 0222;
584 
585 		if (((flags & GENERIC_READ) ||
586 				((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
587 				!(*pmode & mask & 0444))
588 			*pdenied |= mask & 0444;
589 
590 		if (((flags & GENERIC_EXECUTE) ||
591 				((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
592 				!(*pmode & mask & 0111))
593 			*pdenied |= mask & 0111;
594 
595 		return;
596 	} else if (type != ACCESS_ALLOWED) {
597 		cifs_dbg(VFS, "unknown access control type %d\n", type);
598 		return;
599 	}
600 	/* else ACCESS_ALLOWED type */
601 
602 	if ((flags & GENERIC_ALL) &&
603 			!(*pdenied & mask & 0777)) {
604 		*pmode |= mask & 0777;
605 		cifs_dbg(NOISY, "all perms\n");
606 		return;
607 	}
608 
609 	if (((flags & GENERIC_WRITE) ||
610 			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
611 			!(*pdenied & mask & 0222))
612 		*pmode |= mask & 0222;
613 
614 	if (((flags & GENERIC_READ) ||
615 			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
616 			!(*pdenied & mask & 0444))
617 		*pmode |= mask & 0444;
618 
619 	if (((flags & GENERIC_EXECUTE) ||
620 			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
621 			!(*pdenied & mask & 0111))
622 		*pmode |= mask & 0111;
623 
624 	/* If DELETE_CHILD is set only on an owner ACE, set sticky bit */
625 	if (flags & FILE_DELETE_CHILD) {
626 		if (mask == ACL_OWNER_MASK) {
627 			if (!(*pdenied & 01000))
628 				*pmode |= 01000;
629 		} else if (!(*pdenied & 01000)) {
630 			*pmode &= ~01000;
631 			*pdenied |= 01000;
632 		}
633 	}
634 
635 	cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
636 	return;
637 }
638 
639 /*
640    Generate access flags to reflect permissions mode is the existing mode.
641    This function is called for every ACE in the DACL whose SID matches
642    with either owner or group or everyone.
643 */
644 
645 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
646 				__u32 *pace_flags)
647 {
648 	/* reset access mask */
649 	*pace_flags = 0x0;
650 
651 	/* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
652 	mode &= bits_to_use;
653 
654 	/* check for R/W/X UGO since we do not know whose flags
655 	   is this but we have cleared all the bits sans RWX for
656 	   either user or group or other as per bits_to_use */
657 	if (mode & S_IRUGO)
658 		*pace_flags |= SET_FILE_READ_RIGHTS;
659 	if (mode & S_IWUGO)
660 		*pace_flags |= SET_FILE_WRITE_RIGHTS;
661 	if (mode & S_IXUGO)
662 		*pace_flags |= SET_FILE_EXEC_RIGHTS;
663 
664 	cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
665 		 mode, *pace_flags);
666 	return;
667 }
668 
669 static __u16 cifs_copy_ace(struct smb_ace *dst, struct smb_ace *src, struct smb_sid *psid)
670 {
671 	__u16 size = 1 + 1 + 2 + 4;
672 
673 	dst->type = src->type;
674 	dst->flags = src->flags;
675 	dst->access_req = src->access_req;
676 
677 	/* Check if there's a replacement sid specified */
678 	if (psid)
679 		size += cifs_copy_sid(&dst->sid, psid);
680 	else
681 		size += cifs_copy_sid(&dst->sid, &src->sid);
682 
683 	dst->size = cpu_to_le16(size);
684 
685 	return size;
686 }
687 
688 static __u16 fill_ace_for_sid(struct smb_ace *pntace,
689 			const struct smb_sid *psid, __u64 nmode,
690 			umode_t bits, __u8 access_type,
691 			bool allow_delete_child)
692 {
693 	int i;
694 	__u16 size = 0;
695 	__u32 access_req = 0;
696 
697 	pntace->type = access_type;
698 	pntace->flags = 0x0;
699 	mode_to_access_flags(nmode, bits, &access_req);
700 
701 	if (access_type == ACCESS_ALLOWED && allow_delete_child)
702 		access_req |= FILE_DELETE_CHILD;
703 
704 	if (access_type == ACCESS_ALLOWED && !access_req)
705 		access_req = SET_MINIMUM_RIGHTS;
706 	else if (access_type == ACCESS_DENIED)
707 		access_req &= ~SET_MINIMUM_RIGHTS;
708 
709 	pntace->access_req = cpu_to_le32(access_req);
710 
711 	pntace->sid.revision = psid->revision;
712 	pntace->sid.num_subauth = psid->num_subauth;
713 	for (i = 0; i < NUM_AUTHS; i++)
714 		pntace->sid.authority[i] = psid->authority[i];
715 	for (i = 0; i < psid->num_subauth; i++)
716 		pntace->sid.sub_auth[i] = psid->sub_auth[i];
717 
718 	size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
719 	pntace->size = cpu_to_le16(size);
720 
721 	return size;
722 }
723 
724 
725 #ifdef CONFIG_CIFS_DEBUG2
726 static void dump_ace(struct smb_ace *pace, char *end_of_acl)
727 {
728 	int num_subauth;
729 
730 	/* validate that we do not go past end of acl */
731 
732 	if (le16_to_cpu(pace->size) < 16) {
733 		cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
734 		return;
735 	}
736 
737 	if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
738 		cifs_dbg(VFS, "ACL too small to parse ACE\n");
739 		return;
740 	}
741 
742 	num_subauth = pace->sid.num_subauth;
743 	if (num_subauth) {
744 		int i;
745 		cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
746 			 pace->sid.revision, pace->sid.num_subauth, pace->type,
747 			 pace->flags, le16_to_cpu(pace->size));
748 		for (i = 0; i < num_subauth; ++i) {
749 			cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
750 				 i, le32_to_cpu(pace->sid.sub_auth[i]));
751 		}
752 
753 		/* BB add length check to make sure that we do not have huge
754 			num auths and therefore go off the end */
755 	}
756 
757 	return;
758 }
759 #endif
760 
761 static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
762 		       struct smb_sid *pownersid, struct smb_sid *pgrpsid,
763 		       struct cifs_fattr *fattr, bool mode_from_special_sid)
764 {
765 	int i;
766 	u16 num_aces = 0;
767 	int acl_size;
768 	char *acl_base;
769 	struct smb_ace **ppace;
770 
771 	/* BB need to add parm so we can store the SID BB */
772 
773 	if (!pdacl) {
774 		/* no DACL in the security descriptor, set
775 		   all the permissions for user/group/other */
776 		fattr->cf_mode |= 0777;
777 		return;
778 	}
779 
780 	/* validate that we do not go past end of acl */
781 	if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl) ||
782 	    end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
783 		cifs_dbg(VFS, "ACL too small to parse DACL\n");
784 		return;
785 	}
786 
787 	cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
788 		 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
789 		 le16_to_cpu(pdacl->num_aces));
790 
791 	/* reset rwx permissions for user/group/other.
792 	   Also, if num_aces is 0 i.e. DACL has no ACEs,
793 	   user/group/other have no permissions */
794 	fattr->cf_mode &= ~(0777);
795 
796 	acl_base = (char *)pdacl;
797 	acl_size = sizeof(struct smb_acl);
798 
799 	num_aces = le16_to_cpu(pdacl->num_aces);
800 	if (num_aces > 0) {
801 		umode_t denied_mode = 0;
802 
803 		if (num_aces > (le16_to_cpu(pdacl->size) - sizeof(struct smb_acl)) /
804 				(offsetof(struct smb_ace, sid) +
805 				 offsetof(struct smb_sid, sub_auth) + sizeof(__le16)))
806 			return;
807 
808 		ppace = kmalloc_objs(struct smb_ace *, num_aces);
809 		if (!ppace)
810 			return;
811 
812 		for (i = 0; i < num_aces; ++i) {
813 			if (end_of_acl - acl_base < acl_size)
814 				break;
815 
816 			ppace[i] = (struct smb_ace *) (acl_base + acl_size);
817 			acl_base = (char *)ppace[i];
818 			acl_size = offsetof(struct smb_ace, sid) +
819 				offsetof(struct smb_sid, sub_auth);
820 
821 			if (end_of_acl - acl_base < acl_size ||
822 			    ppace[i]->sid.num_subauth == 0 ||
823 			    ppace[i]->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
824 			    (end_of_acl - acl_base <
825 			     acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) ||
826 			    (le16_to_cpu(ppace[i]->size) <
827 			     acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth))
828 				break;
829 
830 #ifdef CONFIG_CIFS_DEBUG2
831 			dump_ace(ppace[i], end_of_acl);
832 #endif
833 			if (mode_from_special_sid &&
834 			    (compare_sids(&(ppace[i]->sid),
835 					  &sid_unix_NFS_mode) == 0)) {
836 				/*
837 				 * Full permissions are:
838 				 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
839 				 *         S_IRWXU | S_IRWXG | S_IRWXO
840 				 */
841 				fattr->cf_mode &= ~07777;
842 				fattr->cf_mode |=
843 					le32_to_cpu(ppace[i]->sid.sub_auth[2]);
844 				break;
845 			} else {
846 				if (compare_sids(&(ppace[i]->sid), pownersid) == 0) {
847 					access_flags_to_mode(ppace[i]->access_req,
848 							ppace[i]->type,
849 							&fattr->cf_mode,
850 							&denied_mode,
851 							ACL_OWNER_MASK);
852 				} else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) {
853 					access_flags_to_mode(ppace[i]->access_req,
854 							ppace[i]->type,
855 							&fattr->cf_mode,
856 							&denied_mode,
857 							ACL_GROUP_MASK);
858 				} else if ((compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) ||
859 						(compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)) {
860 					access_flags_to_mode(ppace[i]->access_req,
861 							ppace[i]->type,
862 							&fattr->cf_mode,
863 							&denied_mode,
864 							ACL_EVERYONE_MASK);
865 				}
866 			}
867 
868 
869 /*			memcpy((void *)(&(cifscred->aces[i])),
870 				(void *)ppace[i],
871 				sizeof(struct smb_ace)); */
872 
873 			acl_size = le16_to_cpu(ppace[i]->size);
874 		}
875 
876 		kfree(ppace);
877 	}
878 
879 	return;
880 }
881 
882 unsigned int setup_authusers_ACE(struct smb_ace *pntace)
883 {
884 	int i;
885 	unsigned int ace_size = 20;
886 
887 	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
888 	pntace->flags = 0x0;
889 	pntace->access_req = cpu_to_le32(GENERIC_ALL);
890 	pntace->sid.num_subauth = 1;
891 	pntace->sid.revision = 1;
892 	for (i = 0; i < NUM_AUTHS; i++)
893 		pntace->sid.authority[i] =  sid_authusers.authority[i];
894 
895 	pntace->sid.sub_auth[0] =  sid_authusers.sub_auth[0];
896 
897 	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
898 	pntace->size = cpu_to_le16(ace_size);
899 	return ace_size;
900 }
901 
902 /*
903  * Fill in the special SID based on the mode. See
904  * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
905  */
906 unsigned int setup_special_mode_ACE(struct smb_ace *pntace,
907 				    bool posix,
908 				    __u64 nmode)
909 {
910 	int i;
911 	unsigned int ace_size = 28;
912 
913 	if (posix)
914 		pntace->type = ACCESS_ALLOWED_ACE_TYPE;
915 	else
916 		pntace->type = ACCESS_DENIED_ACE_TYPE;
917 	pntace->flags = 0x0;
918 	pntace->access_req = 0;
919 	pntace->sid.num_subauth = 3;
920 	pntace->sid.revision = 1;
921 	for (i = 0; i < NUM_AUTHS; i++)
922 		pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
923 
924 	pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
925 	pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
926 	pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
927 
928 	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
929 	pntace->size = cpu_to_le16(ace_size);
930 	return ace_size;
931 }
932 
933 unsigned int setup_special_user_owner_ACE(struct smb_ace *pntace)
934 {
935 	int i;
936 	unsigned int ace_size = 28;
937 
938 	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
939 	pntace->flags = 0x0;
940 	pntace->access_req = cpu_to_le32(GENERIC_ALL);
941 	pntace->sid.num_subauth = 3;
942 	pntace->sid.revision = 1;
943 	for (i = 0; i < NUM_AUTHS; i++)
944 		pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
945 
946 	pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
947 	pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
948 	pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
949 
950 	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
951 	pntace->size = cpu_to_le16(ace_size);
952 	return ace_size;
953 }
954 
955 static void populate_new_aces(char *nacl_base,
956 		struct smb_sid *pownersid,
957 		struct smb_sid *pgrpsid,
958 		__u64 *pnmode, u16 *pnum_aces, u16 *pnsize,
959 		bool modefromsid,
960 		bool posix)
961 {
962 	__u64 nmode;
963 	u16 num_aces = 0;
964 	u16 nsize = 0;
965 	__u64 user_mode;
966 	__u64 group_mode;
967 	__u64 other_mode;
968 	__u64 deny_user_mode = 0;
969 	__u64 deny_group_mode = 0;
970 	bool sticky_set = false;
971 	struct smb_ace *pnntace = NULL;
972 
973 	nmode = *pnmode;
974 	num_aces = *pnum_aces;
975 	nsize = *pnsize;
976 
977 	if (modefromsid || posix) {
978 		pnntace = (struct smb_ace *) (nacl_base + nsize);
979 		nsize += setup_special_mode_ACE(pnntace, posix, nmode);
980 		num_aces++;
981 		if (modefromsid) {
982 			pnntace = (struct smb_ace *) (nacl_base + nsize);
983 			nsize += setup_authusers_ACE(pnntace);
984 			num_aces++;
985 		}
986 		goto set_size;
987 	}
988 
989 	/*
990 	 * We'll try to keep the mode as requested by the user.
991 	 * But in cases where we cannot meaningfully convert that
992 	 * into ACL, return back the updated mode, so that it is
993 	 * updated in the inode.
994 	 */
995 
996 	if (!memcmp(pownersid, pgrpsid, sizeof(struct smb_sid))) {
997 		/*
998 		 * Case when owner and group SIDs are the same.
999 		 * Set the more restrictive of the two modes.
1000 		 */
1001 		user_mode = nmode & (nmode << 3) & 0700;
1002 		group_mode = nmode & (nmode >> 3) & 0070;
1003 	} else {
1004 		user_mode = nmode & 0700;
1005 		group_mode = nmode & 0070;
1006 	}
1007 
1008 	other_mode = nmode & 0007;
1009 
1010 	/* We need DENY ACE when the perm is more restrictive than the next sets. */
1011 	deny_user_mode = ~(user_mode) & ((group_mode << 3) | (other_mode << 6)) & 0700;
1012 	deny_group_mode = ~(group_mode) & (other_mode << 3) & 0070;
1013 
1014 	*pnmode = user_mode | group_mode | other_mode | (nmode & ~0777);
1015 
1016 	/* This tells if we should allow delete child for group and everyone. */
1017 	if (nmode & 01000)
1018 		sticky_set = true;
1019 
1020 	if (deny_user_mode) {
1021 		pnntace = (struct smb_ace *) (nacl_base + nsize);
1022 		nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode,
1023 				0700, ACCESS_DENIED, false);
1024 		num_aces++;
1025 	}
1026 
1027 	/* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/
1028 	if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) {
1029 		pnntace = (struct smb_ace *) (nacl_base + nsize);
1030 		nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1031 				0070, ACCESS_DENIED, false);
1032 		num_aces++;
1033 	}
1034 
1035 	pnntace = (struct smb_ace *) (nacl_base + nsize);
1036 	nsize += fill_ace_for_sid(pnntace, pownersid, user_mode,
1037 			0700, ACCESS_ALLOWED, true);
1038 	num_aces++;
1039 
1040 	/* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */
1041 	if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) {
1042 		pnntace = (struct smb_ace *) (nacl_base + nsize);
1043 		nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1044 				0070, ACCESS_DENIED, false);
1045 		num_aces++;
1046 	}
1047 
1048 	pnntace = (struct smb_ace *) (nacl_base + nsize);
1049 	nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode,
1050 			0070, ACCESS_ALLOWED, !sticky_set);
1051 	num_aces++;
1052 
1053 	pnntace = (struct smb_ace *) (nacl_base + nsize);
1054 	nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode,
1055 			0007, ACCESS_ALLOWED, !sticky_set);
1056 	num_aces++;
1057 
1058 set_size:
1059 	*pnum_aces = num_aces;
1060 	*pnsize = nsize;
1061 }
1062 
1063 static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl,
1064 		struct smb_sid *pownersid, struct smb_sid *pgrpsid,
1065 		struct smb_sid *pnownersid, struct smb_sid *pngrpsid)
1066 {
1067 	int i;
1068 	u16 size = 0;
1069 	struct smb_ace *pntace = NULL;
1070 	char *acl_base = NULL;
1071 	u16 src_num_aces = 0;
1072 	u16 nsize = 0;
1073 	struct smb_ace *pnntace = NULL;
1074 	char *nacl_base = NULL;
1075 	u16 ace_size = 0;
1076 
1077 	acl_base = (char *)pdacl;
1078 	size = sizeof(struct smb_acl);
1079 	src_num_aces = le16_to_cpu(pdacl->num_aces);
1080 
1081 	nacl_base = (char *)pndacl;
1082 	nsize = sizeof(struct smb_acl);
1083 
1084 	/* Go through all the ACEs */
1085 	for (i = 0; i < src_num_aces; ++i) {
1086 		pntace = (struct smb_ace *) (acl_base + size);
1087 		pnntace = (struct smb_ace *) (nacl_base + nsize);
1088 
1089 		if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0)
1090 			ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
1091 		else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0)
1092 			ace_size = cifs_copy_ace(pnntace, pntace, pngrpsid);
1093 		else
1094 			ace_size = cifs_copy_ace(pnntace, pntace, NULL);
1095 
1096 		size += le16_to_cpu(pntace->size);
1097 		nsize += ace_size;
1098 	}
1099 
1100 	return nsize;
1101 }
1102 
1103 static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
1104 		struct smb_sid *pownersid,	struct smb_sid *pgrpsid,
1105 		__u64 *pnmode, bool mode_from_sid, bool posix)
1106 {
1107 	int i;
1108 	u16 size = 0;
1109 	struct smb_ace *pntace = NULL;
1110 	char *acl_base = NULL;
1111 	u16 src_num_aces = 0;
1112 	u16 nsize = 0;
1113 	struct smb_ace *pnntace = NULL;
1114 	char *nacl_base = NULL;
1115 	u16 num_aces = 0;
1116 	bool new_aces_set = false;
1117 
1118 	/* Assuming that pndacl and pnmode are never NULL */
1119 	nacl_base = (char *)pndacl;
1120 	nsize = sizeof(struct smb_acl);
1121 
1122 	/* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
1123 	if (!pdacl || posix) {
1124 		populate_new_aces(nacl_base,
1125 				pownersid, pgrpsid,
1126 				pnmode, &num_aces, &nsize,
1127 				mode_from_sid, posix);
1128 		goto finalize_dacl;
1129 	}
1130 
1131 	acl_base = (char *)pdacl;
1132 	size = sizeof(struct smb_acl);
1133 	src_num_aces = le16_to_cpu(pdacl->num_aces);
1134 
1135 	/* Retain old ACEs which we can retain */
1136 	for (i = 0; i < src_num_aces; ++i) {
1137 		pntace = (struct smb_ace *) (acl_base + size);
1138 
1139 		if (!new_aces_set && (pntace->flags & INHERITED_ACE)) {
1140 			/* Place the new ACEs in between existing explicit and inherited */
1141 			populate_new_aces(nacl_base,
1142 					pownersid, pgrpsid,
1143 					pnmode, &num_aces, &nsize,
1144 					mode_from_sid, posix);
1145 
1146 			new_aces_set = true;
1147 		}
1148 
1149 		/* If it's any one of the ACE we're replacing, skip! */
1150 		if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
1151 				(compare_sids(&pntace->sid, pownersid) == 0) ||
1152 				(compare_sids(&pntace->sid, pgrpsid) == 0) ||
1153 				(compare_sids(&pntace->sid, &sid_everyone) == 0) ||
1154 				(compare_sids(&pntace->sid, &sid_authusers) == 0))) {
1155 			goto next_ace;
1156 		}
1157 
1158 		/* update the pointer to the next ACE to populate*/
1159 		pnntace = (struct smb_ace *) (nacl_base + nsize);
1160 
1161 		nsize += cifs_copy_ace(pnntace, pntace, NULL);
1162 		num_aces++;
1163 
1164 next_ace:
1165 		size += le16_to_cpu(pntace->size);
1166 	}
1167 
1168 	/* If inherited ACEs are not present, place the new ones at the tail */
1169 	if (!new_aces_set) {
1170 		populate_new_aces(nacl_base,
1171 				pownersid, pgrpsid,
1172 				pnmode, &num_aces, &nsize,
1173 				mode_from_sid, posix);
1174 
1175 		new_aces_set = true;
1176 	}
1177 
1178 finalize_dacl:
1179 	pndacl->num_aces = cpu_to_le16(num_aces);
1180 	pndacl->size = cpu_to_le16(nsize);
1181 
1182 	return 0;
1183 }
1184 
1185 static int parse_sid(struct smb_sid *psid, char *end_of_acl)
1186 {
1187 	/* BB need to add parm so we can store the SID BB */
1188 
1189 	/* validate that we do not go past end of ACL - sid must be at least 8
1190 	   bytes long (assuming no sub-auths - e.g. the null SID */
1191 	if (end_of_acl < (char *)psid + 8) {
1192 		cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
1193 		return -EINVAL;
1194 	}
1195 
1196 #ifdef CONFIG_CIFS_DEBUG2
1197 	if (psid->num_subauth) {
1198 		int i;
1199 		cifs_dbg(FYI, "SID revision %d num_auth %d\n",
1200 			 psid->revision, psid->num_subauth);
1201 
1202 		for (i = 0; i < psid->num_subauth; i++) {
1203 			cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
1204 				 i, le32_to_cpu(psid->sub_auth[i]));
1205 		}
1206 
1207 		/* BB add length check to make sure that we do not have huge
1208 			num auths and therefore go off the end */
1209 		cifs_dbg(FYI, "RID 0x%x\n",
1210 			 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1211 	}
1212 #endif
1213 
1214 	return 0;
1215 }
1216 
1217 
1218 /* Convert CIFS ACL to POSIX form */
1219 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1220 		struct smb_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
1221 		bool get_mode_from_special_sid)
1222 {
1223 	int rc = 0;
1224 	struct smb_sid *owner_sid_ptr, *group_sid_ptr;
1225 	struct smb_acl *dacl_ptr; /* no need for SACL ptr */
1226 	char *end_of_acl = ((char *)pntsd) + acl_len;
1227 	__u32 dacloffset;
1228 
1229 	if (pntsd == NULL)
1230 		return smb_EIO(smb_eio_trace_null_pointers);
1231 
1232 	owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
1233 				le32_to_cpu(pntsd->osidoffset));
1234 	group_sid_ptr = (struct smb_sid *)((char *)pntsd +
1235 				le32_to_cpu(pntsd->gsidoffset));
1236 	dacloffset = le32_to_cpu(pntsd->dacloffset);
1237 	dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1238 	cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1239 		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1240 		 le32_to_cpu(pntsd->gsidoffset),
1241 		 le32_to_cpu(pntsd->sacloffset), dacloffset);
1242 /*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1243 	rc = parse_sid(owner_sid_ptr, end_of_acl);
1244 	if (rc) {
1245 		cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1246 		return rc;
1247 	}
1248 	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1249 	if (rc) {
1250 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1251 			 __func__, rc);
1252 		return rc;
1253 	}
1254 
1255 	rc = parse_sid(group_sid_ptr, end_of_acl);
1256 	if (rc) {
1257 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
1258 			 __func__, rc);
1259 		return rc;
1260 	}
1261 	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1262 	if (rc) {
1263 		cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1264 			 __func__, rc);
1265 		return rc;
1266 	}
1267 
1268 	if (dacloffset)
1269 		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1270 			   group_sid_ptr, fattr, get_mode_from_special_sid);
1271 	else
1272 		cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
1273 
1274 	return rc;
1275 }
1276 
1277 /* Convert permission bits from mode to equivalent CIFS ACL */
1278 static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
1279 	__u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
1280 	bool mode_from_sid, bool id_from_sid, bool posix, int *aclflag)
1281 {
1282 	int rc = 0;
1283 	__u32 dacloffset;
1284 	__u32 ndacloffset;
1285 	__u32 sidsoffset;
1286 	struct smb_sid *owner_sid_ptr, *group_sid_ptr;
1287 	struct smb_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
1288 	struct smb_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
1289 	struct smb_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1290 	char *end_of_acl = ((char *)pntsd) + secdesclen;
1291 	u16 size = 0;
1292 
1293 	dacloffset = le32_to_cpu(pntsd->dacloffset);
1294 	if (dacloffset) {
1295 		dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1296 		if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) {
1297 			cifs_dbg(VFS, "Server returned illegal ACL size\n");
1298 			return -EINVAL;
1299 		}
1300 	}
1301 
1302 	owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
1303 			le32_to_cpu(pntsd->osidoffset));
1304 	group_sid_ptr = (struct smb_sid *)((char *)pntsd +
1305 			le32_to_cpu(pntsd->gsidoffset));
1306 
1307 	if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1308 		ndacloffset = sizeof(struct smb_ntsd);
1309 		ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset);
1310 		ndacl_ptr->revision =
1311 			dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1312 
1313 		ndacl_ptr->size = cpu_to_le16(0);
1314 		ndacl_ptr->num_aces = cpu_to_le16(0);
1315 
1316 		rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1317 				    pnmode, mode_from_sid, posix);
1318 
1319 		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1320 		/* copy the non-dacl portion of secdesc */
1321 		*pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1322 				NULL, NULL);
1323 
1324 		*aclflag |= CIFS_ACL_DACL;
1325 	} else {
1326 		ndacloffset = sizeof(struct smb_ntsd);
1327 		ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset);
1328 		ndacl_ptr->revision =
1329 			dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1330 		ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0;
1331 
1332 		if (uid_valid(uid)) { /* chown */
1333 			uid_t id;
1334 			nowner_sid_ptr = kzalloc_obj(struct smb_sid);
1335 			if (!nowner_sid_ptr) {
1336 				rc = -ENOMEM;
1337 				goto chown_chgrp_exit;
1338 			}
1339 			id = from_kuid(&init_user_ns, uid);
1340 			if (id_from_sid) {
1341 				struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1342 				/* Populate the user ownership fields S-1-5-88-1 */
1343 				osid->Revision = 1;
1344 				osid->NumAuth = 3;
1345 				osid->Authority[5] = 5;
1346 				osid->SubAuthorities[0] = cpu_to_le32(88);
1347 				osid->SubAuthorities[1] = cpu_to_le32(1);
1348 				osid->SubAuthorities[2] = cpu_to_le32(id);
1349 
1350 			} else { /* lookup sid with upcall */
1351 				rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1352 				if (rc) {
1353 					cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1354 						 __func__, rc, id);
1355 					goto chown_chgrp_exit;
1356 				}
1357 			}
1358 			*aclflag |= CIFS_ACL_OWNER;
1359 		}
1360 		if (gid_valid(gid)) { /* chgrp */
1361 			gid_t id;
1362 			ngroup_sid_ptr = kzalloc_obj(struct smb_sid);
1363 			if (!ngroup_sid_ptr) {
1364 				rc = -ENOMEM;
1365 				goto chown_chgrp_exit;
1366 			}
1367 			id = from_kgid(&init_user_ns, gid);
1368 			if (id_from_sid) {
1369 				struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1370 				/* Populate the group ownership fields S-1-5-88-2 */
1371 				gsid->Revision = 1;
1372 				gsid->NumAuth = 3;
1373 				gsid->Authority[5] = 5;
1374 				gsid->SubAuthorities[0] = cpu_to_le32(88);
1375 				gsid->SubAuthorities[1] = cpu_to_le32(2);
1376 				gsid->SubAuthorities[2] = cpu_to_le32(id);
1377 
1378 			} else { /* lookup sid with upcall */
1379 				rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1380 				if (rc) {
1381 					cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1382 						 __func__, rc, id);
1383 					goto chown_chgrp_exit;
1384 				}
1385 			}
1386 			*aclflag |= CIFS_ACL_GROUP;
1387 		}
1388 
1389 		if (dacloffset) {
1390 			/* Replace ACEs for old owner with new one */
1391 			size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1392 					owner_sid_ptr, group_sid_ptr,
1393 					nowner_sid_ptr, ngroup_sid_ptr);
1394 			ndacl_ptr->size = cpu_to_le16(size);
1395 		}
1396 
1397 		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1398 		/* copy the non-dacl portion of secdesc */
1399 		*pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1400 				nowner_sid_ptr, ngroup_sid_ptr);
1401 
1402 chown_chgrp_exit:
1403 		/* errors could jump here. So make sure we return soon after this */
1404 		kfree(nowner_sid_ptr);
1405 		kfree(ngroup_sid_ptr);
1406 	}
1407 
1408 	return rc;
1409 }
1410 
1411 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1412 struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1413 				      const struct cifs_fid *cifsfid, u32 *pacllen,
1414 				      u32 info)
1415 {
1416 	struct smb_ntsd *pntsd = NULL;
1417 	unsigned int xid;
1418 	int rc;
1419 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1420 
1421 	if (IS_ERR(tlink))
1422 		return ERR_CAST(tlink);
1423 
1424 	xid = get_xid();
1425 	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1426 				pacllen, info);
1427 	free_xid(xid);
1428 
1429 	cifs_put_tlink(tlink);
1430 
1431 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1432 	if (rc)
1433 		return ERR_PTR(rc);
1434 	return pntsd;
1435 }
1436 
1437 static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1438 		const char *path, u32 *pacllen, u32 info)
1439 {
1440 	struct smb_ntsd *pntsd = NULL;
1441 	int oplock = 0;
1442 	unsigned int xid;
1443 	int rc;
1444 	struct cifs_tcon *tcon;
1445 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1446 	struct cifs_fid fid;
1447 	struct cifs_open_parms oparms;
1448 
1449 	if (IS_ERR(tlink))
1450 		return ERR_CAST(tlink);
1451 
1452 	tcon = tlink_tcon(tlink);
1453 	xid = get_xid();
1454 
1455 	oparms = (struct cifs_open_parms) {
1456 		.tcon = tcon,
1457 		.cifs_sb = cifs_sb,
1458 		.desired_access = READ_CONTROL,
1459 		.create_options = cifs_create_options(cifs_sb, 0),
1460 		.disposition = FILE_OPEN,
1461 		.path = path,
1462 		.fid = &fid,
1463 	};
1464 
1465 	if (info & SACL_SECINFO)
1466 		oparms.desired_access |= SYSTEM_SECURITY;
1467 
1468 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1469 	if (!rc) {
1470 		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen, info);
1471 		CIFSSMBClose(xid, tcon, fid.netfid);
1472 	}
1473 
1474 	cifs_put_tlink(tlink);
1475 	free_xid(xid);
1476 
1477 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1478 	if (rc)
1479 		return ERR_PTR(rc);
1480 	return pntsd;
1481 }
1482 
1483 /* Retrieve an ACL from the server */
1484 struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1485 				      struct inode *inode, const char *path,
1486 			       u32 *pacllen, u32 info)
1487 {
1488 	struct smb_ntsd *pntsd = NULL;
1489 	struct cifsFileInfo *open_file = NULL;
1490 
1491 	if (inode)
1492 		open_file = find_readable_file(CIFS_I(inode), true);
1493 	if (!open_file)
1494 		return get_cifs_acl_by_path(cifs_sb, path, pacllen, info);
1495 
1496 	pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1497 	cifsFileInfo_put(open_file);
1498 	return pntsd;
1499 }
1500 
1501  /* Set an ACL on the server */
1502 int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
1503 			struct inode *inode, const char *path, int aclflag)
1504 {
1505 	int oplock = 0;
1506 	unsigned int xid;
1507 	int rc, access_flags = 0;
1508 	struct cifs_tcon *tcon;
1509 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1510 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1511 	struct cifs_fid fid;
1512 	struct cifs_open_parms oparms;
1513 
1514 	if (IS_ERR(tlink))
1515 		return PTR_ERR(tlink);
1516 
1517 	tcon = tlink_tcon(tlink);
1518 	xid = get_xid();
1519 
1520 	if (aclflag & CIFS_ACL_OWNER || aclflag & CIFS_ACL_GROUP)
1521 		access_flags |= WRITE_OWNER;
1522 	if (aclflag & CIFS_ACL_SACL)
1523 		access_flags |= SYSTEM_SECURITY;
1524 	if (aclflag & CIFS_ACL_DACL)
1525 		access_flags |= WRITE_DAC;
1526 
1527 	oparms = (struct cifs_open_parms) {
1528 		.tcon = tcon,
1529 		.cifs_sb = cifs_sb,
1530 		.desired_access = access_flags,
1531 		.create_options = cifs_create_options(cifs_sb, 0),
1532 		.disposition = FILE_OPEN,
1533 		.path = path,
1534 		.fid = &fid,
1535 	};
1536 
1537 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1538 	if (rc) {
1539 		cifs_dbg(VFS, "Unable to open file to set ACL\n");
1540 		goto out;
1541 	}
1542 
1543 	rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1544 	cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1545 
1546 	CIFSSMBClose(xid, tcon, fid.netfid);
1547 out:
1548 	free_xid(xid);
1549 	cifs_put_tlink(tlink);
1550 	return rc;
1551 }
1552 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1553 
1554 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1555 int
1556 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1557 		  struct inode *inode, bool mode_from_special_sid,
1558 		  const char *path, const struct cifs_fid *pfid)
1559 {
1560 	struct smb_ntsd *pntsd = NULL;
1561 	u32 acllen = 0;
1562 	int rc = 0;
1563 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1564 	struct smb_version_operations *ops;
1565 	const u32 info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO;
1566 
1567 	cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1568 
1569 	if (IS_ERR(tlink))
1570 		return PTR_ERR(tlink);
1571 
1572 	ops = tlink_tcon(tlink)->ses->server->ops;
1573 
1574 	if (pfid && (ops->get_acl_by_fid))
1575 		pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1576 	else if (ops->get_acl)
1577 		pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1578 	else {
1579 		cifs_put_tlink(tlink);
1580 		return -EOPNOTSUPP;
1581 	}
1582 	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1583 	if (IS_ERR(pntsd)) {
1584 		rc = PTR_ERR(pntsd);
1585 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1586 	} else if (mode_from_special_sid) {
1587 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1588 		kfree(pntsd);
1589 	} else {
1590 		/* get approximated mode from ACL */
1591 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1592 		kfree(pntsd);
1593 		if (rc)
1594 			cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1595 	}
1596 
1597 	cifs_put_tlink(tlink);
1598 
1599 	return rc;
1600 }
1601 
1602 /* Convert mode bits to an ACL so we can update the ACL on the server */
1603 int
1604 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1605 			kuid_t uid, kgid_t gid)
1606 {
1607 	int rc = 0;
1608 	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1609 	__u32 secdesclen = 0;
1610 	__u32 nsecdesclen = 0;
1611 	__u32 dacloffset = 0;
1612 	struct smb_acl *dacl_ptr = NULL;
1613 	struct smb_ntsd *pntsd = NULL; /* acl obtained from server */
1614 	struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1615 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1616 	struct tcon_link *tlink;
1617 	struct smb_version_operations *ops;
1618 	bool mode_from_sid, id_from_sid;
1619 	const u32 info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO;
1620 	bool posix;
1621 
1622 	tlink = cifs_sb_tlink(cifs_sb);
1623 	if (IS_ERR(tlink))
1624 		return PTR_ERR(tlink);
1625 	posix = tlink_tcon(tlink)->posix_extensions;
1626 
1627 	ops = tlink_tcon(tlink)->ses->server->ops;
1628 
1629 	cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1630 
1631 	/* Get the security descriptor */
1632 
1633 	if (ops->get_acl == NULL) {
1634 		cifs_put_tlink(tlink);
1635 		return -EOPNOTSUPP;
1636 	}
1637 
1638 	pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1639 	if (IS_ERR(pntsd)) {
1640 		rc = PTR_ERR(pntsd);
1641 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1642 		cifs_put_tlink(tlink);
1643 		return rc;
1644 	}
1645 
1646 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1647 		mode_from_sid = true;
1648 	else
1649 		mode_from_sid = false;
1650 
1651 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1652 		id_from_sid = true;
1653 	else
1654 		id_from_sid = false;
1655 
1656 	/* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1657 	if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1658 		if (posix)
1659 			nsecdesclen = 1 * sizeof(struct smb_ace);
1660 		else if (mode_from_sid)
1661 			nsecdesclen = secdesclen + (2 * sizeof(struct smb_ace));
1662 		else /* cifsacl */
1663 			nsecdesclen = secdesclen + (5 * sizeof(struct smb_ace));
1664 	} else { /* chown */
1665 		/* When ownership changes, changes new owner sid length could be different */
1666 		nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2);
1667 		dacloffset = le32_to_cpu(pntsd->dacloffset);
1668 		if (dacloffset) {
1669 			dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1670 			if (mode_from_sid)
1671 				nsecdesclen +=
1672 					le16_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
1673 			else /* cifsacl */
1674 				nsecdesclen += le16_to_cpu(dacl_ptr->size);
1675 		}
1676 	}
1677 
1678 	/*
1679 	 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1680 	 * as chmod disables ACEs and set the security descriptor. Allocate
1681 	 * memory for the smb header, set security descriptor request security
1682 	 * descriptor parameters, and security descriptor itself
1683 	 */
1684 	nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1685 	pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);
1686 	if (!pnntsd) {
1687 		kfree(pntsd);
1688 		cifs_put_tlink(tlink);
1689 		return -ENOMEM;
1690 	}
1691 
1692 	rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1693 			    mode_from_sid, id_from_sid, posix, &aclflag);
1694 
1695 	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1696 
1697 	if (ops->set_acl == NULL)
1698 		rc = -EOPNOTSUPP;
1699 
1700 	if (!rc) {
1701 		/* Set the security descriptor */
1702 		rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1703 		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1704 	}
1705 	cifs_put_tlink(tlink);
1706 
1707 	kfree(pnntsd);
1708 	kfree(pntsd);
1709 	return rc;
1710 }
1711 
1712 struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap,
1713 			       struct dentry *dentry, int type)
1714 {
1715 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1716 	struct posix_acl *acl = NULL;
1717 	ssize_t rc = -EOPNOTSUPP;
1718 	unsigned int xid;
1719 	struct super_block *sb = dentry->d_sb;
1720 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1721 	struct tcon_link *tlink;
1722 	struct cifs_tcon *pTcon;
1723 	const char *full_path;
1724 	void *page;
1725 
1726 	tlink = cifs_sb_tlink(cifs_sb);
1727 	if (IS_ERR(tlink))
1728 		return ERR_CAST(tlink);
1729 	pTcon = tlink_tcon(tlink);
1730 
1731 	xid = get_xid();
1732 	page = alloc_dentry_path();
1733 
1734 	full_path = build_path_from_dentry(dentry, page);
1735 	if (IS_ERR(full_path)) {
1736 		acl = ERR_CAST(full_path);
1737 		goto out;
1738 	}
1739 
1740 	/* return alt name if available as pseudo attr */
1741 	switch (type) {
1742 	case ACL_TYPE_ACCESS:
1743 		if (sb->s_flags & SB_POSIXACL)
1744 			rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1745 					     ACL_TYPE_ACCESS,
1746 					     cifs_sb->local_nls,
1747 					     cifs_remap(cifs_sb));
1748 		break;
1749 
1750 	case ACL_TYPE_DEFAULT:
1751 		if (sb->s_flags & SB_POSIXACL)
1752 			rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1753 					     ACL_TYPE_DEFAULT,
1754 					     cifs_sb->local_nls,
1755 					     cifs_remap(cifs_sb));
1756 		break;
1757 	}
1758 
1759 	if (rc < 0) {
1760 		if (rc == -EINVAL)
1761 			acl = ERR_PTR(-EOPNOTSUPP);
1762 		else
1763 			acl = ERR_PTR(rc);
1764 	}
1765 
1766 out:
1767 	free_dentry_path(page);
1768 	free_xid(xid);
1769 	cifs_put_tlink(tlink);
1770 	return acl;
1771 #else
1772 	return ERR_PTR(-EOPNOTSUPP);
1773 #endif
1774 }
1775 
1776 int cifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
1777 		 struct posix_acl *acl, int type)
1778 {
1779 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1780 	int rc = -EOPNOTSUPP;
1781 	unsigned int xid;
1782 	struct super_block *sb = dentry->d_sb;
1783 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1784 	struct tcon_link *tlink;
1785 	struct cifs_tcon *pTcon;
1786 	const char *full_path;
1787 	void *page;
1788 
1789 	tlink = cifs_sb_tlink(cifs_sb);
1790 	if (IS_ERR(tlink))
1791 		return PTR_ERR(tlink);
1792 	pTcon = tlink_tcon(tlink);
1793 
1794 	xid = get_xid();
1795 	page = alloc_dentry_path();
1796 
1797 	full_path = build_path_from_dentry(dentry, page);
1798 	if (IS_ERR(full_path)) {
1799 		rc = PTR_ERR(full_path);
1800 		goto out;
1801 	}
1802 
1803 	if (!acl)
1804 		goto out;
1805 
1806 	/* return dos attributes as pseudo xattr */
1807 	/* return alt name if available as pseudo attr */
1808 
1809 	/* if proc/fs/cifs/streamstoxattr is set then
1810 		search server for EAs or streams to
1811 		returns as xattrs */
1812 	if (posix_acl_xattr_size(acl->a_count) > CIFSMaxBufSize) {
1813 		cifs_dbg(FYI, "size of EA value too large\n");
1814 		rc = -EOPNOTSUPP;
1815 		goto out;
1816 	}
1817 
1818 	switch (type) {
1819 	case ACL_TYPE_ACCESS:
1820 		if (sb->s_flags & SB_POSIXACL)
1821 			rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1822 					     ACL_TYPE_ACCESS,
1823 					     cifs_sb->local_nls,
1824 					     cifs_remap(cifs_sb));
1825 		break;
1826 
1827 	case ACL_TYPE_DEFAULT:
1828 		if (sb->s_flags & SB_POSIXACL)
1829 			rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1830 					     ACL_TYPE_DEFAULT,
1831 					     cifs_sb->local_nls,
1832 					     cifs_remap(cifs_sb));
1833 		break;
1834 	}
1835 
1836 out:
1837 	free_dentry_path(page);
1838 	free_xid(xid);
1839 	cifs_put_tlink(tlink);
1840 	return rc;
1841 #else
1842 	return -EOPNOTSUPP;
1843 #endif
1844 }
1845