xref: /linux/fs/smb/client/cifsacl.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
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 "cifspdu.h"
21 #include "cifsglob.h"
22 #include "cifsacl.h"
23 #include "cifsproto.h"
24 #include "cifs_debug.h"
25 #include "fs_context.h"
26 #include "cifs_fs_sb.h"
27 #include "cifs_unicode.h"
28 
29 /* security id for everyone/world system group */
30 static const struct smb_sid sid_everyone = {
31 	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
32 /* security id for Authenticated Users system group */
33 static const struct smb_sid sid_authusers = {
34 	1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
35 
36 /* S-1-22-1 Unmapped Unix users */
37 static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
38 		{cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
39 
40 /* S-1-22-2 Unmapped Unix groups */
41 static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
42 		{cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
43 
44 /*
45  * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
46  */
47 
48 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
49 
50 /* S-1-5-88-1 Unix uid */
51 static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
52 	{cpu_to_le32(88),
53 	 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
54 
55 /* S-1-5-88-2 Unix gid */
56 static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
57 	{cpu_to_le32(88),
58 	 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
59 
60 /* S-1-5-88-3 Unix mode */
61 static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
62 	{cpu_to_le32(88),
63 	 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
64 
65 static const struct cred *root_cred;
66 
67 static int
68 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
69 {
70 	char *payload;
71 
72 	/*
73 	 * If the payload is less than or equal to the size of a pointer, then
74 	 * an allocation here is wasteful. Just copy the data directly to the
75 	 * payload.value union member instead.
76 	 *
77 	 * With this however, you must check the datalen before trying to
78 	 * dereference payload.data!
79 	 */
80 	if (prep->datalen <= sizeof(key->payload)) {
81 		key->payload.data[0] = NULL;
82 		memcpy(&key->payload, prep->data, prep->datalen);
83 	} else {
84 		payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
85 		if (!payload)
86 			return -ENOMEM;
87 		key->payload.data[0] = payload;
88 	}
89 
90 	key->datalen = prep->datalen;
91 	return 0;
92 }
93 
94 static inline void
95 cifs_idmap_key_destroy(struct key *key)
96 {
97 	if (key->datalen > sizeof(key->payload))
98 		kfree(key->payload.data[0]);
99 }
100 
101 static struct key_type cifs_idmap_key_type = {
102 	.name        = "cifs.idmap",
103 	.instantiate = cifs_idmap_key_instantiate,
104 	.destroy     = cifs_idmap_key_destroy,
105 	.describe    = user_describe,
106 };
107 
108 static char *
109 sid_to_key_str(struct smb_sid *sidptr, unsigned int type)
110 {
111 	int i, len;
112 	unsigned int saval;
113 	char *sidstr, *strptr;
114 	unsigned long long id_auth_val;
115 
116 	/* 3 bytes for prefix */
117 	sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
118 			 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
119 			 GFP_KERNEL);
120 	if (!sidstr)
121 		return sidstr;
122 
123 	strptr = sidstr;
124 	len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
125 			sidptr->revision);
126 	strptr += len;
127 
128 	/* The authority field is a single 48-bit number */
129 	id_auth_val = (unsigned long long)sidptr->authority[5];
130 	id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
131 	id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
132 	id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
133 	id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
134 	id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
135 
136 	/*
137 	 * MS-DTYP states that if the authority is >= 2^32, then it should be
138 	 * expressed as a hex value.
139 	 */
140 	if (id_auth_val <= UINT_MAX)
141 		len = sprintf(strptr, "-%llu", id_auth_val);
142 	else
143 		len = sprintf(strptr, "-0x%llx", id_auth_val);
144 
145 	strptr += len;
146 
147 	for (i = 0; i < sidptr->num_subauth; ++i) {
148 		saval = le32_to_cpu(sidptr->sub_auth[i]);
149 		len = sprintf(strptr, "-%u", saval);
150 		strptr += len;
151 	}
152 
153 	return sidstr;
154 }
155 
156 /*
157  * if the two SIDs (roughly equivalent to a UUID for a user or group) are
158  * the same returns zero, if they do not match returns non-zero.
159  */
160 static int
161 compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
162 {
163 	int i;
164 	int num_subauth, num_sat, num_saw;
165 
166 	if ((!ctsid) || (!cwsid))
167 		return 1;
168 
169 	/* compare the revision */
170 	if (ctsid->revision != cwsid->revision) {
171 		if (ctsid->revision > cwsid->revision)
172 			return 1;
173 		else
174 			return -1;
175 	}
176 
177 	/* compare all of the six auth values */
178 	for (i = 0; i < NUM_AUTHS; ++i) {
179 		if (ctsid->authority[i] != cwsid->authority[i]) {
180 			if (ctsid->authority[i] > cwsid->authority[i])
181 				return 1;
182 			else
183 				return -1;
184 		}
185 	}
186 
187 	/* compare all of the subauth values if any */
188 	num_sat = ctsid->num_subauth;
189 	num_saw = cwsid->num_subauth;
190 	num_subauth = min(num_sat, num_saw);
191 	if (num_subauth) {
192 		for (i = 0; i < num_subauth; ++i) {
193 			if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
194 				if (le32_to_cpu(ctsid->sub_auth[i]) >
195 					le32_to_cpu(cwsid->sub_auth[i]))
196 					return 1;
197 				else
198 					return -1;
199 			}
200 		}
201 	}
202 
203 	return 0; /* sids compare/match */
204 }
205 
206 static bool
207 is_well_known_sid(const struct smb_sid *psid, uint32_t *puid, bool is_group)
208 {
209 	int i;
210 	int num_subauth;
211 	const struct smb_sid *pwell_known_sid;
212 
213 	if (!psid || (puid == NULL))
214 		return false;
215 
216 	num_subauth = psid->num_subauth;
217 
218 	/* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
219 	if (num_subauth == 2) {
220 		if (is_group)
221 			pwell_known_sid = &sid_unix_groups;
222 		else
223 			pwell_known_sid = &sid_unix_users;
224 	} else if (num_subauth == 3) {
225 		if (is_group)
226 			pwell_known_sid = &sid_unix_NFS_groups;
227 		else
228 			pwell_known_sid = &sid_unix_NFS_users;
229 	} else
230 		return false;
231 
232 	/* compare the revision */
233 	if (psid->revision != pwell_known_sid->revision)
234 		return false;
235 
236 	/* compare all of the six auth values */
237 	for (i = 0; i < NUM_AUTHS; ++i) {
238 		if (psid->authority[i] != pwell_known_sid->authority[i]) {
239 			cifs_dbg(FYI, "auth %d did not match\n", i);
240 			return false;
241 		}
242 	}
243 
244 	if (num_subauth == 2) {
245 		if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
246 			return false;
247 
248 		*puid = le32_to_cpu(psid->sub_auth[1]);
249 	} else /* 3 subauths, ie Windows/Mac style */ {
250 		*puid = le32_to_cpu(psid->sub_auth[0]);
251 		if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
252 		    (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
253 			return false;
254 
255 		*puid = le32_to_cpu(psid->sub_auth[2]);
256 	}
257 
258 	cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
259 	return true; /* well known sid found, uid returned */
260 }
261 
262 static __u16
263 cifs_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
264 {
265 	int i;
266 	__u16 size = 1 + 1 + 6;
267 
268 	dst->revision = src->revision;
269 	dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
270 	for (i = 0; i < NUM_AUTHS; ++i)
271 		dst->authority[i] = src->authority[i];
272 	for (i = 0; i < dst->num_subauth; ++i)
273 		dst->sub_auth[i] = src->sub_auth[i];
274 	size += (dst->num_subauth * 4);
275 
276 	return size;
277 }
278 
279 static int
280 id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
281 {
282 	int rc;
283 	struct key *sidkey;
284 	struct smb_sid *ksid;
285 	unsigned int ksid_size;
286 	char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
287 	const struct cred *saved_cred;
288 
289 	rc = snprintf(desc, sizeof(desc), "%ci:%u",
290 			sidtype == SIDOWNER ? 'o' : 'g', cid);
291 	if (rc >= sizeof(desc))
292 		return -EINVAL;
293 
294 	rc = 0;
295 	saved_cred = override_creds(root_cred);
296 	sidkey = request_key(&cifs_idmap_key_type, desc, "");
297 	if (IS_ERR(sidkey)) {
298 		rc = -EINVAL;
299 		cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
300 			 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
301 		goto out_revert_creds;
302 	} else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
303 		rc = -EIO;
304 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
305 			 __func__, sidkey->datalen);
306 		goto invalidate_key;
307 	}
308 
309 	/*
310 	 * A sid is usually too large to be embedded in payload.value, but if
311 	 * there are no subauthorities and the host has 8-byte pointers, then
312 	 * it could be.
313 	 */
314 	ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
315 		(struct smb_sid *)&sidkey->payload :
316 		(struct smb_sid *)sidkey->payload.data[0];
317 
318 	ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
319 	if (ksid_size > sidkey->datalen) {
320 		rc = -EIO;
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 	int rc = 0;
343 	struct key *sidkey;
344 	char *sidstr;
345 	const struct cred *saved_cred;
346 	kuid_t fuid = cifs_sb->ctx->linux_uid;
347 	kgid_t fgid = cifs_sb->ctx->linux_gid;
348 
349 	/*
350 	 * If we have too many subauthorities, then something is really wrong.
351 	 * Just return an error.
352 	 */
353 	if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
354 		cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
355 			 __func__, psid->num_subauth);
356 		return -EIO;
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 	rc = 0;
450 	if (sidtype == SIDOWNER)
451 		fattr->cf_uid = fuid;
452 	else
453 		fattr->cf_gid = fgid;
454 	return rc;
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 	int 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 + le16_to_cpu(pdacl->size)) {
782 		cifs_dbg(VFS, "ACL too small to parse DACL\n");
783 		return;
784 	}
785 
786 	cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
787 		 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
788 		 le32_to_cpu(pdacl->num_aces));
789 
790 	/* reset rwx permissions for user/group/other.
791 	   Also, if num_aces is 0 i.e. DACL has no ACEs,
792 	   user/group/other have no permissions */
793 	fattr->cf_mode &= ~(0777);
794 
795 	acl_base = (char *)pdacl;
796 	acl_size = sizeof(struct smb_acl);
797 
798 	num_aces = le32_to_cpu(pdacl->num_aces);
799 	if (num_aces > 0) {
800 		umode_t denied_mode = 0;
801 
802 		if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
803 			return;
804 		ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *),
805 				      GFP_KERNEL);
806 		if (!ppace)
807 			return;
808 
809 		for (i = 0; i < num_aces; ++i) {
810 			ppace[i] = (struct smb_ace *) (acl_base + acl_size);
811 #ifdef CONFIG_CIFS_DEBUG2
812 			dump_ace(ppace[i], end_of_acl);
813 #endif
814 			if (mode_from_special_sid &&
815 			    (compare_sids(&(ppace[i]->sid),
816 					  &sid_unix_NFS_mode) == 0)) {
817 				/*
818 				 * Full permissions are:
819 				 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
820 				 *         S_IRWXU | S_IRWXG | S_IRWXO
821 				 */
822 				fattr->cf_mode &= ~07777;
823 				fattr->cf_mode |=
824 					le32_to_cpu(ppace[i]->sid.sub_auth[2]);
825 				break;
826 			} else {
827 				if (compare_sids(&(ppace[i]->sid), pownersid) == 0) {
828 					access_flags_to_mode(ppace[i]->access_req,
829 							ppace[i]->type,
830 							&fattr->cf_mode,
831 							&denied_mode,
832 							ACL_OWNER_MASK);
833 				} else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) {
834 					access_flags_to_mode(ppace[i]->access_req,
835 							ppace[i]->type,
836 							&fattr->cf_mode,
837 							&denied_mode,
838 							ACL_GROUP_MASK);
839 				} else if ((compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) ||
840 						(compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)) {
841 					access_flags_to_mode(ppace[i]->access_req,
842 							ppace[i]->type,
843 							&fattr->cf_mode,
844 							&denied_mode,
845 							ACL_EVERYONE_MASK);
846 				}
847 			}
848 
849 
850 /*			memcpy((void *)(&(cifscred->aces[i])),
851 				(void *)ppace[i],
852 				sizeof(struct smb_ace)); */
853 
854 			acl_base = (char *)ppace[i];
855 			acl_size = le16_to_cpu(ppace[i]->size);
856 		}
857 
858 		kfree(ppace);
859 	}
860 
861 	return;
862 }
863 
864 unsigned int setup_authusers_ACE(struct smb_ace *pntace)
865 {
866 	int i;
867 	unsigned int ace_size = 20;
868 
869 	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
870 	pntace->flags = 0x0;
871 	pntace->access_req = cpu_to_le32(GENERIC_ALL);
872 	pntace->sid.num_subauth = 1;
873 	pntace->sid.revision = 1;
874 	for (i = 0; i < NUM_AUTHS; i++)
875 		pntace->sid.authority[i] =  sid_authusers.authority[i];
876 
877 	pntace->sid.sub_auth[0] =  sid_authusers.sub_auth[0];
878 
879 	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
880 	pntace->size = cpu_to_le16(ace_size);
881 	return ace_size;
882 }
883 
884 /*
885  * Fill in the special SID based on the mode. See
886  * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
887  */
888 unsigned int setup_special_mode_ACE(struct smb_ace *pntace,
889 				    bool posix,
890 				    __u64 nmode)
891 {
892 	int i;
893 	unsigned int ace_size = 28;
894 
895 	if (posix)
896 		pntace->type = ACCESS_ALLOWED_ACE_TYPE;
897 	else
898 		pntace->type = ACCESS_DENIED_ACE_TYPE;
899 	pntace->flags = 0x0;
900 	pntace->access_req = 0;
901 	pntace->sid.num_subauth = 3;
902 	pntace->sid.revision = 1;
903 	for (i = 0; i < NUM_AUTHS; i++)
904 		pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
905 
906 	pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
907 	pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
908 	pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
909 
910 	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
911 	pntace->size = cpu_to_le16(ace_size);
912 	return ace_size;
913 }
914 
915 unsigned int setup_special_user_owner_ACE(struct smb_ace *pntace)
916 {
917 	int i;
918 	unsigned int ace_size = 28;
919 
920 	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
921 	pntace->flags = 0x0;
922 	pntace->access_req = cpu_to_le32(GENERIC_ALL);
923 	pntace->sid.num_subauth = 3;
924 	pntace->sid.revision = 1;
925 	for (i = 0; i < NUM_AUTHS; i++)
926 		pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
927 
928 	pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
929 	pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
930 	pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
931 
932 	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
933 	pntace->size = cpu_to_le16(ace_size);
934 	return ace_size;
935 }
936 
937 static void populate_new_aces(char *nacl_base,
938 		struct smb_sid *pownersid,
939 		struct smb_sid *pgrpsid,
940 		__u64 *pnmode, u32 *pnum_aces, u16 *pnsize,
941 		bool modefromsid,
942 		bool posix)
943 {
944 	__u64 nmode;
945 	u32 num_aces = 0;
946 	u16 nsize = 0;
947 	__u64 user_mode;
948 	__u64 group_mode;
949 	__u64 other_mode;
950 	__u64 deny_user_mode = 0;
951 	__u64 deny_group_mode = 0;
952 	bool sticky_set = false;
953 	struct smb_ace *pnntace = NULL;
954 
955 	nmode = *pnmode;
956 	num_aces = *pnum_aces;
957 	nsize = *pnsize;
958 
959 	if (modefromsid || posix) {
960 		pnntace = (struct smb_ace *) (nacl_base + nsize);
961 		nsize += setup_special_mode_ACE(pnntace, posix, nmode);
962 		num_aces++;
963 		if (modefromsid) {
964 			pnntace = (struct smb_ace *) (nacl_base + nsize);
965 			nsize += setup_authusers_ACE(pnntace);
966 			num_aces++;
967 		}
968 		goto set_size;
969 	}
970 
971 	/*
972 	 * We'll try to keep the mode as requested by the user.
973 	 * But in cases where we cannot meaningfully convert that
974 	 * into ACL, return back the updated mode, so that it is
975 	 * updated in the inode.
976 	 */
977 
978 	if (!memcmp(pownersid, pgrpsid, sizeof(struct smb_sid))) {
979 		/*
980 		 * Case when owner and group SIDs are the same.
981 		 * Set the more restrictive of the two modes.
982 		 */
983 		user_mode = nmode & (nmode << 3) & 0700;
984 		group_mode = nmode & (nmode >> 3) & 0070;
985 	} else {
986 		user_mode = nmode & 0700;
987 		group_mode = nmode & 0070;
988 	}
989 
990 	other_mode = nmode & 0007;
991 
992 	/* We need DENY ACE when the perm is more restrictive than the next sets. */
993 	deny_user_mode = ~(user_mode) & ((group_mode << 3) | (other_mode << 6)) & 0700;
994 	deny_group_mode = ~(group_mode) & (other_mode << 3) & 0070;
995 
996 	*pnmode = user_mode | group_mode | other_mode | (nmode & ~0777);
997 
998 	/* This tells if we should allow delete child for group and everyone. */
999 	if (nmode & 01000)
1000 		sticky_set = true;
1001 
1002 	if (deny_user_mode) {
1003 		pnntace = (struct smb_ace *) (nacl_base + nsize);
1004 		nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode,
1005 				0700, ACCESS_DENIED, false);
1006 		num_aces++;
1007 	}
1008 
1009 	/* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/
1010 	if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) {
1011 		pnntace = (struct smb_ace *) (nacl_base + nsize);
1012 		nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1013 				0070, ACCESS_DENIED, false);
1014 		num_aces++;
1015 	}
1016 
1017 	pnntace = (struct smb_ace *) (nacl_base + nsize);
1018 	nsize += fill_ace_for_sid(pnntace, pownersid, user_mode,
1019 			0700, ACCESS_ALLOWED, true);
1020 	num_aces++;
1021 
1022 	/* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */
1023 	if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) {
1024 		pnntace = (struct smb_ace *) (nacl_base + nsize);
1025 		nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1026 				0070, ACCESS_DENIED, false);
1027 		num_aces++;
1028 	}
1029 
1030 	pnntace = (struct smb_ace *) (nacl_base + nsize);
1031 	nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode,
1032 			0070, ACCESS_ALLOWED, !sticky_set);
1033 	num_aces++;
1034 
1035 	pnntace = (struct smb_ace *) (nacl_base + nsize);
1036 	nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode,
1037 			0007, ACCESS_ALLOWED, !sticky_set);
1038 	num_aces++;
1039 
1040 set_size:
1041 	*pnum_aces = num_aces;
1042 	*pnsize = nsize;
1043 }
1044 
1045 static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl,
1046 		struct smb_sid *pownersid, struct smb_sid *pgrpsid,
1047 		struct smb_sid *pnownersid, struct smb_sid *pngrpsid)
1048 {
1049 	int i;
1050 	u16 size = 0;
1051 	struct smb_ace *pntace = NULL;
1052 	char *acl_base = NULL;
1053 	u32 src_num_aces = 0;
1054 	u16 nsize = 0;
1055 	struct smb_ace *pnntace = NULL;
1056 	char *nacl_base = NULL;
1057 	u16 ace_size = 0;
1058 
1059 	acl_base = (char *)pdacl;
1060 	size = sizeof(struct smb_acl);
1061 	src_num_aces = le32_to_cpu(pdacl->num_aces);
1062 
1063 	nacl_base = (char *)pndacl;
1064 	nsize = sizeof(struct smb_acl);
1065 
1066 	/* Go through all the ACEs */
1067 	for (i = 0; i < src_num_aces; ++i) {
1068 		pntace = (struct smb_ace *) (acl_base + size);
1069 		pnntace = (struct smb_ace *) (nacl_base + nsize);
1070 
1071 		if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0)
1072 			ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
1073 		else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0)
1074 			ace_size = cifs_copy_ace(pnntace, pntace, pngrpsid);
1075 		else
1076 			ace_size = cifs_copy_ace(pnntace, pntace, NULL);
1077 
1078 		size += le16_to_cpu(pntace->size);
1079 		nsize += ace_size;
1080 	}
1081 
1082 	return nsize;
1083 }
1084 
1085 static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
1086 		struct smb_sid *pownersid,	struct smb_sid *pgrpsid,
1087 		__u64 *pnmode, bool mode_from_sid, bool posix)
1088 {
1089 	int i;
1090 	u16 size = 0;
1091 	struct smb_ace *pntace = NULL;
1092 	char *acl_base = NULL;
1093 	u32 src_num_aces = 0;
1094 	u16 nsize = 0;
1095 	struct smb_ace *pnntace = NULL;
1096 	char *nacl_base = NULL;
1097 	u32 num_aces = 0;
1098 	bool new_aces_set = false;
1099 
1100 	/* Assuming that pndacl and pnmode are never NULL */
1101 	nacl_base = (char *)pndacl;
1102 	nsize = sizeof(struct smb_acl);
1103 
1104 	/* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
1105 	if (!pdacl || posix) {
1106 		populate_new_aces(nacl_base,
1107 				pownersid, pgrpsid,
1108 				pnmode, &num_aces, &nsize,
1109 				mode_from_sid, posix);
1110 		goto finalize_dacl;
1111 	}
1112 
1113 	acl_base = (char *)pdacl;
1114 	size = sizeof(struct smb_acl);
1115 	src_num_aces = le32_to_cpu(pdacl->num_aces);
1116 
1117 	/* Retain old ACEs which we can retain */
1118 	for (i = 0; i < src_num_aces; ++i) {
1119 		pntace = (struct smb_ace *) (acl_base + size);
1120 
1121 		if (!new_aces_set && (pntace->flags & INHERITED_ACE)) {
1122 			/* Place the new ACEs in between existing explicit and inherited */
1123 			populate_new_aces(nacl_base,
1124 					pownersid, pgrpsid,
1125 					pnmode, &num_aces, &nsize,
1126 					mode_from_sid, posix);
1127 
1128 			new_aces_set = true;
1129 		}
1130 
1131 		/* If it's any one of the ACE we're replacing, skip! */
1132 		if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
1133 				(compare_sids(&pntace->sid, pownersid) == 0) ||
1134 				(compare_sids(&pntace->sid, pgrpsid) == 0) ||
1135 				(compare_sids(&pntace->sid, &sid_everyone) == 0) ||
1136 				(compare_sids(&pntace->sid, &sid_authusers) == 0))) {
1137 			goto next_ace;
1138 		}
1139 
1140 		/* update the pointer to the next ACE to populate*/
1141 		pnntace = (struct smb_ace *) (nacl_base + nsize);
1142 
1143 		nsize += cifs_copy_ace(pnntace, pntace, NULL);
1144 		num_aces++;
1145 
1146 next_ace:
1147 		size += le16_to_cpu(pntace->size);
1148 	}
1149 
1150 	/* If inherited ACEs are not present, place the new ones at the tail */
1151 	if (!new_aces_set) {
1152 		populate_new_aces(nacl_base,
1153 				pownersid, pgrpsid,
1154 				pnmode, &num_aces, &nsize,
1155 				mode_from_sid, posix);
1156 
1157 		new_aces_set = true;
1158 	}
1159 
1160 finalize_dacl:
1161 	pndacl->num_aces = cpu_to_le32(num_aces);
1162 	pndacl->size = cpu_to_le16(nsize);
1163 
1164 	return 0;
1165 }
1166 
1167 static int parse_sid(struct smb_sid *psid, char *end_of_acl)
1168 {
1169 	/* BB need to add parm so we can store the SID BB */
1170 
1171 	/* validate that we do not go past end of ACL - sid must be at least 8
1172 	   bytes long (assuming no sub-auths - e.g. the null SID */
1173 	if (end_of_acl < (char *)psid + 8) {
1174 		cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
1175 		return -EINVAL;
1176 	}
1177 
1178 #ifdef CONFIG_CIFS_DEBUG2
1179 	if (psid->num_subauth) {
1180 		int i;
1181 		cifs_dbg(FYI, "SID revision %d num_auth %d\n",
1182 			 psid->revision, psid->num_subauth);
1183 
1184 		for (i = 0; i < psid->num_subauth; i++) {
1185 			cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
1186 				 i, le32_to_cpu(psid->sub_auth[i]));
1187 		}
1188 
1189 		/* BB add length check to make sure that we do not have huge
1190 			num auths and therefore go off the end */
1191 		cifs_dbg(FYI, "RID 0x%x\n",
1192 			 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1193 	}
1194 #endif
1195 
1196 	return 0;
1197 }
1198 
1199 
1200 /* Convert CIFS ACL to POSIX form */
1201 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1202 		struct smb_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
1203 		bool get_mode_from_special_sid)
1204 {
1205 	int rc = 0;
1206 	struct smb_sid *owner_sid_ptr, *group_sid_ptr;
1207 	struct smb_acl *dacl_ptr; /* no need for SACL ptr */
1208 	char *end_of_acl = ((char *)pntsd) + acl_len;
1209 	__u32 dacloffset;
1210 
1211 	if (pntsd == NULL)
1212 		return -EIO;
1213 
1214 	owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
1215 				le32_to_cpu(pntsd->osidoffset));
1216 	group_sid_ptr = (struct smb_sid *)((char *)pntsd +
1217 				le32_to_cpu(pntsd->gsidoffset));
1218 	dacloffset = le32_to_cpu(pntsd->dacloffset);
1219 	dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1220 	cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1221 		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1222 		 le32_to_cpu(pntsd->gsidoffset),
1223 		 le32_to_cpu(pntsd->sacloffset), dacloffset);
1224 /*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1225 	rc = parse_sid(owner_sid_ptr, end_of_acl);
1226 	if (rc) {
1227 		cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1228 		return rc;
1229 	}
1230 	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1231 	if (rc) {
1232 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1233 			 __func__, rc);
1234 		return rc;
1235 	}
1236 
1237 	rc = parse_sid(group_sid_ptr, end_of_acl);
1238 	if (rc) {
1239 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
1240 			 __func__, rc);
1241 		return rc;
1242 	}
1243 	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1244 	if (rc) {
1245 		cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1246 			 __func__, rc);
1247 		return rc;
1248 	}
1249 
1250 	if (dacloffset)
1251 		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1252 			   group_sid_ptr, fattr, get_mode_from_special_sid);
1253 	else
1254 		cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
1255 
1256 	return rc;
1257 }
1258 
1259 /* Convert permission bits from mode to equivalent CIFS ACL */
1260 static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
1261 	__u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
1262 	bool mode_from_sid, bool id_from_sid, bool posix, int *aclflag)
1263 {
1264 	int rc = 0;
1265 	__u32 dacloffset;
1266 	__u32 ndacloffset;
1267 	__u32 sidsoffset;
1268 	struct smb_sid *owner_sid_ptr, *group_sid_ptr;
1269 	struct smb_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
1270 	struct smb_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
1271 	struct smb_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1272 	char *end_of_acl = ((char *)pntsd) + secdesclen;
1273 	u16 size = 0;
1274 
1275 	dacloffset = le32_to_cpu(pntsd->dacloffset);
1276 	if (dacloffset) {
1277 		dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1278 		if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) {
1279 			cifs_dbg(VFS, "Server returned illegal ACL size\n");
1280 			return -EINVAL;
1281 		}
1282 	}
1283 
1284 	owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
1285 			le32_to_cpu(pntsd->osidoffset));
1286 	group_sid_ptr = (struct smb_sid *)((char *)pntsd +
1287 			le32_to_cpu(pntsd->gsidoffset));
1288 
1289 	if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1290 		ndacloffset = sizeof(struct smb_ntsd);
1291 		ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset);
1292 		ndacl_ptr->revision =
1293 			dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1294 
1295 		ndacl_ptr->size = cpu_to_le16(0);
1296 		ndacl_ptr->num_aces = cpu_to_le32(0);
1297 
1298 		rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1299 				    pnmode, mode_from_sid, posix);
1300 
1301 		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1302 		/* copy the non-dacl portion of secdesc */
1303 		*pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1304 				NULL, NULL);
1305 
1306 		*aclflag |= CIFS_ACL_DACL;
1307 	} else {
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 		ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0;
1313 
1314 		if (uid_valid(uid)) { /* chown */
1315 			uid_t id;
1316 			nowner_sid_ptr = kzalloc(sizeof(struct smb_sid),
1317 								GFP_KERNEL);
1318 			if (!nowner_sid_ptr) {
1319 				rc = -ENOMEM;
1320 				goto chown_chgrp_exit;
1321 			}
1322 			id = from_kuid(&init_user_ns, uid);
1323 			if (id_from_sid) {
1324 				struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1325 				/* Populate the user ownership fields S-1-5-88-1 */
1326 				osid->Revision = 1;
1327 				osid->NumAuth = 3;
1328 				osid->Authority[5] = 5;
1329 				osid->SubAuthorities[0] = cpu_to_le32(88);
1330 				osid->SubAuthorities[1] = cpu_to_le32(1);
1331 				osid->SubAuthorities[2] = cpu_to_le32(id);
1332 
1333 			} else { /* lookup sid with upcall */
1334 				rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1335 				if (rc) {
1336 					cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1337 						 __func__, rc, id);
1338 					goto chown_chgrp_exit;
1339 				}
1340 			}
1341 			*aclflag |= CIFS_ACL_OWNER;
1342 		}
1343 		if (gid_valid(gid)) { /* chgrp */
1344 			gid_t id;
1345 			ngroup_sid_ptr = kzalloc(sizeof(struct smb_sid),
1346 								GFP_KERNEL);
1347 			if (!ngroup_sid_ptr) {
1348 				rc = -ENOMEM;
1349 				goto chown_chgrp_exit;
1350 			}
1351 			id = from_kgid(&init_user_ns, gid);
1352 			if (id_from_sid) {
1353 				struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1354 				/* Populate the group ownership fields S-1-5-88-2 */
1355 				gsid->Revision = 1;
1356 				gsid->NumAuth = 3;
1357 				gsid->Authority[5] = 5;
1358 				gsid->SubAuthorities[0] = cpu_to_le32(88);
1359 				gsid->SubAuthorities[1] = cpu_to_le32(2);
1360 				gsid->SubAuthorities[2] = cpu_to_le32(id);
1361 
1362 			} else { /* lookup sid with upcall */
1363 				rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1364 				if (rc) {
1365 					cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1366 						 __func__, rc, id);
1367 					goto chown_chgrp_exit;
1368 				}
1369 			}
1370 			*aclflag |= CIFS_ACL_GROUP;
1371 		}
1372 
1373 		if (dacloffset) {
1374 			/* Replace ACEs for old owner with new one */
1375 			size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1376 					owner_sid_ptr, group_sid_ptr,
1377 					nowner_sid_ptr, ngroup_sid_ptr);
1378 			ndacl_ptr->size = cpu_to_le16(size);
1379 		}
1380 
1381 		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1382 		/* copy the non-dacl portion of secdesc */
1383 		*pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1384 				nowner_sid_ptr, ngroup_sid_ptr);
1385 
1386 chown_chgrp_exit:
1387 		/* errors could jump here. So make sure we return soon after this */
1388 		kfree(nowner_sid_ptr);
1389 		kfree(ngroup_sid_ptr);
1390 	}
1391 
1392 	return rc;
1393 }
1394 
1395 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1396 struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1397 				      const struct cifs_fid *cifsfid, u32 *pacllen,
1398 				      u32 __maybe_unused unused)
1399 {
1400 	struct smb_ntsd *pntsd = NULL;
1401 	unsigned int xid;
1402 	int rc;
1403 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1404 
1405 	if (IS_ERR(tlink))
1406 		return ERR_CAST(tlink);
1407 
1408 	xid = get_xid();
1409 	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1410 				pacllen);
1411 	free_xid(xid);
1412 
1413 	cifs_put_tlink(tlink);
1414 
1415 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1416 	if (rc)
1417 		return ERR_PTR(rc);
1418 	return pntsd;
1419 }
1420 
1421 static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1422 		const char *path, u32 *pacllen)
1423 {
1424 	struct smb_ntsd *pntsd = NULL;
1425 	int oplock = 0;
1426 	unsigned int xid;
1427 	int rc;
1428 	struct cifs_tcon *tcon;
1429 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1430 	struct cifs_fid fid;
1431 	struct cifs_open_parms oparms;
1432 
1433 	if (IS_ERR(tlink))
1434 		return ERR_CAST(tlink);
1435 
1436 	tcon = tlink_tcon(tlink);
1437 	xid = get_xid();
1438 
1439 	oparms = (struct cifs_open_parms) {
1440 		.tcon = tcon,
1441 		.cifs_sb = cifs_sb,
1442 		.desired_access = READ_CONTROL,
1443 		.create_options = cifs_create_options(cifs_sb, 0),
1444 		.disposition = FILE_OPEN,
1445 		.path = path,
1446 		.fid = &fid,
1447 	};
1448 
1449 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1450 	if (!rc) {
1451 		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1452 		CIFSSMBClose(xid, tcon, fid.netfid);
1453 	}
1454 
1455 	cifs_put_tlink(tlink);
1456 	free_xid(xid);
1457 
1458 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1459 	if (rc)
1460 		return ERR_PTR(rc);
1461 	return pntsd;
1462 }
1463 
1464 /* Retrieve an ACL from the server */
1465 struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1466 				      struct inode *inode, const char *path,
1467 			       u32 *pacllen, u32 info)
1468 {
1469 	struct smb_ntsd *pntsd = NULL;
1470 	struct cifsFileInfo *open_file = NULL;
1471 
1472 	if (inode)
1473 		open_file = find_readable_file(CIFS_I(inode), true);
1474 	if (!open_file)
1475 		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1476 
1477 	pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1478 	cifsFileInfo_put(open_file);
1479 	return pntsd;
1480 }
1481 
1482  /* Set an ACL on the server */
1483 int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
1484 			struct inode *inode, const char *path, int aclflag)
1485 {
1486 	int oplock = 0;
1487 	unsigned int xid;
1488 	int rc, access_flags;
1489 	struct cifs_tcon *tcon;
1490 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1491 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1492 	struct cifs_fid fid;
1493 	struct cifs_open_parms oparms;
1494 
1495 	if (IS_ERR(tlink))
1496 		return PTR_ERR(tlink);
1497 
1498 	tcon = tlink_tcon(tlink);
1499 	xid = get_xid();
1500 
1501 	if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1502 		access_flags = WRITE_OWNER;
1503 	else
1504 		access_flags = WRITE_DAC;
1505 
1506 	oparms = (struct cifs_open_parms) {
1507 		.tcon = tcon,
1508 		.cifs_sb = cifs_sb,
1509 		.desired_access = access_flags,
1510 		.create_options = cifs_create_options(cifs_sb, 0),
1511 		.disposition = FILE_OPEN,
1512 		.path = path,
1513 		.fid = &fid,
1514 	};
1515 
1516 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1517 	if (rc) {
1518 		cifs_dbg(VFS, "Unable to open file to set ACL\n");
1519 		goto out;
1520 	}
1521 
1522 	rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1523 	cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1524 
1525 	CIFSSMBClose(xid, tcon, fid.netfid);
1526 out:
1527 	free_xid(xid);
1528 	cifs_put_tlink(tlink);
1529 	return rc;
1530 }
1531 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1532 
1533 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1534 int
1535 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1536 		  struct inode *inode, bool mode_from_special_sid,
1537 		  const char *path, const struct cifs_fid *pfid)
1538 {
1539 	struct smb_ntsd *pntsd = NULL;
1540 	u32 acllen = 0;
1541 	int rc = 0;
1542 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1543 	struct smb_version_operations *ops;
1544 	const u32 info = 0;
1545 
1546 	cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1547 
1548 	if (IS_ERR(tlink))
1549 		return PTR_ERR(tlink);
1550 
1551 	ops = tlink_tcon(tlink)->ses->server->ops;
1552 
1553 	if (pfid && (ops->get_acl_by_fid))
1554 		pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1555 	else if (ops->get_acl)
1556 		pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1557 	else {
1558 		cifs_put_tlink(tlink);
1559 		return -EOPNOTSUPP;
1560 	}
1561 	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1562 	if (IS_ERR(pntsd)) {
1563 		rc = PTR_ERR(pntsd);
1564 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1565 	} else if (mode_from_special_sid) {
1566 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1567 		kfree(pntsd);
1568 	} else {
1569 		/* get approximated mode from ACL */
1570 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1571 		kfree(pntsd);
1572 		if (rc)
1573 			cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1574 	}
1575 
1576 	cifs_put_tlink(tlink);
1577 
1578 	return rc;
1579 }
1580 
1581 /* Convert mode bits to an ACL so we can update the ACL on the server */
1582 int
1583 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1584 			kuid_t uid, kgid_t gid)
1585 {
1586 	int rc = 0;
1587 	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1588 	__u32 secdesclen = 0;
1589 	__u32 nsecdesclen = 0;
1590 	__u32 dacloffset = 0;
1591 	struct smb_acl *dacl_ptr = NULL;
1592 	struct smb_ntsd *pntsd = NULL; /* acl obtained from server */
1593 	struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1594 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1595 	struct tcon_link *tlink;
1596 	struct smb_version_operations *ops;
1597 	bool mode_from_sid, id_from_sid;
1598 	const u32 info = 0;
1599 	bool posix;
1600 
1601 	tlink = cifs_sb_tlink(cifs_sb);
1602 	if (IS_ERR(tlink))
1603 		return PTR_ERR(tlink);
1604 	posix = tlink_tcon(tlink)->posix_extensions;
1605 
1606 	ops = tlink_tcon(tlink)->ses->server->ops;
1607 
1608 	cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1609 
1610 	/* Get the security descriptor */
1611 
1612 	if (ops->get_acl == NULL) {
1613 		cifs_put_tlink(tlink);
1614 		return -EOPNOTSUPP;
1615 	}
1616 
1617 	pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1618 	if (IS_ERR(pntsd)) {
1619 		rc = PTR_ERR(pntsd);
1620 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1621 		cifs_put_tlink(tlink);
1622 		return rc;
1623 	}
1624 
1625 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1626 		mode_from_sid = true;
1627 	else
1628 		mode_from_sid = false;
1629 
1630 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1631 		id_from_sid = true;
1632 	else
1633 		id_from_sid = false;
1634 
1635 	/* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1636 	if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1637 		if (posix)
1638 			nsecdesclen = 1 * sizeof(struct smb_ace);
1639 		else if (mode_from_sid)
1640 			nsecdesclen = secdesclen + (2 * sizeof(struct smb_ace));
1641 		else /* cifsacl */
1642 			nsecdesclen = secdesclen + (5 * sizeof(struct smb_ace));
1643 	} else { /* chown */
1644 		/* When ownership changes, changes new owner sid length could be different */
1645 		nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2);
1646 		dacloffset = le32_to_cpu(pntsd->dacloffset);
1647 		if (dacloffset) {
1648 			dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1649 			if (mode_from_sid)
1650 				nsecdesclen +=
1651 					le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
1652 			else /* cifsacl */
1653 				nsecdesclen += le16_to_cpu(dacl_ptr->size);
1654 		}
1655 	}
1656 
1657 	/*
1658 	 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1659 	 * as chmod disables ACEs and set the security descriptor. Allocate
1660 	 * memory for the smb header, set security descriptor request security
1661 	 * descriptor parameters, and security descriptor itself
1662 	 */
1663 	nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1664 	pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);
1665 	if (!pnntsd) {
1666 		kfree(pntsd);
1667 		cifs_put_tlink(tlink);
1668 		return -ENOMEM;
1669 	}
1670 
1671 	rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1672 			    mode_from_sid, id_from_sid, posix, &aclflag);
1673 
1674 	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1675 
1676 	if (ops->set_acl == NULL)
1677 		rc = -EOPNOTSUPP;
1678 
1679 	if (!rc) {
1680 		/* Set the security descriptor */
1681 		rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1682 		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1683 	}
1684 	cifs_put_tlink(tlink);
1685 
1686 	kfree(pnntsd);
1687 	kfree(pntsd);
1688 	return rc;
1689 }
1690 
1691 struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap,
1692 			       struct dentry *dentry, int type)
1693 {
1694 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1695 	struct posix_acl *acl = NULL;
1696 	ssize_t rc = -EOPNOTSUPP;
1697 	unsigned int xid;
1698 	struct super_block *sb = dentry->d_sb;
1699 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1700 	struct tcon_link *tlink;
1701 	struct cifs_tcon *pTcon;
1702 	const char *full_path;
1703 	void *page;
1704 
1705 	tlink = cifs_sb_tlink(cifs_sb);
1706 	if (IS_ERR(tlink))
1707 		return ERR_CAST(tlink);
1708 	pTcon = tlink_tcon(tlink);
1709 
1710 	xid = get_xid();
1711 	page = alloc_dentry_path();
1712 
1713 	full_path = build_path_from_dentry(dentry, page);
1714 	if (IS_ERR(full_path)) {
1715 		acl = ERR_CAST(full_path);
1716 		goto out;
1717 	}
1718 
1719 	/* return alt name if available as pseudo attr */
1720 	switch (type) {
1721 	case ACL_TYPE_ACCESS:
1722 		if (sb->s_flags & SB_POSIXACL)
1723 			rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1724 					     ACL_TYPE_ACCESS,
1725 					     cifs_sb->local_nls,
1726 					     cifs_remap(cifs_sb));
1727 		break;
1728 
1729 	case ACL_TYPE_DEFAULT:
1730 		if (sb->s_flags & SB_POSIXACL)
1731 			rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1732 					     ACL_TYPE_DEFAULT,
1733 					     cifs_sb->local_nls,
1734 					     cifs_remap(cifs_sb));
1735 		break;
1736 	}
1737 
1738 	if (rc < 0) {
1739 		if (rc == -EINVAL)
1740 			acl = ERR_PTR(-EOPNOTSUPP);
1741 		else
1742 			acl = ERR_PTR(rc);
1743 	}
1744 
1745 out:
1746 	free_dentry_path(page);
1747 	free_xid(xid);
1748 	cifs_put_tlink(tlink);
1749 	return acl;
1750 #else
1751 	return ERR_PTR(-EOPNOTSUPP);
1752 #endif
1753 }
1754 
1755 int cifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
1756 		 struct posix_acl *acl, int type)
1757 {
1758 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1759 	int rc = -EOPNOTSUPP;
1760 	unsigned int xid;
1761 	struct super_block *sb = dentry->d_sb;
1762 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1763 	struct tcon_link *tlink;
1764 	struct cifs_tcon *pTcon;
1765 	const char *full_path;
1766 	void *page;
1767 
1768 	tlink = cifs_sb_tlink(cifs_sb);
1769 	if (IS_ERR(tlink))
1770 		return PTR_ERR(tlink);
1771 	pTcon = tlink_tcon(tlink);
1772 
1773 	xid = get_xid();
1774 	page = alloc_dentry_path();
1775 
1776 	full_path = build_path_from_dentry(dentry, page);
1777 	if (IS_ERR(full_path)) {
1778 		rc = PTR_ERR(full_path);
1779 		goto out;
1780 	}
1781 
1782 	if (!acl)
1783 		goto out;
1784 
1785 	/* return dos attributes as pseudo xattr */
1786 	/* return alt name if available as pseudo attr */
1787 
1788 	/* if proc/fs/cifs/streamstoxattr is set then
1789 		search server for EAs or streams to
1790 		returns as xattrs */
1791 	if (posix_acl_xattr_size(acl->a_count) > CIFSMaxBufSize) {
1792 		cifs_dbg(FYI, "size of EA value too large\n");
1793 		rc = -EOPNOTSUPP;
1794 		goto out;
1795 	}
1796 
1797 	switch (type) {
1798 	case ACL_TYPE_ACCESS:
1799 		if (sb->s_flags & SB_POSIXACL)
1800 			rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1801 					     ACL_TYPE_ACCESS,
1802 					     cifs_sb->local_nls,
1803 					     cifs_remap(cifs_sb));
1804 		break;
1805 
1806 	case ACL_TYPE_DEFAULT:
1807 		if (sb->s_flags & SB_POSIXACL)
1808 			rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1809 					     ACL_TYPE_DEFAULT,
1810 					     cifs_sb->local_nls,
1811 					     cifs_remap(cifs_sb));
1812 		break;
1813 	}
1814 
1815 out:
1816 	free_dentry_path(page);
1817 	free_xid(xid);
1818 	cifs_put_tlink(tlink);
1819 	return rc;
1820 #else
1821 	return -EOPNOTSUPP;
1822 #endif
1823 }
1824