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