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