• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *   fs/cifs/cifsacl.c
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  *   This library is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU Lesser General Public License as published
11  *   by the Free Software Foundation; either version 2.1 of the License, or
12  *   (at your option) any later version.
13  *
14  *   This library is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17  *   the GNU Lesser General Public License for more details.
18  *
19  *   You should have received a copy of the GNU Lesser General Public License
20  *   along with this library; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23 
24 #include <linux/fs.h>
25 #include <linux/slab.h>
26 #include <linux/string.h>
27 #include <linux/keyctl.h>
28 #include <linux/key-type.h>
29 #include <keys/user-type.h>
30 #include "cifspdu.h"
31 #include "cifsglob.h"
32 #include "cifsacl.h"
33 #include "cifsproto.h"
34 #include "cifs_debug.h"
35 
36 /* security id for everyone/world system group */
37 static const struct cifs_sid sid_everyone = {
38 	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
39 /* security id for Authenticated Users system group */
40 static const struct cifs_sid sid_authusers = {
41 	1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
42 
43 /* S-1-22-1 Unmapped Unix users */
44 static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
45 		{cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
46 
47 /* S-1-22-2 Unmapped Unix groups */
48 static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
49 		{cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
50 
51 /*
52  * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
53  */
54 
55 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
56 
57 /* S-1-5-88-1 Unix uid */
58 static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
59 	{cpu_to_le32(88),
60 	 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
61 
62 /* S-1-5-88-2 Unix gid */
63 static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
64 	{cpu_to_le32(88),
65 	 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
66 
67 /* S-1-5-88-3 Unix mode */
68 static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
69 	{cpu_to_le32(88),
70 	 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
71 
72 static const struct cred *root_cred;
73 
74 static int
cifs_idmap_key_instantiate(struct key * key,struct key_preparsed_payload * prep)75 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
76 {
77 	char *payload;
78 
79 	/*
80 	 * If the payload is less than or equal to the size of a pointer, then
81 	 * an allocation here is wasteful. Just copy the data directly to the
82 	 * payload.value union member instead.
83 	 *
84 	 * With this however, you must check the datalen before trying to
85 	 * dereference payload.data!
86 	 */
87 	if (prep->datalen <= sizeof(key->payload)) {
88 		key->payload.data[0] = NULL;
89 		memcpy(&key->payload, prep->data, prep->datalen);
90 	} else {
91 		payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
92 		if (!payload)
93 			return -ENOMEM;
94 		key->payload.data[0] = payload;
95 	}
96 
97 	key->datalen = prep->datalen;
98 	return 0;
99 }
100 
101 static inline void
cifs_idmap_key_destroy(struct key * key)102 cifs_idmap_key_destroy(struct key *key)
103 {
104 	if (key->datalen > sizeof(key->payload))
105 		kfree(key->payload.data[0]);
106 }
107 
108 static struct key_type cifs_idmap_key_type = {
109 	.name        = "cifs.idmap",
110 	.instantiate = cifs_idmap_key_instantiate,
111 	.destroy     = cifs_idmap_key_destroy,
112 	.describe    = user_describe,
113 };
114 
115 static char *
sid_to_key_str(struct cifs_sid * sidptr,unsigned int type)116 sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
117 {
118 	int i, len;
119 	unsigned int saval;
120 	char *sidstr, *strptr;
121 	unsigned long long id_auth_val;
122 
123 	/* 3 bytes for prefix */
124 	sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
125 			 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
126 			 GFP_KERNEL);
127 	if (!sidstr)
128 		return sidstr;
129 
130 	strptr = sidstr;
131 	len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
132 			sidptr->revision);
133 	strptr += len;
134 
135 	/* The authority field is a single 48-bit number */
136 	id_auth_val = (unsigned long long)sidptr->authority[5];
137 	id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
138 	id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
139 	id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
140 	id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
141 	id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
142 
143 	/*
144 	 * MS-DTYP states that if the authority is >= 2^32, then it should be
145 	 * expressed as a hex value.
146 	 */
147 	if (id_auth_val <= UINT_MAX)
148 		len = sprintf(strptr, "-%llu", id_auth_val);
149 	else
150 		len = sprintf(strptr, "-0x%llx", id_auth_val);
151 
152 	strptr += len;
153 
154 	for (i = 0; i < sidptr->num_subauth; ++i) {
155 		saval = le32_to_cpu(sidptr->sub_auth[i]);
156 		len = sprintf(strptr, "-%u", saval);
157 		strptr += len;
158 	}
159 
160 	return sidstr;
161 }
162 
163 /*
164  * if the two SIDs (roughly equivalent to a UUID for a user or group) are
165  * the same returns zero, if they do not match returns non-zero.
166  */
167 static int
compare_sids(const struct cifs_sid * ctsid,const struct cifs_sid * cwsid)168 compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
169 {
170 	int i;
171 	int num_subauth, num_sat, num_saw;
172 
173 	if ((!ctsid) || (!cwsid))
174 		return 1;
175 
176 	/* compare the revision */
177 	if (ctsid->revision != cwsid->revision) {
178 		if (ctsid->revision > cwsid->revision)
179 			return 1;
180 		else
181 			return -1;
182 	}
183 
184 	/* compare all of the six auth values */
185 	for (i = 0; i < NUM_AUTHS; ++i) {
186 		if (ctsid->authority[i] != cwsid->authority[i]) {
187 			if (ctsid->authority[i] > cwsid->authority[i])
188 				return 1;
189 			else
190 				return -1;
191 		}
192 	}
193 
194 	/* compare all of the subauth values if any */
195 	num_sat = ctsid->num_subauth;
196 	num_saw = cwsid->num_subauth;
197 	num_subauth = num_sat < num_saw ? num_sat : num_saw;
198 	if (num_subauth) {
199 		for (i = 0; i < num_subauth; ++i) {
200 			if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
201 				if (le32_to_cpu(ctsid->sub_auth[i]) >
202 					le32_to_cpu(cwsid->sub_auth[i]))
203 					return 1;
204 				else
205 					return -1;
206 			}
207 		}
208 	}
209 
210 	return 0; /* sids compare/match */
211 }
212 
213 static bool
is_well_known_sid(const struct cifs_sid * psid,uint32_t * puid,bool is_group)214 is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
215 {
216 	int i;
217 	int num_subauth;
218 	const struct cifs_sid *pwell_known_sid;
219 
220 	if (!psid || (puid == NULL))
221 		return false;
222 
223 	num_subauth = psid->num_subauth;
224 
225 	/* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
226 	if (num_subauth == 2) {
227 		if (is_group)
228 			pwell_known_sid = &sid_unix_groups;
229 		else
230 			pwell_known_sid = &sid_unix_users;
231 	} else if (num_subauth == 3) {
232 		if (is_group)
233 			pwell_known_sid = &sid_unix_NFS_groups;
234 		else
235 			pwell_known_sid = &sid_unix_NFS_users;
236 	} else
237 		return false;
238 
239 	/* compare the revision */
240 	if (psid->revision != pwell_known_sid->revision)
241 		return false;
242 
243 	/* compare all of the six auth values */
244 	for (i = 0; i < NUM_AUTHS; ++i) {
245 		if (psid->authority[i] != pwell_known_sid->authority[i]) {
246 			cifs_dbg(FYI, "auth %d did not match\n", i);
247 			return false;
248 		}
249 	}
250 
251 	if (num_subauth == 2) {
252 		if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
253 			return false;
254 
255 		*puid = le32_to_cpu(psid->sub_auth[1]);
256 	} else /* 3 subauths, ie Windows/Mac style */ {
257 		*puid = le32_to_cpu(psid->sub_auth[0]);
258 		if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
259 		    (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
260 			return false;
261 
262 		*puid = le32_to_cpu(psid->sub_auth[2]);
263 	}
264 
265 	cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
266 	return true; /* well known sid found, uid returned */
267 }
268 
269 static void
cifs_copy_sid(struct cifs_sid * dst,const struct cifs_sid * src)270 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
271 {
272 	int i;
273 
274 	dst->revision = src->revision;
275 	dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
276 	for (i = 0; i < NUM_AUTHS; ++i)
277 		dst->authority[i] = src->authority[i];
278 	for (i = 0; i < dst->num_subauth; ++i)
279 		dst->sub_auth[i] = src->sub_auth[i];
280 }
281 
282 static int
id_to_sid(unsigned int cid,uint sidtype,struct cifs_sid * ssid)283 id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
284 {
285 	int rc;
286 	struct key *sidkey;
287 	struct cifs_sid *ksid;
288 	unsigned int ksid_size;
289 	char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
290 	const struct cred *saved_cred;
291 
292 	rc = snprintf(desc, sizeof(desc), "%ci:%u",
293 			sidtype == SIDOWNER ? 'o' : 'g', cid);
294 	if (rc >= sizeof(desc))
295 		return -EINVAL;
296 
297 	rc = 0;
298 	saved_cred = override_creds(root_cred);
299 	sidkey = request_key(&cifs_idmap_key_type, desc, "");
300 	if (IS_ERR(sidkey)) {
301 		rc = -EINVAL;
302 		cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
303 			 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
304 		goto out_revert_creds;
305 	} else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
306 		rc = -EIO;
307 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
308 			 __func__, sidkey->datalen);
309 		goto invalidate_key;
310 	}
311 
312 	/*
313 	 * A sid is usually too large to be embedded in payload.value, but if
314 	 * there are no subauthorities and the host has 8-byte pointers, then
315 	 * it could be.
316 	 */
317 	ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
318 		(struct cifs_sid *)&sidkey->payload :
319 		(struct cifs_sid *)sidkey->payload.data[0];
320 
321 	ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
322 	if (ksid_size > sidkey->datalen) {
323 		rc = -EIO;
324 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
325 			 __func__, sidkey->datalen, ksid_size);
326 		goto invalidate_key;
327 	}
328 
329 	cifs_copy_sid(ssid, ksid);
330 out_key_put:
331 	key_put(sidkey);
332 out_revert_creds:
333 	revert_creds(saved_cred);
334 	return rc;
335 
336 invalidate_key:
337 	key_invalidate(sidkey);
338 	goto out_key_put;
339 }
340 
341 int
sid_to_id(struct cifs_sb_info * cifs_sb,struct cifs_sid * psid,struct cifs_fattr * fattr,uint sidtype)342 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
343 		struct cifs_fattr *fattr, uint sidtype)
344 {
345 	int rc = 0;
346 	struct key *sidkey;
347 	char *sidstr;
348 	const struct cred *saved_cred;
349 	kuid_t fuid = cifs_sb->mnt_uid;
350 	kgid_t fgid = cifs_sb->mnt_gid;
351 
352 	/*
353 	 * If we have too many subauthorities, then something is really wrong.
354 	 * Just return an error.
355 	 */
356 	if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
357 		cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
358 			 __func__, psid->num_subauth);
359 		return -EIO;
360 	}
361 
362 	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
363 	    (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
364 		uint32_t unix_id;
365 		bool is_group;
366 
367 		if (sidtype != SIDOWNER)
368 			is_group = true;
369 		else
370 			is_group = false;
371 
372 		if (is_well_known_sid(psid, &unix_id, is_group) == false)
373 			goto try_upcall_to_get_id;
374 
375 		if (is_group) {
376 			kgid_t gid;
377 			gid_t id;
378 
379 			id = (gid_t)unix_id;
380 			gid = make_kgid(&init_user_ns, id);
381 			if (gid_valid(gid)) {
382 				fgid = gid;
383 				goto got_valid_id;
384 			}
385 		} else {
386 			kuid_t uid;
387 			uid_t id;
388 
389 			id = (uid_t)unix_id;
390 			uid = make_kuid(&init_user_ns, id);
391 			if (uid_valid(uid)) {
392 				fuid = uid;
393 				goto got_valid_id;
394 			}
395 		}
396 		/* If unable to find uid/gid easily from SID try via upcall */
397 	}
398 
399 try_upcall_to_get_id:
400 	sidstr = sid_to_key_str(psid, sidtype);
401 	if (!sidstr)
402 		return -ENOMEM;
403 
404 	saved_cred = override_creds(root_cred);
405 	sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
406 	if (IS_ERR(sidkey)) {
407 		rc = -EINVAL;
408 		cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
409 			 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
410 		goto out_revert_creds;
411 	}
412 
413 	/*
414 	 * FIXME: Here we assume that uid_t and gid_t are same size. It's
415 	 * probably a safe assumption but might be better to check based on
416 	 * sidtype.
417 	 */
418 	BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
419 	if (sidkey->datalen != sizeof(uid_t)) {
420 		rc = -EIO;
421 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
422 			 __func__, sidkey->datalen);
423 		key_invalidate(sidkey);
424 		goto out_key_put;
425 	}
426 
427 	if (sidtype == SIDOWNER) {
428 		kuid_t uid;
429 		uid_t id;
430 		memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
431 		uid = make_kuid(&init_user_ns, id);
432 		if (uid_valid(uid))
433 			fuid = uid;
434 	} else {
435 		kgid_t gid;
436 		gid_t id;
437 		memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
438 		gid = make_kgid(&init_user_ns, id);
439 		if (gid_valid(gid))
440 			fgid = gid;
441 	}
442 
443 out_key_put:
444 	key_put(sidkey);
445 out_revert_creds:
446 	revert_creds(saved_cred);
447 	kfree(sidstr);
448 
449 	/*
450 	 * Note that we return 0 here unconditionally. If the mapping
451 	 * fails then we just fall back to using the mnt_uid/mnt_gid.
452 	 */
453 got_valid_id:
454 	rc = 0;
455 	if (sidtype == SIDOWNER)
456 		fattr->cf_uid = fuid;
457 	else
458 		fattr->cf_gid = fgid;
459 	return rc;
460 }
461 
462 int
init_cifs_idmap(void)463 init_cifs_idmap(void)
464 {
465 	struct cred *cred;
466 	struct key *keyring;
467 	int ret;
468 
469 	cifs_dbg(FYI, "Registering the %s key type\n",
470 		 cifs_idmap_key_type.name);
471 
472 	/* create an override credential set with a special thread keyring in
473 	 * which requests are cached
474 	 *
475 	 * this is used to prevent malicious redirections from being installed
476 	 * with add_key().
477 	 */
478 	cred = prepare_kernel_cred(NULL);
479 	if (!cred)
480 		return -ENOMEM;
481 
482 	keyring = keyring_alloc(".cifs_idmap",
483 				GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
484 				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
485 				KEY_USR_VIEW | KEY_USR_READ,
486 				KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
487 	if (IS_ERR(keyring)) {
488 		ret = PTR_ERR(keyring);
489 		goto failed_put_cred;
490 	}
491 
492 	ret = register_key_type(&cifs_idmap_key_type);
493 	if (ret < 0)
494 		goto failed_put_key;
495 
496 	/* instruct request_key() to use this special keyring as a cache for
497 	 * the results it looks up */
498 	set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
499 	cred->thread_keyring = keyring;
500 	cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
501 	root_cred = cred;
502 
503 	cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
504 	return 0;
505 
506 failed_put_key:
507 	key_put(keyring);
508 failed_put_cred:
509 	put_cred(cred);
510 	return ret;
511 }
512 
513 void
exit_cifs_idmap(void)514 exit_cifs_idmap(void)
515 {
516 	key_revoke(root_cred->thread_keyring);
517 	unregister_key_type(&cifs_idmap_key_type);
518 	put_cred(root_cred);
519 	cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
520 }
521 
522 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
copy_sec_desc(const struct cifs_ntsd * pntsd,struct cifs_ntsd * pnntsd,__u32 sidsoffset)523 static void copy_sec_desc(const struct cifs_ntsd *pntsd,
524 				struct cifs_ntsd *pnntsd, __u32 sidsoffset)
525 {
526 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
527 	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
528 
529 	/* copy security descriptor control portion */
530 	pnntsd->revision = pntsd->revision;
531 	pnntsd->type = pntsd->type;
532 	pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
533 	pnntsd->sacloffset = 0;
534 	pnntsd->osidoffset = cpu_to_le32(sidsoffset);
535 	pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
536 
537 	/* copy owner sid */
538 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
539 				le32_to_cpu(pntsd->osidoffset));
540 	nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
541 	cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
542 
543 	/* copy group sid */
544 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
545 				le32_to_cpu(pntsd->gsidoffset));
546 	ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
547 					sizeof(struct cifs_sid));
548 	cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
549 
550 	return;
551 }
552 
553 
554 /*
555    change posix mode to reflect permissions
556    pmode is the existing mode (we only want to overwrite part of this
557    bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
558 */
access_flags_to_mode(__le32 ace_flags,int type,umode_t * pmode,umode_t * pbits_to_set)559 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
560 				 umode_t *pbits_to_set)
561 {
562 	__u32 flags = le32_to_cpu(ace_flags);
563 	/* the order of ACEs is important.  The canonical order is to begin with
564 	   DENY entries followed by ALLOW, otherwise an allow entry could be
565 	   encountered first, making the subsequent deny entry like "dead code"
566 	   which would be superflous since Windows stops when a match is made
567 	   for the operation you are trying to perform for your user */
568 
569 	/* For deny ACEs we change the mask so that subsequent allow access
570 	   control entries do not turn on the bits we are denying */
571 	if (type == ACCESS_DENIED) {
572 		if (flags & GENERIC_ALL)
573 			*pbits_to_set &= ~S_IRWXUGO;
574 
575 		if ((flags & GENERIC_WRITE) ||
576 			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
577 			*pbits_to_set &= ~S_IWUGO;
578 		if ((flags & GENERIC_READ) ||
579 			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
580 			*pbits_to_set &= ~S_IRUGO;
581 		if ((flags & GENERIC_EXECUTE) ||
582 			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
583 			*pbits_to_set &= ~S_IXUGO;
584 		return;
585 	} else if (type != ACCESS_ALLOWED) {
586 		cifs_dbg(VFS, "unknown access control type %d\n", type);
587 		return;
588 	}
589 	/* else ACCESS_ALLOWED type */
590 
591 	if (flags & GENERIC_ALL) {
592 		*pmode |= (S_IRWXUGO & (*pbits_to_set));
593 		cifs_dbg(NOISY, "all perms\n");
594 		return;
595 	}
596 	if ((flags & GENERIC_WRITE) ||
597 			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
598 		*pmode |= (S_IWUGO & (*pbits_to_set));
599 	if ((flags & GENERIC_READ) ||
600 			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
601 		*pmode |= (S_IRUGO & (*pbits_to_set));
602 	if ((flags & GENERIC_EXECUTE) ||
603 			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
604 		*pmode |= (S_IXUGO & (*pbits_to_set));
605 
606 	cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
607 	return;
608 }
609 
610 /*
611    Generate access flags to reflect permissions mode is the existing mode.
612    This function is called for every ACE in the DACL whose SID matches
613    with either owner or group or everyone.
614 */
615 
mode_to_access_flags(umode_t mode,umode_t bits_to_use,__u32 * pace_flags)616 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
617 				__u32 *pace_flags)
618 {
619 	/* reset access mask */
620 	*pace_flags = 0x0;
621 
622 	/* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
623 	mode &= bits_to_use;
624 
625 	/* check for R/W/X UGO since we do not know whose flags
626 	   is this but we have cleared all the bits sans RWX for
627 	   either user or group or other as per bits_to_use */
628 	if (mode & S_IRUGO)
629 		*pace_flags |= SET_FILE_READ_RIGHTS;
630 	if (mode & S_IWUGO)
631 		*pace_flags |= SET_FILE_WRITE_RIGHTS;
632 	if (mode & S_IXUGO)
633 		*pace_flags |= SET_FILE_EXEC_RIGHTS;
634 
635 	cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
636 		 mode, *pace_flags);
637 	return;
638 }
639 
fill_ace_for_sid(struct cifs_ace * pntace,const struct cifs_sid * psid,__u64 nmode,umode_t bits)640 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
641 			const struct cifs_sid *psid, __u64 nmode, umode_t bits)
642 {
643 	int i;
644 	__u16 size = 0;
645 	__u32 access_req = 0;
646 
647 	pntace->type = ACCESS_ALLOWED;
648 	pntace->flags = 0x0;
649 	mode_to_access_flags(nmode, bits, &access_req);
650 	if (!access_req)
651 		access_req = SET_MINIMUM_RIGHTS;
652 	pntace->access_req = cpu_to_le32(access_req);
653 
654 	pntace->sid.revision = psid->revision;
655 	pntace->sid.num_subauth = psid->num_subauth;
656 	for (i = 0; i < NUM_AUTHS; i++)
657 		pntace->sid.authority[i] = psid->authority[i];
658 	for (i = 0; i < psid->num_subauth; i++)
659 		pntace->sid.sub_auth[i] = psid->sub_auth[i];
660 
661 	size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
662 	pntace->size = cpu_to_le16(size);
663 
664 	return size;
665 }
666 
667 
668 #ifdef CONFIG_CIFS_DEBUG2
dump_ace(struct cifs_ace * pace,char * end_of_acl)669 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
670 {
671 	int num_subauth;
672 
673 	/* validate that we do not go past end of acl */
674 
675 	if (le16_to_cpu(pace->size) < 16) {
676 		cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
677 		return;
678 	}
679 
680 	if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
681 		cifs_dbg(VFS, "ACL too small to parse ACE\n");
682 		return;
683 	}
684 
685 	num_subauth = pace->sid.num_subauth;
686 	if (num_subauth) {
687 		int i;
688 		cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
689 			 pace->sid.revision, pace->sid.num_subauth, pace->type,
690 			 pace->flags, le16_to_cpu(pace->size));
691 		for (i = 0; i < num_subauth; ++i) {
692 			cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
693 				 i, le32_to_cpu(pace->sid.sub_auth[i]));
694 		}
695 
696 		/* BB add length check to make sure that we do not have huge
697 			num auths and therefore go off the end */
698 	}
699 
700 	return;
701 }
702 #endif
703 
parse_dacl(struct cifs_acl * pdacl,char * end_of_acl,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,struct cifs_fattr * fattr,bool mode_from_special_sid)704 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
705 		       struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
706 		       struct cifs_fattr *fattr, bool mode_from_special_sid)
707 {
708 	int i;
709 	int num_aces = 0;
710 	int acl_size;
711 	char *acl_base;
712 	struct cifs_ace **ppace;
713 
714 	/* BB need to add parm so we can store the SID BB */
715 
716 	if (!pdacl) {
717 		/* no DACL in the security descriptor, set
718 		   all the permissions for user/group/other */
719 		fattr->cf_mode |= S_IRWXUGO;
720 		return;
721 	}
722 
723 	/* validate that we do not go past end of acl */
724 	if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
725 		cifs_dbg(VFS, "ACL too small to parse DACL\n");
726 		return;
727 	}
728 
729 	cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
730 		 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
731 		 le32_to_cpu(pdacl->num_aces));
732 
733 	/* reset rwx permissions for user/group/other.
734 	   Also, if num_aces is 0 i.e. DACL has no ACEs,
735 	   user/group/other have no permissions */
736 	fattr->cf_mode &= ~(S_IRWXUGO);
737 
738 	acl_base = (char *)pdacl;
739 	acl_size = sizeof(struct cifs_acl);
740 
741 	num_aces = le32_to_cpu(pdacl->num_aces);
742 	if (num_aces > 0) {
743 		umode_t user_mask = S_IRWXU;
744 		umode_t group_mask = S_IRWXG;
745 		umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
746 
747 		if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
748 			return;
749 		ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
750 				      GFP_KERNEL);
751 		if (!ppace)
752 			return;
753 
754 		for (i = 0; i < num_aces; ++i) {
755 			ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
756 #ifdef CONFIG_CIFS_DEBUG2
757 			dump_ace(ppace[i], end_of_acl);
758 #endif
759 			if (mode_from_special_sid &&
760 			    (compare_sids(&(ppace[i]->sid),
761 					  &sid_unix_NFS_mode) == 0)) {
762 				/*
763 				 * Full permissions are:
764 				 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
765 				 *         S_IRWXU | S_IRWXG | S_IRWXO
766 				 */
767 				fattr->cf_mode &= ~07777;
768 				fattr->cf_mode |=
769 					le32_to_cpu(ppace[i]->sid.sub_auth[2]);
770 				break;
771 			} else if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
772 				access_flags_to_mode(ppace[i]->access_req,
773 						     ppace[i]->type,
774 						     &fattr->cf_mode,
775 						     &user_mask);
776 			else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
777 				access_flags_to_mode(ppace[i]->access_req,
778 						     ppace[i]->type,
779 						     &fattr->cf_mode,
780 						     &group_mask);
781 			else if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
782 				access_flags_to_mode(ppace[i]->access_req,
783 						     ppace[i]->type,
784 						     &fattr->cf_mode,
785 						     &other_mask);
786 			else if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
787 				access_flags_to_mode(ppace[i]->access_req,
788 						     ppace[i]->type,
789 						     &fattr->cf_mode,
790 						     &other_mask);
791 
792 
793 /*			memcpy((void *)(&(cifscred->aces[i])),
794 				(void *)ppace[i],
795 				sizeof(struct cifs_ace)); */
796 
797 			acl_base = (char *)ppace[i];
798 			acl_size = le16_to_cpu(ppace[i]->size);
799 		}
800 
801 		kfree(ppace);
802 	}
803 
804 	return;
805 }
806 
setup_authusers_ACE(struct cifs_ace * pntace)807 unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
808 {
809 	int i;
810 	unsigned int ace_size = 20;
811 
812 	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
813 	pntace->flags = 0x0;
814 	pntace->access_req = cpu_to_le32(GENERIC_ALL);
815 	pntace->sid.num_subauth = 1;
816 	pntace->sid.revision = 1;
817 	for (i = 0; i < NUM_AUTHS; i++)
818 		pntace->sid.authority[i] =  sid_authusers.authority[i];
819 
820 	pntace->sid.sub_auth[0] =  sid_authusers.sub_auth[0];
821 
822 	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
823 	pntace->size = cpu_to_le16(ace_size);
824 	return ace_size;
825 }
826 
827 /*
828  * Fill in the special SID based on the mode. See
829  * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
830  */
setup_special_mode_ACE(struct cifs_ace * pntace,__u64 nmode)831 unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
832 {
833 	int i;
834 	unsigned int ace_size = 28;
835 
836 	pntace->type = ACCESS_DENIED_ACE_TYPE;
837 	pntace->flags = 0x0;
838 	pntace->access_req = 0;
839 	pntace->sid.num_subauth = 3;
840 	pntace->sid.revision = 1;
841 	for (i = 0; i < NUM_AUTHS; i++)
842 		pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
843 
844 	pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
845 	pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
846 	pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
847 
848 	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
849 	pntace->size = cpu_to_le16(ace_size);
850 	return ace_size;
851 }
852 
setup_special_user_owner_ACE(struct cifs_ace * pntace)853 unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
854 {
855 	int i;
856 	unsigned int ace_size = 28;
857 
858 	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
859 	pntace->flags = 0x0;
860 	pntace->access_req = cpu_to_le32(GENERIC_ALL);
861 	pntace->sid.num_subauth = 3;
862 	pntace->sid.revision = 1;
863 	for (i = 0; i < NUM_AUTHS; i++)
864 		pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
865 
866 	pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
867 	pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
868 	pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
869 
870 	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
871 	pntace->size = cpu_to_le16(ace_size);
872 	return ace_size;
873 }
874 
set_chmod_dacl(struct cifs_acl * pndacl,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,__u64 nmode,bool modefromsid)875 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
876 			struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
877 {
878 	u16 size = 0;
879 	u32 num_aces = 0;
880 	struct cifs_acl *pnndacl;
881 
882 	pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
883 
884 	if (modefromsid) {
885 		struct cifs_ace *pntace =
886 			(struct cifs_ace *)((char *)pnndacl + size);
887 
888 		size += setup_special_mode_ACE(pntace, nmode);
889 		num_aces++;
890 	}
891 
892 	size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
893 					pownersid, nmode, S_IRWXU);
894 	num_aces++;
895 	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
896 					pgrpsid, nmode, S_IRWXG);
897 	num_aces++;
898 	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
899 					 &sid_everyone, nmode, S_IRWXO);
900 	num_aces++;
901 
902 	pndacl->num_aces = cpu_to_le32(num_aces);
903 	pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
904 
905 	return 0;
906 }
907 
908 
parse_sid(struct cifs_sid * psid,char * end_of_acl)909 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
910 {
911 	/* BB need to add parm so we can store the SID BB */
912 
913 	/* validate that we do not go past end of ACL - sid must be at least 8
914 	   bytes long (assuming no sub-auths - e.g. the null SID */
915 	if (end_of_acl < (char *)psid + 8) {
916 		cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
917 		return -EINVAL;
918 	}
919 
920 #ifdef CONFIG_CIFS_DEBUG2
921 	if (psid->num_subauth) {
922 		int i;
923 		cifs_dbg(FYI, "SID revision %d num_auth %d\n",
924 			 psid->revision, psid->num_subauth);
925 
926 		for (i = 0; i < psid->num_subauth; i++) {
927 			cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
928 				 i, le32_to_cpu(psid->sub_auth[i]));
929 		}
930 
931 		/* BB add length check to make sure that we do not have huge
932 			num auths and therefore go off the end */
933 		cifs_dbg(FYI, "RID 0x%x\n",
934 			 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
935 	}
936 #endif
937 
938 	return 0;
939 }
940 
941 
942 /* Convert CIFS ACL to POSIX form */
parse_sec_desc(struct cifs_sb_info * cifs_sb,struct cifs_ntsd * pntsd,int acl_len,struct cifs_fattr * fattr,bool get_mode_from_special_sid)943 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
944 		struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
945 		bool get_mode_from_special_sid)
946 {
947 	int rc = 0;
948 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
949 	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
950 	char *end_of_acl = ((char *)pntsd) + acl_len;
951 	__u32 dacloffset;
952 
953 	if (pntsd == NULL)
954 		return -EIO;
955 
956 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
957 				le32_to_cpu(pntsd->osidoffset));
958 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
959 				le32_to_cpu(pntsd->gsidoffset));
960 	dacloffset = le32_to_cpu(pntsd->dacloffset);
961 	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
962 	cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
963 		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
964 		 le32_to_cpu(pntsd->gsidoffset),
965 		 le32_to_cpu(pntsd->sacloffset), dacloffset);
966 /*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
967 	rc = parse_sid(owner_sid_ptr, end_of_acl);
968 	if (rc) {
969 		cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
970 		return rc;
971 	}
972 	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
973 	if (rc) {
974 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
975 			 __func__, rc);
976 		return rc;
977 	}
978 
979 	rc = parse_sid(group_sid_ptr, end_of_acl);
980 	if (rc) {
981 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
982 			 __func__, rc);
983 		return rc;
984 	}
985 	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
986 	if (rc) {
987 		cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
988 			 __func__, rc);
989 		return rc;
990 	}
991 
992 	if (dacloffset)
993 		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
994 			   group_sid_ptr, fattr, get_mode_from_special_sid);
995 	else
996 		cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
997 
998 	return rc;
999 }
1000 
1001 /* Convert permission bits from mode to equivalent CIFS ACL */
build_sec_desc(struct cifs_ntsd * pntsd,struct cifs_ntsd * pnntsd,__u32 secdesclen,__u64 nmode,kuid_t uid,kgid_t gid,bool mode_from_sid,bool id_from_sid,int * aclflag)1002 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1003 	__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid,
1004 	bool mode_from_sid, bool id_from_sid, int *aclflag)
1005 {
1006 	int rc = 0;
1007 	__u32 dacloffset;
1008 	__u32 ndacloffset;
1009 	__u32 sidsoffset;
1010 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1011 	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
1012 	struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
1013 	struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1014 
1015 	if (nmode != NO_CHANGE_64) { /* chmod */
1016 		owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1017 				le32_to_cpu(pntsd->osidoffset));
1018 		group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1019 				le32_to_cpu(pntsd->gsidoffset));
1020 		dacloffset = le32_to_cpu(pntsd->dacloffset);
1021 		dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1022 		ndacloffset = sizeof(struct cifs_ntsd);
1023 		ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1024 		ndacl_ptr->revision = dacl_ptr->revision;
1025 		ndacl_ptr->size = 0;
1026 		ndacl_ptr->num_aces = 0;
1027 
1028 		rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1029 				    nmode, mode_from_sid);
1030 		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1031 		/* copy sec desc control portion & owner and group sids */
1032 		copy_sec_desc(pntsd, pnntsd, sidsoffset);
1033 		*aclflag = CIFS_ACL_DACL;
1034 	} else {
1035 		memcpy(pnntsd, pntsd, secdesclen);
1036 		if (uid_valid(uid)) { /* chown */
1037 			uid_t id;
1038 			owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1039 					le32_to_cpu(pnntsd->osidoffset));
1040 			nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1041 								GFP_KERNEL);
1042 			if (!nowner_sid_ptr)
1043 				return -ENOMEM;
1044 			id = from_kuid(&init_user_ns, uid);
1045 			if (id_from_sid) {
1046 				struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1047 				/* Populate the user ownership fields S-1-5-88-1 */
1048 				osid->Revision = 1;
1049 				osid->NumAuth = 3;
1050 				osid->Authority[5] = 5;
1051 				osid->SubAuthorities[0] = cpu_to_le32(88);
1052 				osid->SubAuthorities[1] = cpu_to_le32(1);
1053 				osid->SubAuthorities[2] = cpu_to_le32(id);
1054 			} else { /* lookup sid with upcall */
1055 				rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1056 				if (rc) {
1057 					cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1058 						 __func__, rc, id);
1059 					kfree(nowner_sid_ptr);
1060 					return rc;
1061 				}
1062 			}
1063 			cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
1064 			kfree(nowner_sid_ptr);
1065 			*aclflag = CIFS_ACL_OWNER;
1066 		}
1067 		if (gid_valid(gid)) { /* chgrp */
1068 			gid_t id;
1069 			group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1070 					le32_to_cpu(pnntsd->gsidoffset));
1071 			ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1072 								GFP_KERNEL);
1073 			if (!ngroup_sid_ptr)
1074 				return -ENOMEM;
1075 			id = from_kgid(&init_user_ns, gid);
1076 			if (id_from_sid) {
1077 				struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1078 				/* Populate the group ownership fields S-1-5-88-2 */
1079 				gsid->Revision = 1;
1080 				gsid->NumAuth = 3;
1081 				gsid->Authority[5] = 5;
1082 				gsid->SubAuthorities[0] = cpu_to_le32(88);
1083 				gsid->SubAuthorities[1] = cpu_to_le32(2);
1084 				gsid->SubAuthorities[2] = cpu_to_le32(id);
1085 			} else { /* lookup sid with upcall */
1086 				rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1087 				if (rc) {
1088 					cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1089 						 __func__, rc, id);
1090 					kfree(ngroup_sid_ptr);
1091 					return rc;
1092 				}
1093 			}
1094 			cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
1095 			kfree(ngroup_sid_ptr);
1096 			*aclflag = CIFS_ACL_GROUP;
1097 		}
1098 	}
1099 
1100 	return rc;
1101 }
1102 
get_cifs_acl_by_fid(struct cifs_sb_info * cifs_sb,const struct cifs_fid * cifsfid,u32 * pacllen)1103 struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1104 		const struct cifs_fid *cifsfid, u32 *pacllen)
1105 {
1106 	struct cifs_ntsd *pntsd = NULL;
1107 	unsigned int xid;
1108 	int rc;
1109 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1110 
1111 	if (IS_ERR(tlink))
1112 		return ERR_CAST(tlink);
1113 
1114 	xid = get_xid();
1115 	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1116 				pacllen);
1117 	free_xid(xid);
1118 
1119 	cifs_put_tlink(tlink);
1120 
1121 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1122 	if (rc)
1123 		return ERR_PTR(rc);
1124 	return pntsd;
1125 }
1126 
get_cifs_acl_by_path(struct cifs_sb_info * cifs_sb,const char * path,u32 * pacllen)1127 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1128 		const char *path, u32 *pacllen)
1129 {
1130 	struct cifs_ntsd *pntsd = NULL;
1131 	int oplock = 0;
1132 	unsigned int xid;
1133 	int rc;
1134 	struct cifs_tcon *tcon;
1135 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1136 	struct cifs_fid fid;
1137 	struct cifs_open_parms oparms;
1138 
1139 	if (IS_ERR(tlink))
1140 		return ERR_CAST(tlink);
1141 
1142 	tcon = tlink_tcon(tlink);
1143 	xid = get_xid();
1144 
1145 	oparms.tcon = tcon;
1146 	oparms.cifs_sb = cifs_sb;
1147 	oparms.desired_access = READ_CONTROL;
1148 	oparms.create_options = cifs_create_options(cifs_sb, 0);
1149 	oparms.disposition = FILE_OPEN;
1150 	oparms.path = path;
1151 	oparms.fid = &fid;
1152 	oparms.reconnect = false;
1153 
1154 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1155 	if (!rc) {
1156 		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1157 		CIFSSMBClose(xid, tcon, fid.netfid);
1158 	}
1159 
1160 	cifs_put_tlink(tlink);
1161 	free_xid(xid);
1162 
1163 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1164 	if (rc)
1165 		return ERR_PTR(rc);
1166 	return pntsd;
1167 }
1168 
1169 /* Retrieve an ACL from the server */
get_cifs_acl(struct cifs_sb_info * cifs_sb,struct inode * inode,const char * path,u32 * pacllen)1170 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1171 				      struct inode *inode, const char *path,
1172 				      u32 *pacllen)
1173 {
1174 	struct cifs_ntsd *pntsd = NULL;
1175 	struct cifsFileInfo *open_file = NULL;
1176 
1177 	if (inode)
1178 		open_file = find_readable_file(CIFS_I(inode), true);
1179 	if (!open_file)
1180 		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1181 
1182 	pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
1183 	cifsFileInfo_put(open_file);
1184 	return pntsd;
1185 }
1186 
1187  /* Set an ACL on the server */
set_cifs_acl(struct cifs_ntsd * pnntsd,__u32 acllen,struct inode * inode,const char * path,int aclflag)1188 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1189 			struct inode *inode, const char *path, int aclflag)
1190 {
1191 	int oplock = 0;
1192 	unsigned int xid;
1193 	int rc, access_flags;
1194 	struct cifs_tcon *tcon;
1195 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1196 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1197 	struct cifs_fid fid;
1198 	struct cifs_open_parms oparms;
1199 
1200 	if (IS_ERR(tlink))
1201 		return PTR_ERR(tlink);
1202 
1203 	tcon = tlink_tcon(tlink);
1204 	xid = get_xid();
1205 
1206 	if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1207 		access_flags = WRITE_OWNER;
1208 	else
1209 		access_flags = WRITE_DAC;
1210 
1211 	oparms.tcon = tcon;
1212 	oparms.cifs_sb = cifs_sb;
1213 	oparms.desired_access = access_flags;
1214 	oparms.create_options = cifs_create_options(cifs_sb, 0);
1215 	oparms.disposition = FILE_OPEN;
1216 	oparms.path = path;
1217 	oparms.fid = &fid;
1218 	oparms.reconnect = false;
1219 
1220 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1221 	if (rc) {
1222 		cifs_dbg(VFS, "Unable to open file to set ACL\n");
1223 		goto out;
1224 	}
1225 
1226 	rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1227 	cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1228 
1229 	CIFSSMBClose(xid, tcon, fid.netfid);
1230 out:
1231 	free_xid(xid);
1232 	cifs_put_tlink(tlink);
1233 	return rc;
1234 }
1235 
1236 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1237 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)1238 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1239 		  struct inode *inode, bool mode_from_special_sid,
1240 		  const char *path, const struct cifs_fid *pfid)
1241 {
1242 	struct cifs_ntsd *pntsd = NULL;
1243 	u32 acllen = 0;
1244 	int rc = 0;
1245 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1246 	struct smb_version_operations *ops;
1247 
1248 	cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1249 
1250 	if (IS_ERR(tlink))
1251 		return PTR_ERR(tlink);
1252 
1253 	ops = tlink_tcon(tlink)->ses->server->ops;
1254 
1255 	if (pfid && (ops->get_acl_by_fid))
1256 		pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
1257 	else if (ops->get_acl)
1258 		pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
1259 	else {
1260 		cifs_put_tlink(tlink);
1261 		return -EOPNOTSUPP;
1262 	}
1263 	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1264 	if (IS_ERR(pntsd)) {
1265 		rc = PTR_ERR(pntsd);
1266 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1267 	} else if (mode_from_special_sid) {
1268 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1269 		kfree(pntsd);
1270 	} else {
1271 		/* get approximated mode from ACL */
1272 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1273 		kfree(pntsd);
1274 		if (rc)
1275 			cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1276 	}
1277 
1278 	cifs_put_tlink(tlink);
1279 
1280 	return rc;
1281 }
1282 
1283 /* Convert mode bits to an ACL so we can update the ACL on the server */
1284 int
id_mode_to_cifs_acl(struct inode * inode,const char * path,__u64 nmode,kuid_t uid,kgid_t gid)1285 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1286 			kuid_t uid, kgid_t gid)
1287 {
1288 	int rc = 0;
1289 	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1290 	__u32 secdesclen = 0;
1291 	struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1292 	struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1293 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1294 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1295 	struct smb_version_operations *ops;
1296 	bool mode_from_sid, id_from_sid;
1297 
1298 	if (IS_ERR(tlink))
1299 		return PTR_ERR(tlink);
1300 
1301 	ops = tlink_tcon(tlink)->ses->server->ops;
1302 
1303 	cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1304 
1305 	/* Get the security descriptor */
1306 
1307 	if (ops->get_acl == NULL) {
1308 		cifs_put_tlink(tlink);
1309 		return -EOPNOTSUPP;
1310 	}
1311 
1312 	pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
1313 	if (IS_ERR(pntsd)) {
1314 		rc = PTR_ERR(pntsd);
1315 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1316 		cifs_put_tlink(tlink);
1317 		return rc;
1318 	}
1319 
1320 	/*
1321 	 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1322 	 * as chmod disables ACEs and set the security descriptor. Allocate
1323 	 * memory for the smb header, set security descriptor request security
1324 	 * descriptor parameters, and secuirty descriptor itself
1325 	 */
1326 	secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1327 	pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1328 	if (!pnntsd) {
1329 		kfree(pntsd);
1330 		cifs_put_tlink(tlink);
1331 		return -ENOMEM;
1332 	}
1333 
1334 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1335 		mode_from_sid = true;
1336 	else
1337 		mode_from_sid = false;
1338 
1339 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1340 		id_from_sid = true;
1341 	else
1342 		id_from_sid = false;
1343 
1344 	rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1345 			    mode_from_sid, id_from_sid, &aclflag);
1346 
1347 	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1348 
1349 	if (ops->set_acl == NULL)
1350 		rc = -EOPNOTSUPP;
1351 
1352 	if (!rc) {
1353 		/* Set the security descriptor */
1354 		rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
1355 		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1356 	}
1357 	cifs_put_tlink(tlink);
1358 
1359 	kfree(pnntsd);
1360 	kfree(pntsd);
1361 	return rc;
1362 }
1363