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