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