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