• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 cifs_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 cifs_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 cifs_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 cifs_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 cifs_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 cifs_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 cifs_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 cifs_sid * sidptr,unsigned int type)109 sid_to_key_str(struct cifs_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 cifs_sid * ctsid,const struct cifs_sid * cwsid)161 compare_sids(const struct cifs_sid *ctsid, const struct cifs_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 = num_sat < num_saw ? 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 cifs_sid * psid,uint32_t * puid,bool is_group)207 is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
208 {
209 	int i;
210 	int num_subauth;
211 	const struct cifs_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 cifs_sid * dst,const struct cifs_sid * src)263 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_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 cifs_sid * ssid)280 id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
281 {
282 	int rc;
283 	struct key *sidkey;
284 	struct cifs_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 cifs_sid *)&sidkey->payload :
316 		(struct cifs_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 cifs_sid * psid,struct cifs_fattr * fattr,uint sidtype)339 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_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 cifs_ntsd * pntsd,struct cifs_ntsd * pnntsd,__u32 sidsoffset,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid)518 static __u32 copy_sec_desc(const struct cifs_ntsd *pntsd,
519 				struct cifs_ntsd *pnntsd,
520 				__u32 sidsoffset,
521 				struct cifs_sid *pownersid,
522 				struct cifs_sid *pgrpsid)
523 {
524 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
525 	struct cifs_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 cifs_ntsd));
531 	pnntsd->sacloffset = 0;
532 	pnntsd->osidoffset = cpu_to_le32(sidsoffset);
533 	pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
534 
535 	/* copy owner sid */
536 	if (pownersid)
537 		owner_sid_ptr = pownersid;
538 	else
539 		owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
540 				le32_to_cpu(pntsd->osidoffset));
541 	nowner_sid_ptr = (struct cifs_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 cifs_sid *)((char *)pntsd +
549 				le32_to_cpu(pntsd->gsidoffset));
550 	ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
551 					sizeof(struct cifs_sid));
552 	cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
553 
554 	return sidsoffset + (2 * sizeof(struct cifs_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 cifs_ace * dst,struct cifs_ace * src,struct cifs_sid * psid)669 static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct cifs_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 cifs_ace * pntace,const struct cifs_sid * psid,__u64 nmode,umode_t bits,__u8 access_type,bool allow_delete_child)688 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
689 			const struct cifs_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 cifs_ace * pace,char * end_of_acl)726 static void dump_ace(struct cifs_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 cifs_acl * pdacl,char * end_of_acl,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,struct cifs_fattr * fattr,bool mode_from_special_sid)761 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
762 		       struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
763 		       struct cifs_fattr *fattr, bool mode_from_special_sid)
764 {
765 	int i;
766 	int num_aces = 0;
767 	int acl_size;
768 	char *acl_base;
769 	struct cifs_ace **ppace;
770 
771 	/* BB need to add parm so we can store the SID BB */
772 
773 	if (!pdacl) {
774 		/* no DACL in the security descriptor, set
775 		   all the permissions for user/group/other */
776 		fattr->cf_mode |= 0777;
777 		return;
778 	}
779 
780 	/* validate that we do not go past end of acl */
781 	if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
782 		cifs_dbg(VFS, "ACL too small to parse DACL\n");
783 		return;
784 	}
785 
786 	cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
787 		 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
788 		 le32_to_cpu(pdacl->num_aces));
789 
790 	/* reset rwx permissions for user/group/other.
791 	   Also, if num_aces is 0 i.e. DACL has no ACEs,
792 	   user/group/other have no permissions */
793 	fattr->cf_mode &= ~(0777);
794 
795 	acl_base = (char *)pdacl;
796 	acl_size = sizeof(struct cifs_acl);
797 
798 	num_aces = le32_to_cpu(pdacl->num_aces);
799 	if (num_aces > 0) {
800 		umode_t denied_mode = 0;
801 
802 		if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
803 			return;
804 		ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
805 				      GFP_KERNEL);
806 		if (!ppace)
807 			return;
808 
809 		for (i = 0; i < num_aces; ++i) {
810 			ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
811 #ifdef CONFIG_CIFS_DEBUG2
812 			dump_ace(ppace[i], end_of_acl);
813 #endif
814 			if (mode_from_special_sid &&
815 			    (compare_sids(&(ppace[i]->sid),
816 					  &sid_unix_NFS_mode) == 0)) {
817 				/*
818 				 * Full permissions are:
819 				 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
820 				 *         S_IRWXU | S_IRWXG | S_IRWXO
821 				 */
822 				fattr->cf_mode &= ~07777;
823 				fattr->cf_mode |=
824 					le32_to_cpu(ppace[i]->sid.sub_auth[2]);
825 				break;
826 			} else {
827 				if (compare_sids(&(ppace[i]->sid), pownersid) == 0) {
828 					access_flags_to_mode(ppace[i]->access_req,
829 							ppace[i]->type,
830 							&fattr->cf_mode,
831 							&denied_mode,
832 							ACL_OWNER_MASK);
833 				} else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) {
834 					access_flags_to_mode(ppace[i]->access_req,
835 							ppace[i]->type,
836 							&fattr->cf_mode,
837 							&denied_mode,
838 							ACL_GROUP_MASK);
839 				} else if ((compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) ||
840 						(compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)) {
841 					access_flags_to_mode(ppace[i]->access_req,
842 							ppace[i]->type,
843 							&fattr->cf_mode,
844 							&denied_mode,
845 							ACL_EVERYONE_MASK);
846 				}
847 			}
848 
849 
850 /*			memcpy((void *)(&(cifscred->aces[i])),
851 				(void *)ppace[i],
852 				sizeof(struct cifs_ace)); */
853 
854 			acl_base = (char *)ppace[i];
855 			acl_size = le16_to_cpu(ppace[i]->size);
856 		}
857 
858 		kfree(ppace);
859 	}
860 
861 	return;
862 }
863 
setup_authusers_ACE(struct cifs_ace * pntace)864 unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
865 {
866 	int i;
867 	unsigned int ace_size = 20;
868 
869 	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
870 	pntace->flags = 0x0;
871 	pntace->access_req = cpu_to_le32(GENERIC_ALL);
872 	pntace->sid.num_subauth = 1;
873 	pntace->sid.revision = 1;
874 	for (i = 0; i < NUM_AUTHS; i++)
875 		pntace->sid.authority[i] =  sid_authusers.authority[i];
876 
877 	pntace->sid.sub_auth[0] =  sid_authusers.sub_auth[0];
878 
879 	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
880 	pntace->size = cpu_to_le16(ace_size);
881 	return ace_size;
882 }
883 
884 /*
885  * Fill in the special SID based on the mode. See
886  * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
887  */
setup_special_mode_ACE(struct cifs_ace * pntace,__u64 nmode)888 unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
889 {
890 	int i;
891 	unsigned int ace_size = 28;
892 
893 	pntace->type = ACCESS_DENIED_ACE_TYPE;
894 	pntace->flags = 0x0;
895 	pntace->access_req = 0;
896 	pntace->sid.num_subauth = 3;
897 	pntace->sid.revision = 1;
898 	for (i = 0; i < NUM_AUTHS; i++)
899 		pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
900 
901 	pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
902 	pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
903 	pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
904 
905 	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
906 	pntace->size = cpu_to_le16(ace_size);
907 	return ace_size;
908 }
909 
setup_special_user_owner_ACE(struct cifs_ace * pntace)910 unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
911 {
912 	int i;
913 	unsigned int ace_size = 28;
914 
915 	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
916 	pntace->flags = 0x0;
917 	pntace->access_req = cpu_to_le32(GENERIC_ALL);
918 	pntace->sid.num_subauth = 3;
919 	pntace->sid.revision = 1;
920 	for (i = 0; i < NUM_AUTHS; i++)
921 		pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
922 
923 	pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
924 	pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
925 	pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
926 
927 	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
928 	pntace->size = cpu_to_le16(ace_size);
929 	return ace_size;
930 }
931 
populate_new_aces(char * nacl_base,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,__u64 * pnmode,u32 * pnum_aces,u16 * pnsize,bool modefromsid)932 static void populate_new_aces(char *nacl_base,
933 		struct cifs_sid *pownersid,
934 		struct cifs_sid *pgrpsid,
935 		__u64 *pnmode, u32 *pnum_aces, u16 *pnsize,
936 		bool modefromsid)
937 {
938 	__u64 nmode;
939 	u32 num_aces = 0;
940 	u16 nsize = 0;
941 	__u64 user_mode;
942 	__u64 group_mode;
943 	__u64 other_mode;
944 	__u64 deny_user_mode = 0;
945 	__u64 deny_group_mode = 0;
946 	bool sticky_set = false;
947 	struct cifs_ace *pnntace = NULL;
948 
949 	nmode = *pnmode;
950 	num_aces = *pnum_aces;
951 	nsize = *pnsize;
952 
953 	if (modefromsid) {
954 		pnntace = (struct cifs_ace *) (nacl_base + nsize);
955 		nsize += setup_special_mode_ACE(pnntace, nmode);
956 		num_aces++;
957 		pnntace = (struct cifs_ace *) (nacl_base + nsize);
958 		nsize += setup_authusers_ACE(pnntace);
959 		num_aces++;
960 		goto set_size;
961 	}
962 
963 	/*
964 	 * We'll try to keep the mode as requested by the user.
965 	 * But in cases where we cannot meaningfully convert that
966 	 * into ACL, return back the updated mode, so that it is
967 	 * updated in the inode.
968 	 */
969 
970 	if (!memcmp(pownersid, pgrpsid, sizeof(struct cifs_sid))) {
971 		/*
972 		 * Case when owner and group SIDs are the same.
973 		 * Set the more restrictive of the two modes.
974 		 */
975 		user_mode = nmode & (nmode << 3) & 0700;
976 		group_mode = nmode & (nmode >> 3) & 0070;
977 	} else {
978 		user_mode = nmode & 0700;
979 		group_mode = nmode & 0070;
980 	}
981 
982 	other_mode = nmode & 0007;
983 
984 	/* We need DENY ACE when the perm is more restrictive than the next sets. */
985 	deny_user_mode = ~(user_mode) & ((group_mode << 3) | (other_mode << 6)) & 0700;
986 	deny_group_mode = ~(group_mode) & (other_mode << 3) & 0070;
987 
988 	*pnmode = user_mode | group_mode | other_mode | (nmode & ~0777);
989 
990 	/* This tells if we should allow delete child for group and everyone. */
991 	if (nmode & 01000)
992 		sticky_set = true;
993 
994 	if (deny_user_mode) {
995 		pnntace = (struct cifs_ace *) (nacl_base + nsize);
996 		nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode,
997 				0700, ACCESS_DENIED, false);
998 		num_aces++;
999 	}
1000 
1001 	/* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/
1002 	if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) {
1003 		pnntace = (struct cifs_ace *) (nacl_base + nsize);
1004 		nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1005 				0070, ACCESS_DENIED, false);
1006 		num_aces++;
1007 	}
1008 
1009 	pnntace = (struct cifs_ace *) (nacl_base + nsize);
1010 	nsize += fill_ace_for_sid(pnntace, pownersid, user_mode,
1011 			0700, ACCESS_ALLOWED, true);
1012 	num_aces++;
1013 
1014 	/* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */
1015 	if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) {
1016 		pnntace = (struct cifs_ace *) (nacl_base + nsize);
1017 		nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1018 				0070, ACCESS_DENIED, false);
1019 		num_aces++;
1020 	}
1021 
1022 	pnntace = (struct cifs_ace *) (nacl_base + nsize);
1023 	nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode,
1024 			0070, ACCESS_ALLOWED, !sticky_set);
1025 	num_aces++;
1026 
1027 	pnntace = (struct cifs_ace *) (nacl_base + nsize);
1028 	nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode,
1029 			0007, ACCESS_ALLOWED, !sticky_set);
1030 	num_aces++;
1031 
1032 set_size:
1033 	*pnum_aces = num_aces;
1034 	*pnsize = nsize;
1035 }
1036 
replace_sids_and_copy_aces(struct cifs_acl * pdacl,struct cifs_acl * pndacl,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,struct cifs_sid * pnownersid,struct cifs_sid * pngrpsid)1037 static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
1038 		struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
1039 		struct cifs_sid *pnownersid, struct cifs_sid *pngrpsid)
1040 {
1041 	int i;
1042 	u16 size = 0;
1043 	struct cifs_ace *pntace = NULL;
1044 	char *acl_base = NULL;
1045 	u32 src_num_aces = 0;
1046 	u16 nsize = 0;
1047 	struct cifs_ace *pnntace = NULL;
1048 	char *nacl_base = NULL;
1049 	u16 ace_size = 0;
1050 
1051 	acl_base = (char *)pdacl;
1052 	size = sizeof(struct cifs_acl);
1053 	src_num_aces = le32_to_cpu(pdacl->num_aces);
1054 
1055 	nacl_base = (char *)pndacl;
1056 	nsize = sizeof(struct cifs_acl);
1057 
1058 	/* Go through all the ACEs */
1059 	for (i = 0; i < src_num_aces; ++i) {
1060 		pntace = (struct cifs_ace *) (acl_base + size);
1061 		pnntace = (struct cifs_ace *) (nacl_base + nsize);
1062 
1063 		if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0)
1064 			ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
1065 		else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0)
1066 			ace_size = cifs_copy_ace(pnntace, pntace, pngrpsid);
1067 		else
1068 			ace_size = cifs_copy_ace(pnntace, pntace, NULL);
1069 
1070 		size += le16_to_cpu(pntace->size);
1071 		nsize += ace_size;
1072 	}
1073 
1074 	return nsize;
1075 }
1076 
set_chmod_dacl(struct cifs_acl * pdacl,struct cifs_acl * pndacl,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,__u64 * pnmode,bool mode_from_sid)1077 static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
1078 		struct cifs_sid *pownersid,	struct cifs_sid *pgrpsid,
1079 		__u64 *pnmode, bool mode_from_sid)
1080 {
1081 	int i;
1082 	u16 size = 0;
1083 	struct cifs_ace *pntace = NULL;
1084 	char *acl_base = NULL;
1085 	u32 src_num_aces = 0;
1086 	u16 nsize = 0;
1087 	struct cifs_ace *pnntace = NULL;
1088 	char *nacl_base = NULL;
1089 	u32 num_aces = 0;
1090 	bool new_aces_set = false;
1091 
1092 	/* Assuming that pndacl and pnmode are never NULL */
1093 	nacl_base = (char *)pndacl;
1094 	nsize = sizeof(struct cifs_acl);
1095 
1096 	/* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
1097 	if (!pdacl) {
1098 		populate_new_aces(nacl_base,
1099 				pownersid, pgrpsid,
1100 				pnmode, &num_aces, &nsize,
1101 				mode_from_sid);
1102 		goto finalize_dacl;
1103 	}
1104 
1105 	acl_base = (char *)pdacl;
1106 	size = sizeof(struct cifs_acl);
1107 	src_num_aces = le32_to_cpu(pdacl->num_aces);
1108 
1109 	/* Retain old ACEs which we can retain */
1110 	for (i = 0; i < src_num_aces; ++i) {
1111 		pntace = (struct cifs_ace *) (acl_base + size);
1112 
1113 		if (!new_aces_set && (pntace->flags & INHERITED_ACE)) {
1114 			/* Place the new ACEs in between existing explicit and inherited */
1115 			populate_new_aces(nacl_base,
1116 					pownersid, pgrpsid,
1117 					pnmode, &num_aces, &nsize,
1118 					mode_from_sid);
1119 
1120 			new_aces_set = true;
1121 		}
1122 
1123 		/* If it's any one of the ACE we're replacing, skip! */
1124 		if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
1125 				(compare_sids(&pntace->sid, pownersid) == 0) ||
1126 				(compare_sids(&pntace->sid, pgrpsid) == 0) ||
1127 				(compare_sids(&pntace->sid, &sid_everyone) == 0) ||
1128 				(compare_sids(&pntace->sid, &sid_authusers) == 0))) {
1129 			goto next_ace;
1130 		}
1131 
1132 		/* update the pointer to the next ACE to populate*/
1133 		pnntace = (struct cifs_ace *) (nacl_base + nsize);
1134 
1135 		nsize += cifs_copy_ace(pnntace, pntace, NULL);
1136 		num_aces++;
1137 
1138 next_ace:
1139 		size += le16_to_cpu(pntace->size);
1140 	}
1141 
1142 	/* If inherited ACEs are not present, place the new ones at the tail */
1143 	if (!new_aces_set) {
1144 		populate_new_aces(nacl_base,
1145 				pownersid, pgrpsid,
1146 				pnmode, &num_aces, &nsize,
1147 				mode_from_sid);
1148 
1149 		new_aces_set = true;
1150 	}
1151 
1152 finalize_dacl:
1153 	pndacl->num_aces = cpu_to_le32(num_aces);
1154 	pndacl->size = cpu_to_le16(nsize);
1155 
1156 	return 0;
1157 }
1158 
parse_sid(struct cifs_sid * psid,char * end_of_acl)1159 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
1160 {
1161 	/* BB need to add parm so we can store the SID BB */
1162 
1163 	/* validate that we do not go past end of ACL - sid must be at least 8
1164 	   bytes long (assuming no sub-auths - e.g. the null SID */
1165 	if (end_of_acl < (char *)psid + 8) {
1166 		cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
1167 		return -EINVAL;
1168 	}
1169 
1170 #ifdef CONFIG_CIFS_DEBUG2
1171 	if (psid->num_subauth) {
1172 		int i;
1173 		cifs_dbg(FYI, "SID revision %d num_auth %d\n",
1174 			 psid->revision, psid->num_subauth);
1175 
1176 		for (i = 0; i < psid->num_subauth; i++) {
1177 			cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
1178 				 i, le32_to_cpu(psid->sub_auth[i]));
1179 		}
1180 
1181 		/* BB add length check to make sure that we do not have huge
1182 			num auths and therefore go off the end */
1183 		cifs_dbg(FYI, "RID 0x%x\n",
1184 			 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1185 	}
1186 #endif
1187 
1188 	return 0;
1189 }
1190 
1191 
1192 /* Convert CIFS ACL to POSIX form */
parse_sec_desc(struct cifs_sb_info * cifs_sb,struct cifs_ntsd * pntsd,int acl_len,struct cifs_fattr * fattr,bool get_mode_from_special_sid)1193 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1194 		struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
1195 		bool get_mode_from_special_sid)
1196 {
1197 	int rc = 0;
1198 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1199 	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
1200 	char *end_of_acl = ((char *)pntsd) + acl_len;
1201 	__u32 dacloffset;
1202 
1203 	if (pntsd == NULL)
1204 		return -EIO;
1205 
1206 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1207 				le32_to_cpu(pntsd->osidoffset));
1208 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1209 				le32_to_cpu(pntsd->gsidoffset));
1210 	dacloffset = le32_to_cpu(pntsd->dacloffset);
1211 	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1212 	cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1213 		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1214 		 le32_to_cpu(pntsd->gsidoffset),
1215 		 le32_to_cpu(pntsd->sacloffset), dacloffset);
1216 /*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1217 	rc = parse_sid(owner_sid_ptr, end_of_acl);
1218 	if (rc) {
1219 		cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1220 		return rc;
1221 	}
1222 	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1223 	if (rc) {
1224 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1225 			 __func__, rc);
1226 		return rc;
1227 	}
1228 
1229 	rc = parse_sid(group_sid_ptr, end_of_acl);
1230 	if (rc) {
1231 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
1232 			 __func__, rc);
1233 		return rc;
1234 	}
1235 	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1236 	if (rc) {
1237 		cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1238 			 __func__, rc);
1239 		return rc;
1240 	}
1241 
1242 	if (dacloffset)
1243 		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1244 			   group_sid_ptr, fattr, get_mode_from_special_sid);
1245 	else
1246 		cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
1247 
1248 	return rc;
1249 }
1250 
1251 /* Convert permission bits from mode to equivalent CIFS ACL */
build_sec_desc(struct cifs_ntsd * pntsd,struct cifs_ntsd * pnntsd,__u32 secdesclen,__u32 * pnsecdesclen,__u64 * pnmode,kuid_t uid,kgid_t gid,bool mode_from_sid,bool id_from_sid,int * aclflag)1252 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1253 	__u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
1254 	bool mode_from_sid, bool id_from_sid, int *aclflag)
1255 {
1256 	int rc = 0;
1257 	__u32 dacloffset;
1258 	__u32 ndacloffset;
1259 	__u32 sidsoffset;
1260 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1261 	struct cifs_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
1262 	struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
1263 	struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1264 	char *end_of_acl = ((char *)pntsd) + secdesclen;
1265 	u16 size = 0;
1266 
1267 	dacloffset = le32_to_cpu(pntsd->dacloffset);
1268 	if (dacloffset) {
1269 		dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1270 		if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) {
1271 			cifs_dbg(VFS, "Server returned illegal ACL size\n");
1272 			return -EINVAL;
1273 		}
1274 	}
1275 
1276 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1277 			le32_to_cpu(pntsd->osidoffset));
1278 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1279 			le32_to_cpu(pntsd->gsidoffset));
1280 
1281 	if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1282 		ndacloffset = sizeof(struct cifs_ntsd);
1283 		ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1284 		ndacl_ptr->revision =
1285 			dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1286 
1287 		ndacl_ptr->size = cpu_to_le16(0);
1288 		ndacl_ptr->num_aces = cpu_to_le32(0);
1289 
1290 		rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1291 				    pnmode, mode_from_sid);
1292 
1293 		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1294 		/* copy the non-dacl portion of secdesc */
1295 		*pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1296 				NULL, NULL);
1297 
1298 		*aclflag |= CIFS_ACL_DACL;
1299 	} else {
1300 		ndacloffset = sizeof(struct cifs_ntsd);
1301 		ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1302 		ndacl_ptr->revision =
1303 			dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1304 		ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0;
1305 
1306 		if (uid_valid(uid)) { /* chown */
1307 			uid_t id;
1308 			nowner_sid_ptr = kzalloc(sizeof(struct cifs_sid),
1309 								GFP_KERNEL);
1310 			if (!nowner_sid_ptr) {
1311 				rc = -ENOMEM;
1312 				goto chown_chgrp_exit;
1313 			}
1314 			id = from_kuid(&init_user_ns, uid);
1315 			if (id_from_sid) {
1316 				struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1317 				/* Populate the user ownership fields S-1-5-88-1 */
1318 				osid->Revision = 1;
1319 				osid->NumAuth = 3;
1320 				osid->Authority[5] = 5;
1321 				osid->SubAuthorities[0] = cpu_to_le32(88);
1322 				osid->SubAuthorities[1] = cpu_to_le32(1);
1323 				osid->SubAuthorities[2] = cpu_to_le32(id);
1324 
1325 			} else { /* lookup sid with upcall */
1326 				rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1327 				if (rc) {
1328 					cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1329 						 __func__, rc, id);
1330 					goto chown_chgrp_exit;
1331 				}
1332 			}
1333 			*aclflag |= CIFS_ACL_OWNER;
1334 		}
1335 		if (gid_valid(gid)) { /* chgrp */
1336 			gid_t id;
1337 			ngroup_sid_ptr = kzalloc(sizeof(struct cifs_sid),
1338 								GFP_KERNEL);
1339 			if (!ngroup_sid_ptr) {
1340 				rc = -ENOMEM;
1341 				goto chown_chgrp_exit;
1342 			}
1343 			id = from_kgid(&init_user_ns, gid);
1344 			if (id_from_sid) {
1345 				struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1346 				/* Populate the group ownership fields S-1-5-88-2 */
1347 				gsid->Revision = 1;
1348 				gsid->NumAuth = 3;
1349 				gsid->Authority[5] = 5;
1350 				gsid->SubAuthorities[0] = cpu_to_le32(88);
1351 				gsid->SubAuthorities[1] = cpu_to_le32(2);
1352 				gsid->SubAuthorities[2] = cpu_to_le32(id);
1353 
1354 			} else { /* lookup sid with upcall */
1355 				rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1356 				if (rc) {
1357 					cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1358 						 __func__, rc, id);
1359 					goto chown_chgrp_exit;
1360 				}
1361 			}
1362 			*aclflag |= CIFS_ACL_GROUP;
1363 		}
1364 
1365 		if (dacloffset) {
1366 			/* Replace ACEs for old owner with new one */
1367 			size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1368 					owner_sid_ptr, group_sid_ptr,
1369 					nowner_sid_ptr, ngroup_sid_ptr);
1370 			ndacl_ptr->size = cpu_to_le16(size);
1371 		}
1372 
1373 		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1374 		/* copy the non-dacl portion of secdesc */
1375 		*pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1376 				nowner_sid_ptr, ngroup_sid_ptr);
1377 
1378 chown_chgrp_exit:
1379 		/* errors could jump here. So make sure we return soon after this */
1380 		kfree(nowner_sid_ptr);
1381 		kfree(ngroup_sid_ptr);
1382 	}
1383 
1384 	return rc;
1385 }
1386 
1387 #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 __maybe_unused unused)1388 struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1389 				      const struct cifs_fid *cifsfid, u32 *pacllen,
1390 				      u32 __maybe_unused unused)
1391 {
1392 	struct cifs_ntsd *pntsd = NULL;
1393 	unsigned int xid;
1394 	int rc;
1395 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1396 
1397 	if (IS_ERR(tlink))
1398 		return ERR_CAST(tlink);
1399 
1400 	xid = get_xid();
1401 	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1402 				pacllen);
1403 	free_xid(xid);
1404 
1405 	cifs_put_tlink(tlink);
1406 
1407 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1408 	if (rc)
1409 		return ERR_PTR(rc);
1410 	return pntsd;
1411 }
1412 
get_cifs_acl_by_path(struct cifs_sb_info * cifs_sb,const char * path,u32 * pacllen)1413 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1414 		const char *path, u32 *pacllen)
1415 {
1416 	struct cifs_ntsd *pntsd = NULL;
1417 	int oplock = 0;
1418 	unsigned int xid;
1419 	int rc;
1420 	struct cifs_tcon *tcon;
1421 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1422 	struct cifs_fid fid;
1423 	struct cifs_open_parms oparms;
1424 
1425 	if (IS_ERR(tlink))
1426 		return ERR_CAST(tlink);
1427 
1428 	tcon = tlink_tcon(tlink);
1429 	xid = get_xid();
1430 
1431 	oparms = (struct cifs_open_parms) {
1432 		.tcon = tcon,
1433 		.cifs_sb = cifs_sb,
1434 		.desired_access = READ_CONTROL,
1435 		.create_options = cifs_create_options(cifs_sb, 0),
1436 		.disposition = FILE_OPEN,
1437 		.path = path,
1438 		.fid = &fid,
1439 	};
1440 
1441 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1442 	if (!rc) {
1443 		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1444 		CIFSSMBClose(xid, tcon, fid.netfid);
1445 	}
1446 
1447 	cifs_put_tlink(tlink);
1448 	free_xid(xid);
1449 
1450 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1451 	if (rc)
1452 		return ERR_PTR(rc);
1453 	return pntsd;
1454 }
1455 
1456 /* 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)1457 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1458 				      struct inode *inode, const char *path,
1459 			       u32 *pacllen, u32 info)
1460 {
1461 	struct cifs_ntsd *pntsd = NULL;
1462 	struct cifsFileInfo *open_file = NULL;
1463 
1464 	if (inode)
1465 		open_file = find_readable_file(CIFS_I(inode), true);
1466 	if (!open_file)
1467 		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1468 
1469 	pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1470 	cifsFileInfo_put(open_file);
1471 	return pntsd;
1472 }
1473 
1474  /* Set an ACL on the server */
set_cifs_acl(struct cifs_ntsd * pnntsd,__u32 acllen,struct inode * inode,const char * path,int aclflag)1475 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1476 			struct inode *inode, const char *path, int aclflag)
1477 {
1478 	int oplock = 0;
1479 	unsigned int xid;
1480 	int rc, access_flags;
1481 	struct cifs_tcon *tcon;
1482 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1483 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1484 	struct cifs_fid fid;
1485 	struct cifs_open_parms oparms;
1486 
1487 	if (IS_ERR(tlink))
1488 		return PTR_ERR(tlink);
1489 
1490 	tcon = tlink_tcon(tlink);
1491 	xid = get_xid();
1492 
1493 	if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1494 		access_flags = WRITE_OWNER;
1495 	else
1496 		access_flags = WRITE_DAC;
1497 
1498 	oparms = (struct cifs_open_parms) {
1499 		.tcon = tcon,
1500 		.cifs_sb = cifs_sb,
1501 		.desired_access = access_flags,
1502 		.create_options = cifs_create_options(cifs_sb, 0),
1503 		.disposition = FILE_OPEN,
1504 		.path = path,
1505 		.fid = &fid,
1506 	};
1507 
1508 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1509 	if (rc) {
1510 		cifs_dbg(VFS, "Unable to open file to set ACL\n");
1511 		goto out;
1512 	}
1513 
1514 	rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1515 	cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1516 
1517 	CIFSSMBClose(xid, tcon, fid.netfid);
1518 out:
1519 	free_xid(xid);
1520 	cifs_put_tlink(tlink);
1521 	return rc;
1522 }
1523 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1524 
1525 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1526 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)1527 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1528 		  struct inode *inode, bool mode_from_special_sid,
1529 		  const char *path, const struct cifs_fid *pfid)
1530 {
1531 	struct cifs_ntsd *pntsd = NULL;
1532 	u32 acllen = 0;
1533 	int rc = 0;
1534 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1535 	struct smb_version_operations *ops;
1536 	const u32 info = 0;
1537 
1538 	cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1539 
1540 	if (IS_ERR(tlink))
1541 		return PTR_ERR(tlink);
1542 
1543 	ops = tlink_tcon(tlink)->ses->server->ops;
1544 
1545 	if (pfid && (ops->get_acl_by_fid))
1546 		pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1547 	else if (ops->get_acl)
1548 		pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1549 	else {
1550 		cifs_put_tlink(tlink);
1551 		return -EOPNOTSUPP;
1552 	}
1553 	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1554 	if (IS_ERR(pntsd)) {
1555 		rc = PTR_ERR(pntsd);
1556 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1557 	} else if (mode_from_special_sid) {
1558 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1559 		kfree(pntsd);
1560 	} else {
1561 		/* get approximated mode from ACL */
1562 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1563 		kfree(pntsd);
1564 		if (rc)
1565 			cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1566 	}
1567 
1568 	cifs_put_tlink(tlink);
1569 
1570 	return rc;
1571 }
1572 
1573 /* Convert mode bits to an ACL so we can update the ACL on the server */
1574 int
id_mode_to_cifs_acl(struct inode * inode,const char * path,__u64 * pnmode,kuid_t uid,kgid_t gid)1575 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1576 			kuid_t uid, kgid_t gid)
1577 {
1578 	int rc = 0;
1579 	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1580 	__u32 secdesclen = 0;
1581 	__u32 nsecdesclen = 0;
1582 	__u32 dacloffset = 0;
1583 	struct cifs_acl *dacl_ptr = NULL;
1584 	struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1585 	struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1586 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1587 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1588 	struct smb_version_operations *ops;
1589 	bool mode_from_sid, id_from_sid;
1590 	const u32 info = 0;
1591 
1592 	if (IS_ERR(tlink))
1593 		return PTR_ERR(tlink);
1594 
1595 	ops = tlink_tcon(tlink)->ses->server->ops;
1596 
1597 	cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1598 
1599 	/* Get the security descriptor */
1600 
1601 	if (ops->get_acl == NULL) {
1602 		cifs_put_tlink(tlink);
1603 		return -EOPNOTSUPP;
1604 	}
1605 
1606 	pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1607 	if (IS_ERR(pntsd)) {
1608 		rc = PTR_ERR(pntsd);
1609 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1610 		cifs_put_tlink(tlink);
1611 		return rc;
1612 	}
1613 
1614 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1615 		mode_from_sid = true;
1616 	else
1617 		mode_from_sid = false;
1618 
1619 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1620 		id_from_sid = true;
1621 	else
1622 		id_from_sid = false;
1623 
1624 	/* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1625 	nsecdesclen = secdesclen;
1626 	if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1627 		if (mode_from_sid)
1628 			nsecdesclen += 2 * sizeof(struct cifs_ace);
1629 		else /* cifsacl */
1630 			nsecdesclen += 5 * sizeof(struct cifs_ace);
1631 	} else { /* chown */
1632 		/* When ownership changes, changes new owner sid length could be different */
1633 		nsecdesclen = sizeof(struct cifs_ntsd) + (sizeof(struct cifs_sid) * 2);
1634 		dacloffset = le32_to_cpu(pntsd->dacloffset);
1635 		if (dacloffset) {
1636 			dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1637 			if (mode_from_sid)
1638 				nsecdesclen +=
1639 					le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace);
1640 			else /* cifsacl */
1641 				nsecdesclen += le16_to_cpu(dacl_ptr->size);
1642 		}
1643 	}
1644 
1645 	/*
1646 	 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1647 	 * as chmod disables ACEs and set the security descriptor. Allocate
1648 	 * memory for the smb header, set security descriptor request security
1649 	 * descriptor parameters, and security descriptor itself
1650 	 */
1651 	nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1652 	pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);
1653 	if (!pnntsd) {
1654 		kfree(pntsd);
1655 		cifs_put_tlink(tlink);
1656 		return -ENOMEM;
1657 	}
1658 
1659 	rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1660 			    mode_from_sid, id_from_sid, &aclflag);
1661 
1662 	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1663 
1664 	if (ops->set_acl == NULL)
1665 		rc = -EOPNOTSUPP;
1666 
1667 	if (!rc) {
1668 		/* Set the security descriptor */
1669 		rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1670 		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1671 	}
1672 	cifs_put_tlink(tlink);
1673 
1674 	kfree(pnntsd);
1675 	kfree(pntsd);
1676 	return rc;
1677 }
1678 
cifs_get_acl(struct mnt_idmap * idmap,struct dentry * dentry,int type)1679 struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap,
1680 			       struct dentry *dentry, int type)
1681 {
1682 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1683 	struct posix_acl *acl = NULL;
1684 	ssize_t rc = -EOPNOTSUPP;
1685 	unsigned int xid;
1686 	struct super_block *sb = dentry->d_sb;
1687 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1688 	struct tcon_link *tlink;
1689 	struct cifs_tcon *pTcon;
1690 	const char *full_path;
1691 	void *page;
1692 
1693 	tlink = cifs_sb_tlink(cifs_sb);
1694 	if (IS_ERR(tlink))
1695 		return ERR_CAST(tlink);
1696 	pTcon = tlink_tcon(tlink);
1697 
1698 	xid = get_xid();
1699 	page = alloc_dentry_path();
1700 
1701 	full_path = build_path_from_dentry(dentry, page);
1702 	if (IS_ERR(full_path)) {
1703 		acl = ERR_CAST(full_path);
1704 		goto out;
1705 	}
1706 
1707 	/* return alt name if available as pseudo attr */
1708 	switch (type) {
1709 	case ACL_TYPE_ACCESS:
1710 		if (sb->s_flags & SB_POSIXACL)
1711 			rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1712 					     ACL_TYPE_ACCESS,
1713 					     cifs_sb->local_nls,
1714 					     cifs_remap(cifs_sb));
1715 		break;
1716 
1717 	case ACL_TYPE_DEFAULT:
1718 		if (sb->s_flags & SB_POSIXACL)
1719 			rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1720 					     ACL_TYPE_DEFAULT,
1721 					     cifs_sb->local_nls,
1722 					     cifs_remap(cifs_sb));
1723 		break;
1724 	}
1725 
1726 	if (rc < 0) {
1727 		if (rc == -EINVAL)
1728 			acl = ERR_PTR(-EOPNOTSUPP);
1729 		else
1730 			acl = ERR_PTR(rc);
1731 	}
1732 
1733 out:
1734 	free_dentry_path(page);
1735 	free_xid(xid);
1736 	cifs_put_tlink(tlink);
1737 	return acl;
1738 #else
1739 	return ERR_PTR(-EOPNOTSUPP);
1740 #endif
1741 }
1742 
cifs_set_acl(struct mnt_idmap * idmap,struct dentry * dentry,struct posix_acl * acl,int type)1743 int cifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
1744 		 struct posix_acl *acl, int type)
1745 {
1746 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1747 	int rc = -EOPNOTSUPP;
1748 	unsigned int xid;
1749 	struct super_block *sb = dentry->d_sb;
1750 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1751 	struct tcon_link *tlink;
1752 	struct cifs_tcon *pTcon;
1753 	const char *full_path;
1754 	void *page;
1755 
1756 	tlink = cifs_sb_tlink(cifs_sb);
1757 	if (IS_ERR(tlink))
1758 		return PTR_ERR(tlink);
1759 	pTcon = tlink_tcon(tlink);
1760 
1761 	xid = get_xid();
1762 	page = alloc_dentry_path();
1763 
1764 	full_path = build_path_from_dentry(dentry, page);
1765 	if (IS_ERR(full_path)) {
1766 		rc = PTR_ERR(full_path);
1767 		goto out;
1768 	}
1769 
1770 	if (!acl)
1771 		goto out;
1772 
1773 	/* return dos attributes as pseudo xattr */
1774 	/* return alt name if available as pseudo attr */
1775 
1776 	/* if proc/fs/cifs/streamstoxattr is set then
1777 		search server for EAs or streams to
1778 		returns as xattrs */
1779 	if (posix_acl_xattr_size(acl->a_count) > CIFSMaxBufSize) {
1780 		cifs_dbg(FYI, "size of EA value too large\n");
1781 		rc = -EOPNOTSUPP;
1782 		goto out;
1783 	}
1784 
1785 	switch (type) {
1786 	case ACL_TYPE_ACCESS:
1787 		if (sb->s_flags & SB_POSIXACL)
1788 			rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1789 					     ACL_TYPE_ACCESS,
1790 					     cifs_sb->local_nls,
1791 					     cifs_remap(cifs_sb));
1792 		break;
1793 
1794 	case ACL_TYPE_DEFAULT:
1795 		if (sb->s_flags & SB_POSIXACL)
1796 			rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1797 					     ACL_TYPE_DEFAULT,
1798 					     cifs_sb->local_nls,
1799 					     cifs_remap(cifs_sb));
1800 		break;
1801 	}
1802 
1803 out:
1804 	free_dentry_path(page);
1805 	free_xid(xid);
1806 	cifs_put_tlink(tlink);
1807 	return rc;
1808 #else
1809 	return -EOPNOTSUPP;
1810 #endif
1811 }
1812