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