xref: /linux/fs/smb/client/cifsacl.c (revision 42eb01783091e49020221a8a7d6c00e154ae7e58)
1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3  *
4  *   Copyright (C) International Business Machines  Corp., 2007,2008
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
7  *   Contains the routines for mapping CIFS/NTFS ACLs
8  *
9  */
10 
11 #include <linux/fs.h>
12 #include <linux/slab.h>
13 #include <linux/string.h>
14 #include <linux/keyctl.h>
15 #include <linux/key-type.h>
16 #include <uapi/linux/posix_acl.h>
17 #include <linux/posix_acl.h>
18 #include <linux/posix_acl_xattr.h>
19 #include <keys/user-type.h>
20 #include "cifsglob.h"
21 #include "cifsacl.h"
22 #include "cifsproto.h"
23 #include "cifs_debug.h"
24 #include "fs_context.h"
25 #include "cifs_fs_sb.h"
26 #include "cifs_unicode.h"
27 
28 /* security id for everyone/world system group */
29 static const struct smb_sid sid_everyone = {
30 	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
31 /* security id for Authenticated Users system group */
32 static const struct smb_sid sid_authusers = {
33 	1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
34 
35 /* S-1-22-1 Unmapped Unix users */
36 static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
37 		{cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
38 
39 /* S-1-22-2 Unmapped Unix groups */
40 static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
41 		{cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
42 
43 /*
44  * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
45  */
46 
47 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
48 
49 /* S-1-5-88-1 Unix uid */
50 static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
51 	{cpu_to_le32(88),
52 	 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
53 
54 /* S-1-5-88-2 Unix gid */
55 static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
56 	{cpu_to_le32(88),
57 	 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
58 
59 /* S-1-5-88-3 Unix mode */
60 static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
61 	{cpu_to_le32(88),
62 	 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
63 
64 static const struct cred *root_cred;
65 
66 static int
cifs_idmap_key_instantiate(struct key * key,struct key_preparsed_payload * prep)67 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
68 {
69 	char *payload;
70 
71 	/*
72 	 * If the payload is less than or equal to the size of a pointer, then
73 	 * an allocation here is wasteful. Just copy the data directly to the
74 	 * payload.value union member instead.
75 	 *
76 	 * With this however, you must check the datalen before trying to
77 	 * dereference payload.data!
78 	 */
79 	if (prep->datalen <= sizeof(key->payload)) {
80 		key->payload.data[0] = NULL;
81 		memcpy(&key->payload, prep->data, prep->datalen);
82 	} else {
83 		payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
84 		if (!payload)
85 			return -ENOMEM;
86 		key->payload.data[0] = payload;
87 	}
88 
89 	key->datalen = prep->datalen;
90 	return 0;
91 }
92 
93 static inline void
cifs_idmap_key_destroy(struct key * key)94 cifs_idmap_key_destroy(struct key *key)
95 {
96 	if (key->datalen > sizeof(key->payload))
97 		kfree(key->payload.data[0]);
98 }
99 
100 static struct key_type cifs_idmap_key_type = {
101 	.name        = "cifs.idmap",
102 	.instantiate = cifs_idmap_key_instantiate,
103 	.destroy     = cifs_idmap_key_destroy,
104 	.describe    = user_describe,
105 };
106 
107 static char *
sid_to_key_str(struct smb_sid * sidptr,unsigned int type)108 sid_to_key_str(struct smb_sid *sidptr, unsigned int type)
109 {
110 	int i, len;
111 	unsigned int saval;
112 	char *sidstr, *strptr;
113 	unsigned long long id_auth_val;
114 
115 	/* 3 bytes for prefix */
116 	sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
117 			 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
118 			 GFP_KERNEL);
119 	if (!sidstr)
120 		return sidstr;
121 
122 	strptr = sidstr;
123 	len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
124 			sidptr->revision);
125 	strptr += len;
126 
127 	/* The authority field is a single 48-bit number */
128 	id_auth_val = (unsigned long long)sidptr->authority[5];
129 	id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
130 	id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
131 	id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
132 	id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
133 	id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
134 
135 	/*
136 	 * MS-DTYP states that if the authority is >= 2^32, then it should be
137 	 * expressed as a hex value.
138 	 */
139 	if (id_auth_val <= UINT_MAX)
140 		len = sprintf(strptr, "-%llu", id_auth_val);
141 	else
142 		len = sprintf(strptr, "-0x%llx", id_auth_val);
143 
144 	strptr += len;
145 
146 	for (i = 0; i < sidptr->num_subauth; ++i) {
147 		saval = le32_to_cpu(sidptr->sub_auth[i]);
148 		len = sprintf(strptr, "-%u", saval);
149 		strptr += len;
150 	}
151 
152 	return sidstr;
153 }
154 
155 /*
156  * if the two SIDs (roughly equivalent to a UUID for a user or group) are
157  * the same returns zero, if they do not match returns non-zero.
158  */
159 static int
compare_sids(const struct smb_sid * ctsid,const struct smb_sid * cwsid)160 compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
161 {
162 	int i;
163 	int num_subauth, num_sat, num_saw;
164 
165 	if ((!ctsid) || (!cwsid))
166 		return 1;
167 
168 	/* compare the revision */
169 	if (ctsid->revision != cwsid->revision) {
170 		if (ctsid->revision > cwsid->revision)
171 			return 1;
172 		else
173 			return -1;
174 	}
175 
176 	/* compare all of the six auth values */
177 	for (i = 0; i < NUM_AUTHS; ++i) {
178 		if (ctsid->authority[i] != cwsid->authority[i]) {
179 			if (ctsid->authority[i] > cwsid->authority[i])
180 				return 1;
181 			else
182 				return -1;
183 		}
184 	}
185 
186 	/* compare all of the subauth values if any */
187 	num_sat = ctsid->num_subauth;
188 	num_saw = cwsid->num_subauth;
189 	num_subauth = min(num_sat, num_saw);
190 	if (num_subauth) {
191 		for (i = 0; i < num_subauth; ++i) {
192 			if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
193 				if (le32_to_cpu(ctsid->sub_auth[i]) >
194 					le32_to_cpu(cwsid->sub_auth[i]))
195 					return 1;
196 				else
197 					return -1;
198 			}
199 		}
200 	}
201 
202 	return 0; /* sids compare/match */
203 }
204 
205 static bool
is_well_known_sid(const struct smb_sid * psid,uint32_t * puid,bool is_group)206 is_well_known_sid(const struct smb_sid *psid, uint32_t *puid, bool is_group)
207 {
208 	int i;
209 	int num_subauth;
210 	const struct smb_sid *pwell_known_sid;
211 
212 	if (!psid || (puid == NULL))
213 		return false;
214 
215 	num_subauth = psid->num_subauth;
216 
217 	/* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
218 	if (num_subauth == 2) {
219 		if (is_group)
220 			pwell_known_sid = &sid_unix_groups;
221 		else
222 			pwell_known_sid = &sid_unix_users;
223 	} else if (num_subauth == 3) {
224 		if (is_group)
225 			pwell_known_sid = &sid_unix_NFS_groups;
226 		else
227 			pwell_known_sid = &sid_unix_NFS_users;
228 	} else
229 		return false;
230 
231 	/* compare the revision */
232 	if (psid->revision != pwell_known_sid->revision)
233 		return false;
234 
235 	/* compare all of the six auth values */
236 	for (i = 0; i < NUM_AUTHS; ++i) {
237 		if (psid->authority[i] != pwell_known_sid->authority[i]) {
238 			cifs_dbg(FYI, "auth %d did not match\n", i);
239 			return false;
240 		}
241 	}
242 
243 	if (num_subauth == 2) {
244 		if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
245 			return false;
246 
247 		*puid = le32_to_cpu(psid->sub_auth[1]);
248 	} else /* 3 subauths, ie Windows/Mac style */ {
249 		*puid = le32_to_cpu(psid->sub_auth[0]);
250 		if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
251 		    (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
252 			return false;
253 
254 		*puid = le32_to_cpu(psid->sub_auth[2]);
255 	}
256 
257 	cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
258 	return true; /* well known sid found, uid returned */
259 }
260 
261 static __u16
cifs_copy_sid(struct smb_sid * dst,const struct smb_sid * src)262 cifs_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
263 {
264 	int i;
265 	__u16 size = 1 + 1 + 6;
266 
267 	dst->revision = src->revision;
268 	dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
269 	for (i = 0; i < NUM_AUTHS; ++i)
270 		dst->authority[i] = src->authority[i];
271 	for (i = 0; i < dst->num_subauth; ++i)
272 		dst->sub_auth[i] = src->sub_auth[i];
273 	size += (dst->num_subauth * 4);
274 
275 	return size;
276 }
277 
278 static int
id_to_sid(unsigned int cid,uint sidtype,struct smb_sid * ssid)279 id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
280 {
281 	int rc;
282 	struct key *sidkey;
283 	struct smb_sid *ksid;
284 	unsigned int ksid_size;
285 	char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
286 	const struct cred *saved_cred;
287 
288 	rc = snprintf(desc, sizeof(desc), "%ci:%u",
289 			sidtype == SIDOWNER ? 'o' : 'g', cid);
290 	if (rc >= sizeof(desc))
291 		return -EINVAL;
292 
293 	rc = 0;
294 	saved_cred = override_creds(root_cred);
295 	sidkey = request_key(&cifs_idmap_key_type, desc, "");
296 	if (IS_ERR(sidkey)) {
297 		rc = -EINVAL;
298 		cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
299 			 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
300 		goto out_revert_creds;
301 	} else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
302 		rc = smb_EIO1(smb_eio_trace_malformed_sid_key, sidkey->datalen);
303 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
304 			 __func__, sidkey->datalen);
305 		goto invalidate_key;
306 	}
307 
308 	/*
309 	 * A sid is usually too large to be embedded in payload.value, but if
310 	 * there are no subauthorities and the host has 8-byte pointers, then
311 	 * it could be.
312 	 */
313 	ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
314 		(struct smb_sid *)&sidkey->payload :
315 		(struct smb_sid *)sidkey->payload.data[0];
316 
317 	ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
318 	if (ksid_size > sidkey->datalen) {
319 		rc = smb_EIO2(smb_eio_trace_malformed_ksid_key,
320 			      ksid_size, sidkey->datalen);
321 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
322 			 __func__, sidkey->datalen, ksid_size);
323 		goto invalidate_key;
324 	}
325 
326 	cifs_copy_sid(ssid, ksid);
327 out_key_put:
328 	key_put(sidkey);
329 out_revert_creds:
330 	revert_creds(saved_cred);
331 	return rc;
332 
333 invalidate_key:
334 	key_invalidate(sidkey);
335 	goto out_key_put;
336 }
337 
338 int
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 smb_EIO2(smb_eio_trace_sid_too_many_auth,
356 				psid->num_subauth, SID_MAX_SUB_AUTHORITIES);
357 	}
358 
359 	if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_UID_FROM_ACL) ||
360 	    (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
361 		uint32_t unix_id;
362 		bool is_group;
363 
364 		if (sidtype != SIDOWNER)
365 			is_group = true;
366 		else
367 			is_group = false;
368 
369 		if (is_well_known_sid(psid, &unix_id, is_group) == false)
370 			goto try_upcall_to_get_id;
371 
372 		if (is_group) {
373 			kgid_t gid;
374 			gid_t id;
375 
376 			id = (gid_t)unix_id;
377 			gid = make_kgid(&init_user_ns, id);
378 			if (gid_valid(gid)) {
379 				fgid = gid;
380 				goto got_valid_id;
381 			}
382 		} else {
383 			kuid_t uid;
384 			uid_t id;
385 
386 			id = (uid_t)unix_id;
387 			uid = make_kuid(&init_user_ns, id);
388 			if (uid_valid(uid)) {
389 				fuid = uid;
390 				goto got_valid_id;
391 			}
392 		}
393 		/* If unable to find uid/gid easily from SID try via upcall */
394 	}
395 
396 try_upcall_to_get_id:
397 	sidstr = sid_to_key_str(psid, sidtype);
398 	if (!sidstr)
399 		return -ENOMEM;
400 
401 	saved_cred = override_creds(root_cred);
402 	sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
403 	if (IS_ERR(sidkey)) {
404 		cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
405 			 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
406 		goto out_revert_creds;
407 	}
408 
409 	/*
410 	 * FIXME: Here we assume that uid_t and gid_t are same size. It's
411 	 * probably a safe assumption but might be better to check based on
412 	 * sidtype.
413 	 */
414 	BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
415 	if (sidkey->datalen != sizeof(uid_t)) {
416 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
417 			 __func__, sidkey->datalen);
418 		key_invalidate(sidkey);
419 		goto out_key_put;
420 	}
421 
422 	if (sidtype == SIDOWNER) {
423 		kuid_t uid;
424 		uid_t id;
425 		memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
426 		uid = make_kuid(&init_user_ns, id);
427 		if (uid_valid(uid))
428 			fuid = uid;
429 	} else {
430 		kgid_t gid;
431 		gid_t id;
432 		memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
433 		gid = make_kgid(&init_user_ns, id);
434 		if (gid_valid(gid))
435 			fgid = gid;
436 	}
437 
438 out_key_put:
439 	key_put(sidkey);
440 out_revert_creds:
441 	revert_creds(saved_cred);
442 	kfree(sidstr);
443 
444 	/*
445 	 * Note that we return 0 here unconditionally. If the mapping
446 	 * fails then we just fall back to using the ctx->linux_uid/linux_gid.
447 	 */
448 got_valid_id:
449 	if (sidtype == SIDOWNER)
450 		fattr->cf_uid = fuid;
451 	else
452 		fattr->cf_gid = fgid;
453 
454 	return 0;
455 }
456 
457 int
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_objs(struct smb_ace *, num_aces);
809 		if (!ppace)
810 			return;
811 
812 		for (i = 0; i < num_aces; ++i) {
813 			if (end_of_acl - acl_base < acl_size)
814 				break;
815 
816 			ppace[i] = (struct smb_ace *) (acl_base + acl_size);
817 			acl_base = (char *)ppace[i];
818 			acl_size = offsetof(struct smb_ace, sid) +
819 				offsetof(struct smb_sid, sub_auth);
820 
821 			if (end_of_acl - acl_base < acl_size ||
822 			    ppace[i]->sid.num_subauth == 0 ||
823 			    ppace[i]->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
824 			    (end_of_acl - acl_base <
825 			     acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) ||
826 			    (le16_to_cpu(ppace[i]->size) <
827 			     acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth))
828 				break;
829 
830 #ifdef CONFIG_CIFS_DEBUG2
831 			dump_ace(ppace[i], end_of_acl);
832 #endif
833 			if (mode_from_special_sid &&
834 			    (compare_sids(&(ppace[i]->sid),
835 					  &sid_unix_NFS_mode) == 0)) {
836 				/*
837 				 * Full permissions are:
838 				 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
839 				 *         S_IRWXU | S_IRWXG | S_IRWXO
840 				 */
841 				fattr->cf_mode &= ~07777;
842 				fattr->cf_mode |=
843 					le32_to_cpu(ppace[i]->sid.sub_auth[2]);
844 				break;
845 			} else {
846 				if (compare_sids(&(ppace[i]->sid), pownersid) == 0) {
847 					access_flags_to_mode(ppace[i]->access_req,
848 							ppace[i]->type,
849 							&fattr->cf_mode,
850 							&denied_mode,
851 							ACL_OWNER_MASK);
852 				} else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) {
853 					access_flags_to_mode(ppace[i]->access_req,
854 							ppace[i]->type,
855 							&fattr->cf_mode,
856 							&denied_mode,
857 							ACL_GROUP_MASK);
858 				} else if ((compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) ||
859 						(compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)) {
860 					access_flags_to_mode(ppace[i]->access_req,
861 							ppace[i]->type,
862 							&fattr->cf_mode,
863 							&denied_mode,
864 							ACL_EVERYONE_MASK);
865 				}
866 			}
867 
868 
869 /*			memcpy((void *)(&(cifscred->aces[i])),
870 				(void *)ppace[i],
871 				sizeof(struct smb_ace)); */
872 
873 			acl_size = le16_to_cpu(ppace[i]->size);
874 		}
875 
876 		kfree(ppace);
877 	}
878 
879 	return;
880 }
881 
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 smb_EIO(smb_eio_trace_null_pointers);
1231 
1232 	owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
1233 				le32_to_cpu(pntsd->osidoffset));
1234 	group_sid_ptr = (struct smb_sid *)((char *)pntsd +
1235 				le32_to_cpu(pntsd->gsidoffset));
1236 	dacloffset = le32_to_cpu(pntsd->dacloffset);
1237 	dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1238 	cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1239 		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1240 		 le32_to_cpu(pntsd->gsidoffset),
1241 		 le32_to_cpu(pntsd->sacloffset), dacloffset);
1242 /*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1243 	rc = parse_sid(owner_sid_ptr, end_of_acl);
1244 	if (rc) {
1245 		cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1246 		return rc;
1247 	}
1248 	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1249 	if (rc) {
1250 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1251 			 __func__, rc);
1252 		return rc;
1253 	}
1254 
1255 	rc = parse_sid(group_sid_ptr, end_of_acl);
1256 	if (rc) {
1257 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
1258 			 __func__, rc);
1259 		return rc;
1260 	}
1261 	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1262 	if (rc) {
1263 		cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1264 			 __func__, rc);
1265 		return rc;
1266 	}
1267 
1268 	if (dacloffset)
1269 		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1270 			   group_sid_ptr, fattr, get_mode_from_special_sid);
1271 	else
1272 		cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
1273 
1274 	return rc;
1275 }
1276 
1277 /* Convert permission bits from mode to equivalent CIFS ACL */
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_obj(struct smb_sid);
1335 			if (!nowner_sid_ptr) {
1336 				rc = -ENOMEM;
1337 				goto chown_chgrp_exit;
1338 			}
1339 			id = from_kuid(&init_user_ns, uid);
1340 			if (id_from_sid) {
1341 				struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1342 				/* Populate the user ownership fields S-1-5-88-1 */
1343 				osid->Revision = 1;
1344 				osid->NumAuth = 3;
1345 				osid->Authority[5] = 5;
1346 				osid->SubAuthorities[0] = cpu_to_le32(88);
1347 				osid->SubAuthorities[1] = cpu_to_le32(1);
1348 				osid->SubAuthorities[2] = cpu_to_le32(id);
1349 
1350 			} else { /* lookup sid with upcall */
1351 				rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1352 				if (rc) {
1353 					cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1354 						 __func__, rc, id);
1355 					goto chown_chgrp_exit;
1356 				}
1357 			}
1358 			*aclflag |= CIFS_ACL_OWNER;
1359 		}
1360 		if (gid_valid(gid)) { /* chgrp */
1361 			gid_t id;
1362 			ngroup_sid_ptr = kzalloc_obj(struct smb_sid);
1363 			if (!ngroup_sid_ptr) {
1364 				rc = -ENOMEM;
1365 				goto chown_chgrp_exit;
1366 			}
1367 			id = from_kgid(&init_user_ns, gid);
1368 			if (id_from_sid) {
1369 				struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1370 				/* Populate the group ownership fields S-1-5-88-2 */
1371 				gsid->Revision = 1;
1372 				gsid->NumAuth = 3;
1373 				gsid->Authority[5] = 5;
1374 				gsid->SubAuthorities[0] = cpu_to_le32(88);
1375 				gsid->SubAuthorities[1] = cpu_to_le32(2);
1376 				gsid->SubAuthorities[2] = cpu_to_le32(id);
1377 
1378 			} else { /* lookup sid with upcall */
1379 				rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1380 				if (rc) {
1381 					cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1382 						 __func__, rc, id);
1383 					goto chown_chgrp_exit;
1384 				}
1385 			}
1386 			*aclflag |= CIFS_ACL_GROUP;
1387 		}
1388 
1389 		if (dacloffset) {
1390 			/* Replace ACEs for old owner with new one */
1391 			size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1392 					owner_sid_ptr, group_sid_ptr,
1393 					nowner_sid_ptr, ngroup_sid_ptr);
1394 			ndacl_ptr->size = cpu_to_le16(size);
1395 		}
1396 
1397 		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1398 		/* copy the non-dacl portion of secdesc */
1399 		*pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1400 				nowner_sid_ptr, ngroup_sid_ptr);
1401 
1402 chown_chgrp_exit:
1403 		/* errors could jump here. So make sure we return soon after this */
1404 		kfree(nowner_sid_ptr);
1405 		kfree(ngroup_sid_ptr);
1406 	}
1407 
1408 	return rc;
1409 }
1410 
1411 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
get_cifs_acl_by_fid(struct cifs_sb_info * cifs_sb,const struct cifs_fid * cifsfid,u32 * pacllen,u32 info)1412 struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1413 				      const struct cifs_fid *cifsfid, u32 *pacllen,
1414 				      u32 info)
1415 {
1416 	struct smb_ntsd *pntsd = NULL;
1417 	unsigned int xid;
1418 	int rc;
1419 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1420 
1421 	if (IS_ERR(tlink))
1422 		return ERR_CAST(tlink);
1423 
1424 	xid = get_xid();
1425 	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1426 				pacllen, info);
1427 	free_xid(xid);
1428 
1429 	cifs_put_tlink(tlink);
1430 
1431 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1432 	if (rc)
1433 		return ERR_PTR(rc);
1434 	return pntsd;
1435 }
1436 
get_cifs_acl_by_path(struct cifs_sb_info * cifs_sb,const char * path,u32 * pacllen,u32 info)1437 static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1438 		const char *path, u32 *pacllen, u32 info)
1439 {
1440 	struct smb_ntsd *pntsd = NULL;
1441 	int oplock = 0;
1442 	unsigned int xid;
1443 	int rc;
1444 	struct cifs_tcon *tcon;
1445 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1446 	struct cifs_fid fid;
1447 	struct cifs_open_parms oparms;
1448 
1449 	if (IS_ERR(tlink))
1450 		return ERR_CAST(tlink);
1451 
1452 	tcon = tlink_tcon(tlink);
1453 	xid = get_xid();
1454 
1455 	oparms = (struct cifs_open_parms) {
1456 		.tcon = tcon,
1457 		.cifs_sb = cifs_sb,
1458 		.desired_access = READ_CONTROL,
1459 		.create_options = cifs_create_options(cifs_sb, 0),
1460 		.disposition = FILE_OPEN,
1461 		.path = path,
1462 		.fid = &fid,
1463 	};
1464 
1465 	if (info & SACL_SECINFO)
1466 		oparms.desired_access |= SYSTEM_SECURITY;
1467 
1468 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1469 	if (!rc) {
1470 		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen, info);
1471 		CIFSSMBClose(xid, tcon, fid.netfid);
1472 	}
1473 
1474 	cifs_put_tlink(tlink);
1475 	free_xid(xid);
1476 
1477 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1478 	if (rc)
1479 		return ERR_PTR(rc);
1480 	return pntsd;
1481 }
1482 
1483 /* Retrieve an ACL from the server */
get_cifs_acl(struct cifs_sb_info * cifs_sb,struct inode * inode,const char * path,u32 * pacllen,u32 info)1484 struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1485 				      struct inode *inode, const char *path,
1486 			       u32 *pacllen, u32 info)
1487 {
1488 	struct smb_ntsd *pntsd = NULL;
1489 	struct cifsFileInfo *open_file = NULL;
1490 
1491 	if (inode)
1492 		open_file = find_readable_file(CIFS_I(inode), true);
1493 	if (!open_file)
1494 		return get_cifs_acl_by_path(cifs_sb, path, pacllen, info);
1495 
1496 	pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1497 	cifsFileInfo_put(open_file);
1498 	return pntsd;
1499 }
1500 
1501  /* Set an ACL on the server */
set_cifs_acl(struct smb_ntsd * pnntsd,__u32 acllen,struct inode * inode,const char * path,int aclflag)1502 int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
1503 			struct inode *inode, const char *path, int aclflag)
1504 {
1505 	int oplock = 0;
1506 	unsigned int xid;
1507 	int rc, access_flags = 0;
1508 	struct cifs_tcon *tcon;
1509 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1510 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1511 	struct cifs_fid fid;
1512 	struct cifs_open_parms oparms;
1513 
1514 	if (IS_ERR(tlink))
1515 		return PTR_ERR(tlink);
1516 
1517 	tcon = tlink_tcon(tlink);
1518 	xid = get_xid();
1519 
1520 	if (aclflag & CIFS_ACL_OWNER || aclflag & CIFS_ACL_GROUP)
1521 		access_flags |= WRITE_OWNER;
1522 	if (aclflag & CIFS_ACL_SACL)
1523 		access_flags |= SYSTEM_SECURITY;
1524 	if (aclflag & CIFS_ACL_DACL)
1525 		access_flags |= WRITE_DAC;
1526 
1527 	oparms = (struct cifs_open_parms) {
1528 		.tcon = tcon,
1529 		.cifs_sb = cifs_sb,
1530 		.desired_access = access_flags,
1531 		.create_options = cifs_create_options(cifs_sb, 0),
1532 		.disposition = FILE_OPEN,
1533 		.path = path,
1534 		.fid = &fid,
1535 	};
1536 
1537 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1538 	if (rc) {
1539 		cifs_dbg(VFS, "Unable to open file to set ACL\n");
1540 		goto out;
1541 	}
1542 
1543 	rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1544 	cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1545 
1546 	CIFSSMBClose(xid, tcon, fid.netfid);
1547 out:
1548 	free_xid(xid);
1549 	cifs_put_tlink(tlink);
1550 	return rc;
1551 }
1552 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1553 
1554 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1555 int
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)1556 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1557 		  struct inode *inode, bool mode_from_special_sid,
1558 		  const char *path, const struct cifs_fid *pfid)
1559 {
1560 	struct smb_ntsd *pntsd = NULL;
1561 	u32 acllen = 0;
1562 	int rc = 0;
1563 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1564 	struct smb_version_operations *ops;
1565 	const u32 info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO;
1566 
1567 	cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1568 
1569 	if (IS_ERR(tlink))
1570 		return PTR_ERR(tlink);
1571 
1572 	ops = tlink_tcon(tlink)->ses->server->ops;
1573 
1574 	if (pfid && (ops->get_acl_by_fid))
1575 		pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1576 	else if (ops->get_acl)
1577 		pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1578 	else {
1579 		cifs_put_tlink(tlink);
1580 		return -EOPNOTSUPP;
1581 	}
1582 	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1583 	if (IS_ERR(pntsd)) {
1584 		rc = PTR_ERR(pntsd);
1585 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1586 	} else if (mode_from_special_sid) {
1587 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1588 		kfree(pntsd);
1589 	} else {
1590 		/* get approximated mode from ACL */
1591 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1592 		kfree(pntsd);
1593 		if (rc)
1594 			cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1595 	}
1596 
1597 	cifs_put_tlink(tlink);
1598 
1599 	return rc;
1600 }
1601 
1602 /* Convert mode bits to an ACL so we can update the ACL on the server */
1603 int
id_mode_to_cifs_acl(struct inode * inode,const char * path,__u64 * pnmode,kuid_t uid,kgid_t gid)1604 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1605 			kuid_t uid, kgid_t gid)
1606 {
1607 	int rc = 0;
1608 	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1609 	__u32 secdesclen = 0;
1610 	__u32 nsecdesclen = 0;
1611 	__u32 dacloffset = 0;
1612 	struct smb_acl *dacl_ptr = NULL;
1613 	struct smb_ntsd *pntsd = NULL; /* acl obtained from server */
1614 	struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1615 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
1616 	unsigned int sbflags;
1617 	struct tcon_link *tlink;
1618 	struct smb_version_operations *ops;
1619 	bool mode_from_sid, id_from_sid;
1620 	const u32 info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO;
1621 	bool posix;
1622 
1623 	tlink = cifs_sb_tlink(cifs_sb);
1624 	if (IS_ERR(tlink))
1625 		return PTR_ERR(tlink);
1626 	posix = tlink_tcon(tlink)->posix_extensions;
1627 
1628 	ops = tlink_tcon(tlink)->ses->server->ops;
1629 
1630 	cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1631 
1632 	/* Get the security descriptor */
1633 
1634 	if (ops->get_acl == NULL) {
1635 		cifs_put_tlink(tlink);
1636 		return -EOPNOTSUPP;
1637 	}
1638 
1639 	pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1640 	if (IS_ERR(pntsd)) {
1641 		rc = PTR_ERR(pntsd);
1642 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1643 		cifs_put_tlink(tlink);
1644 		return rc;
1645 	}
1646 
1647 	sbflags = cifs_sb_flags(cifs_sb);
1648 	mode_from_sid = sbflags & CIFS_MOUNT_MODE_FROM_SID;
1649 	id_from_sid = sbflags & CIFS_MOUNT_UID_FROM_ACL;
1650 
1651 	/* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1652 	if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1653 		if (posix)
1654 			nsecdesclen = 1 * sizeof(struct smb_ace);
1655 		else if (mode_from_sid)
1656 			nsecdesclen = secdesclen + (2 * sizeof(struct smb_ace));
1657 		else /* cifsacl */
1658 			nsecdesclen = secdesclen + (5 * sizeof(struct smb_ace));
1659 	} else { /* chown */
1660 		/* When ownership changes, changes new owner sid length could be different */
1661 		nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2);
1662 		dacloffset = le32_to_cpu(pntsd->dacloffset);
1663 		if (dacloffset) {
1664 			dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1665 			if (mode_from_sid)
1666 				nsecdesclen +=
1667 					le16_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
1668 			else /* cifsacl */
1669 				nsecdesclen += le16_to_cpu(dacl_ptr->size);
1670 		}
1671 	}
1672 
1673 	/*
1674 	 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1675 	 * as chmod disables ACEs and set the security descriptor. Allocate
1676 	 * memory for the smb header, set security descriptor request security
1677 	 * descriptor parameters, and security descriptor itself
1678 	 */
1679 	nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1680 	pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);
1681 	if (!pnntsd) {
1682 		kfree(pntsd);
1683 		cifs_put_tlink(tlink);
1684 		return -ENOMEM;
1685 	}
1686 
1687 	rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1688 			    mode_from_sid, id_from_sid, posix, &aclflag);
1689 
1690 	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1691 
1692 	if (ops->set_acl == NULL)
1693 		rc = -EOPNOTSUPP;
1694 
1695 	if (!rc) {
1696 		/* Set the security descriptor */
1697 		rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1698 		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1699 	}
1700 	cifs_put_tlink(tlink);
1701 
1702 	kfree(pnntsd);
1703 	kfree(pntsd);
1704 	return rc;
1705 }
1706 
cifs_get_acl(struct mnt_idmap * idmap,struct dentry * dentry,int type)1707 struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap,
1708 			       struct dentry *dentry, int type)
1709 {
1710 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1711 	struct posix_acl *acl = NULL;
1712 	ssize_t rc = -EOPNOTSUPP;
1713 	unsigned int xid;
1714 	struct super_block *sb = dentry->d_sb;
1715 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1716 	struct tcon_link *tlink;
1717 	struct cifs_tcon *pTcon;
1718 	const char *full_path;
1719 	void *page;
1720 
1721 	tlink = cifs_sb_tlink(cifs_sb);
1722 	if (IS_ERR(tlink))
1723 		return ERR_CAST(tlink);
1724 	pTcon = tlink_tcon(tlink);
1725 
1726 	xid = get_xid();
1727 	page = alloc_dentry_path();
1728 
1729 	full_path = build_path_from_dentry(dentry, page);
1730 	if (IS_ERR(full_path)) {
1731 		acl = ERR_CAST(full_path);
1732 		goto out;
1733 	}
1734 
1735 	/* return alt name if available as pseudo attr */
1736 	switch (type) {
1737 	case ACL_TYPE_ACCESS:
1738 		if (sb->s_flags & SB_POSIXACL)
1739 			rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1740 					     ACL_TYPE_ACCESS,
1741 					     cifs_sb->local_nls,
1742 					     cifs_remap(cifs_sb));
1743 		break;
1744 
1745 	case ACL_TYPE_DEFAULT:
1746 		if (sb->s_flags & SB_POSIXACL)
1747 			rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1748 					     ACL_TYPE_DEFAULT,
1749 					     cifs_sb->local_nls,
1750 					     cifs_remap(cifs_sb));
1751 		break;
1752 	}
1753 
1754 	if (rc < 0) {
1755 		if (rc == -EINVAL)
1756 			acl = ERR_PTR(-EOPNOTSUPP);
1757 		else
1758 			acl = ERR_PTR(rc);
1759 	}
1760 
1761 out:
1762 	free_dentry_path(page);
1763 	free_xid(xid);
1764 	cifs_put_tlink(tlink);
1765 	return acl;
1766 #else
1767 	return ERR_PTR(-EOPNOTSUPP);
1768 #endif
1769 }
1770 
cifs_set_acl(struct mnt_idmap * idmap,struct dentry * dentry,struct posix_acl * acl,int type)1771 int cifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
1772 		 struct posix_acl *acl, int type)
1773 {
1774 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1775 	int rc = -EOPNOTSUPP;
1776 	unsigned int xid;
1777 	struct super_block *sb = dentry->d_sb;
1778 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1779 	struct tcon_link *tlink;
1780 	struct cifs_tcon *pTcon;
1781 	const char *full_path;
1782 	void *page;
1783 
1784 	tlink = cifs_sb_tlink(cifs_sb);
1785 	if (IS_ERR(tlink))
1786 		return PTR_ERR(tlink);
1787 	pTcon = tlink_tcon(tlink);
1788 
1789 	xid = get_xid();
1790 	page = alloc_dentry_path();
1791 
1792 	full_path = build_path_from_dentry(dentry, page);
1793 	if (IS_ERR(full_path)) {
1794 		rc = PTR_ERR(full_path);
1795 		goto out;
1796 	}
1797 
1798 	if (!acl)
1799 		goto out;
1800 
1801 	/* return dos attributes as pseudo xattr */
1802 	/* return alt name if available as pseudo attr */
1803 
1804 	/* if proc/fs/cifs/streamstoxattr is set then
1805 		search server for EAs or streams to
1806 		returns as xattrs */
1807 	if (posix_acl_xattr_size(acl->a_count) > CIFSMaxBufSize) {
1808 		cifs_dbg(FYI, "size of EA value too large\n");
1809 		rc = -EOPNOTSUPP;
1810 		goto out;
1811 	}
1812 
1813 	switch (type) {
1814 	case ACL_TYPE_ACCESS:
1815 		if (sb->s_flags & SB_POSIXACL)
1816 			rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1817 					     ACL_TYPE_ACCESS,
1818 					     cifs_sb->local_nls,
1819 					     cifs_remap(cifs_sb));
1820 		break;
1821 
1822 	case ACL_TYPE_DEFAULT:
1823 		if (sb->s_flags & SB_POSIXACL)
1824 			rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1825 					     ACL_TYPE_DEFAULT,
1826 					     cifs_sb->local_nls,
1827 					     cifs_remap(cifs_sb));
1828 		break;
1829 	}
1830 
1831 out:
1832 	free_dentry_path(page);
1833 	free_xid(xid);
1834 	cifs_put_tlink(tlink);
1835 	return rc;
1836 #else
1837 	return -EOPNOTSUPP;
1838 #endif
1839 }
1840