• 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}, {__constant_cpu_to_le32(11)} };
42 /* group users */
43 static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
44 
45 static const struct cred *root_cred;
46 
47 static int
cifs_idmap_key_instantiate(struct key * key,struct key_preparsed_payload * prep)48 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
49 {
50 	char *payload;
51 
52 	/*
53 	 * If the payload is less than or equal to the size of a pointer, then
54 	 * an allocation here is wasteful. Just copy the data directly to the
55 	 * payload.value union member instead.
56 	 *
57 	 * With this however, you must check the datalen before trying to
58 	 * dereference payload.data!
59 	 */
60 	if (prep->datalen <= sizeof(key->payload)) {
61 		key->payload.value = 0;
62 		memcpy(&key->payload.value, prep->data, prep->datalen);
63 		key->datalen = prep->datalen;
64 		return 0;
65 	}
66 	payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
67 	if (!payload)
68 		return -ENOMEM;
69 
70 	key->payload.data = payload;
71 	key->datalen = prep->datalen;
72 	return 0;
73 }
74 
75 static inline void
cifs_idmap_key_destroy(struct key * key)76 cifs_idmap_key_destroy(struct key *key)
77 {
78 	if (key->datalen > sizeof(key->payload))
79 		kfree(key->payload.data);
80 }
81 
82 static struct key_type cifs_idmap_key_type = {
83 	.name        = "cifs.idmap",
84 	.instantiate = cifs_idmap_key_instantiate,
85 	.destroy     = cifs_idmap_key_destroy,
86 	.describe    = user_describe,
87 	.match       = user_match,
88 };
89 
90 static char *
sid_to_key_str(struct cifs_sid * sidptr,unsigned int type)91 sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
92 {
93 	int i, len;
94 	unsigned int saval;
95 	char *sidstr, *strptr;
96 	unsigned long long id_auth_val;
97 
98 	/* 3 bytes for prefix */
99 	sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
100 			 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
101 			 GFP_KERNEL);
102 	if (!sidstr)
103 		return sidstr;
104 
105 	strptr = sidstr;
106 	len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
107 			sidptr->revision);
108 	strptr += len;
109 
110 	/* The authority field is a single 48-bit number */
111 	id_auth_val = (unsigned long long)sidptr->authority[5];
112 	id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
113 	id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
114 	id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
115 	id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
116 	id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
117 
118 	/*
119 	 * MS-DTYP states that if the authority is >= 2^32, then it should be
120 	 * expressed as a hex value.
121 	 */
122 	if (id_auth_val <= UINT_MAX)
123 		len = sprintf(strptr, "-%llu", id_auth_val);
124 	else
125 		len = sprintf(strptr, "-0x%llx", id_auth_val);
126 
127 	strptr += len;
128 
129 	for (i = 0; i < sidptr->num_subauth; ++i) {
130 		saval = le32_to_cpu(sidptr->sub_auth[i]);
131 		len = sprintf(strptr, "-%u", saval);
132 		strptr += len;
133 	}
134 
135 	return sidstr;
136 }
137 
138 /*
139  * if the two SIDs (roughly equivalent to a UUID for a user or group) are
140  * the same returns zero, if they do not match returns non-zero.
141  */
142 static int
compare_sids(const struct cifs_sid * ctsid,const struct cifs_sid * cwsid)143 compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
144 {
145 	int i;
146 	int num_subauth, num_sat, num_saw;
147 
148 	if ((!ctsid) || (!cwsid))
149 		return 1;
150 
151 	/* compare the revision */
152 	if (ctsid->revision != cwsid->revision) {
153 		if (ctsid->revision > cwsid->revision)
154 			return 1;
155 		else
156 			return -1;
157 	}
158 
159 	/* compare all of the six auth values */
160 	for (i = 0; i < NUM_AUTHS; ++i) {
161 		if (ctsid->authority[i] != cwsid->authority[i]) {
162 			if (ctsid->authority[i] > cwsid->authority[i])
163 				return 1;
164 			else
165 				return -1;
166 		}
167 	}
168 
169 	/* compare all of the subauth values if any */
170 	num_sat = ctsid->num_subauth;
171 	num_saw = cwsid->num_subauth;
172 	num_subauth = num_sat < num_saw ? num_sat : num_saw;
173 	if (num_subauth) {
174 		for (i = 0; i < num_subauth; ++i) {
175 			if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
176 				if (le32_to_cpu(ctsid->sub_auth[i]) >
177 					le32_to_cpu(cwsid->sub_auth[i]))
178 					return 1;
179 				else
180 					return -1;
181 			}
182 		}
183 	}
184 
185 	return 0; /* sids compare/match */
186 }
187 
188 static void
cifs_copy_sid(struct cifs_sid * dst,const struct cifs_sid * src)189 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
190 {
191 	int i;
192 
193 	dst->revision = src->revision;
194 	dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
195 	for (i = 0; i < NUM_AUTHS; ++i)
196 		dst->authority[i] = src->authority[i];
197 	for (i = 0; i < dst->num_subauth; ++i)
198 		dst->sub_auth[i] = src->sub_auth[i];
199 }
200 
201 static int
id_to_sid(unsigned int cid,uint sidtype,struct cifs_sid * ssid)202 id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
203 {
204 	int rc;
205 	struct key *sidkey;
206 	struct cifs_sid *ksid;
207 	unsigned int ksid_size;
208 	char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
209 	const struct cred *saved_cred;
210 
211 	rc = snprintf(desc, sizeof(desc), "%ci:%u",
212 			sidtype == SIDOWNER ? 'o' : 'g', cid);
213 	if (rc >= sizeof(desc))
214 		return -EINVAL;
215 
216 	rc = 0;
217 	saved_cred = override_creds(root_cred);
218 	sidkey = request_key(&cifs_idmap_key_type, desc, "");
219 	if (IS_ERR(sidkey)) {
220 		rc = -EINVAL;
221 		cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
222 			 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
223 		goto out_revert_creds;
224 	} else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
225 		rc = -EIO;
226 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
227 			 __func__, sidkey->datalen);
228 		goto invalidate_key;
229 	}
230 
231 	/*
232 	 * A sid is usually too large to be embedded in payload.value, but if
233 	 * there are no subauthorities and the host has 8-byte pointers, then
234 	 * it could be.
235 	 */
236 	ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
237 		(struct cifs_sid *)&sidkey->payload.value :
238 		(struct cifs_sid *)sidkey->payload.data;
239 
240 	ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
241 	if (ksid_size > sidkey->datalen) {
242 		rc = -EIO;
243 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
244 			 __func__, sidkey->datalen, ksid_size);
245 		goto invalidate_key;
246 	}
247 
248 	cifs_copy_sid(ssid, ksid);
249 out_key_put:
250 	key_put(sidkey);
251 out_revert_creds:
252 	revert_creds(saved_cred);
253 	return rc;
254 
255 invalidate_key:
256 	key_invalidate(sidkey);
257 	goto out_key_put;
258 }
259 
260 static int
sid_to_id(struct cifs_sb_info * cifs_sb,struct cifs_sid * psid,struct cifs_fattr * fattr,uint sidtype)261 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
262 		struct cifs_fattr *fattr, uint sidtype)
263 {
264 	int rc;
265 	struct key *sidkey;
266 	char *sidstr;
267 	const struct cred *saved_cred;
268 	kuid_t fuid = cifs_sb->mnt_uid;
269 	kgid_t fgid = cifs_sb->mnt_gid;
270 
271 	/*
272 	 * If we have too many subauthorities, then something is really wrong.
273 	 * Just return an error.
274 	 */
275 	if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
276 		cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
277 			 __func__, psid->num_subauth);
278 		return -EIO;
279 	}
280 
281 	sidstr = sid_to_key_str(psid, sidtype);
282 	if (!sidstr)
283 		return -ENOMEM;
284 
285 	saved_cred = override_creds(root_cred);
286 	sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
287 	if (IS_ERR(sidkey)) {
288 		rc = -EINVAL;
289 		cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
290 			 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
291 		goto out_revert_creds;
292 	}
293 
294 	/*
295 	 * FIXME: Here we assume that uid_t and gid_t are same size. It's
296 	 * probably a safe assumption but might be better to check based on
297 	 * sidtype.
298 	 */
299 	BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
300 	if (sidkey->datalen != sizeof(uid_t)) {
301 		rc = -EIO;
302 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
303 			 __func__, sidkey->datalen);
304 		key_invalidate(sidkey);
305 		goto out_key_put;
306 	}
307 
308 	if (sidtype == SIDOWNER) {
309 		kuid_t uid;
310 		uid_t id;
311 		memcpy(&id, &sidkey->payload.value, sizeof(uid_t));
312 		uid = make_kuid(&init_user_ns, id);
313 		if (uid_valid(uid))
314 			fuid = uid;
315 	} else {
316 		kgid_t gid;
317 		gid_t id;
318 		memcpy(&id, &sidkey->payload.value, sizeof(gid_t));
319 		gid = make_kgid(&init_user_ns, id);
320 		if (gid_valid(gid))
321 			fgid = gid;
322 	}
323 
324 out_key_put:
325 	key_put(sidkey);
326 out_revert_creds:
327 	revert_creds(saved_cred);
328 	kfree(sidstr);
329 
330 	/*
331 	 * Note that we return 0 here unconditionally. If the mapping
332 	 * fails then we just fall back to using the mnt_uid/mnt_gid.
333 	 */
334 	if (sidtype == SIDOWNER)
335 		fattr->cf_uid = fuid;
336 	else
337 		fattr->cf_gid = fgid;
338 	return 0;
339 }
340 
341 int
init_cifs_idmap(void)342 init_cifs_idmap(void)
343 {
344 	struct cred *cred;
345 	struct key *keyring;
346 	int ret;
347 
348 	cifs_dbg(FYI, "Registering the %s key type\n",
349 		 cifs_idmap_key_type.name);
350 
351 	/* create an override credential set with a special thread keyring in
352 	 * which requests are cached
353 	 *
354 	 * this is used to prevent malicious redirections from being installed
355 	 * with add_key().
356 	 */
357 	cred = prepare_kernel_cred(NULL);
358 	if (!cred)
359 		return -ENOMEM;
360 
361 	keyring = keyring_alloc(".cifs_idmap",
362 				GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
363 				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
364 				KEY_USR_VIEW | KEY_USR_READ,
365 				KEY_ALLOC_NOT_IN_QUOTA, NULL);
366 	if (IS_ERR(keyring)) {
367 		ret = PTR_ERR(keyring);
368 		goto failed_put_cred;
369 	}
370 
371 	ret = register_key_type(&cifs_idmap_key_type);
372 	if (ret < 0)
373 		goto failed_put_key;
374 
375 	/* instruct request_key() to use this special keyring as a cache for
376 	 * the results it looks up */
377 	set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
378 	cred->thread_keyring = keyring;
379 	cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
380 	root_cred = cred;
381 
382 	cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
383 	return 0;
384 
385 failed_put_key:
386 	key_put(keyring);
387 failed_put_cred:
388 	put_cred(cred);
389 	return ret;
390 }
391 
392 void
exit_cifs_idmap(void)393 exit_cifs_idmap(void)
394 {
395 	key_revoke(root_cred->thread_keyring);
396 	unregister_key_type(&cifs_idmap_key_type);
397 	put_cred(root_cred);
398 	cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
399 }
400 
401 /* 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)402 static void copy_sec_desc(const struct cifs_ntsd *pntsd,
403 				struct cifs_ntsd *pnntsd, __u32 sidsoffset)
404 {
405 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
406 	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
407 
408 	/* copy security descriptor control portion */
409 	pnntsd->revision = pntsd->revision;
410 	pnntsd->type = pntsd->type;
411 	pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
412 	pnntsd->sacloffset = 0;
413 	pnntsd->osidoffset = cpu_to_le32(sidsoffset);
414 	pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
415 
416 	/* copy owner sid */
417 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
418 				le32_to_cpu(pntsd->osidoffset));
419 	nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
420 	cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
421 
422 	/* copy group sid */
423 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
424 				le32_to_cpu(pntsd->gsidoffset));
425 	ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
426 					sizeof(struct cifs_sid));
427 	cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
428 
429 	return;
430 }
431 
432 
433 /*
434    change posix mode to reflect permissions
435    pmode is the existing mode (we only want to overwrite part of this
436    bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
437 */
access_flags_to_mode(__le32 ace_flags,int type,umode_t * pmode,umode_t * pbits_to_set)438 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
439 				 umode_t *pbits_to_set)
440 {
441 	__u32 flags = le32_to_cpu(ace_flags);
442 	/* the order of ACEs is important.  The canonical order is to begin with
443 	   DENY entries followed by ALLOW, otherwise an allow entry could be
444 	   encountered first, making the subsequent deny entry like "dead code"
445 	   which would be superflous since Windows stops when a match is made
446 	   for the operation you are trying to perform for your user */
447 
448 	/* For deny ACEs we change the mask so that subsequent allow access
449 	   control entries do not turn on the bits we are denying */
450 	if (type == ACCESS_DENIED) {
451 		if (flags & GENERIC_ALL)
452 			*pbits_to_set &= ~S_IRWXUGO;
453 
454 		if ((flags & GENERIC_WRITE) ||
455 			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
456 			*pbits_to_set &= ~S_IWUGO;
457 		if ((flags & GENERIC_READ) ||
458 			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
459 			*pbits_to_set &= ~S_IRUGO;
460 		if ((flags & GENERIC_EXECUTE) ||
461 			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
462 			*pbits_to_set &= ~S_IXUGO;
463 		return;
464 	} else if (type != ACCESS_ALLOWED) {
465 		cifs_dbg(VFS, "unknown access control type %d\n", type);
466 		return;
467 	}
468 	/* else ACCESS_ALLOWED type */
469 
470 	if (flags & GENERIC_ALL) {
471 		*pmode |= (S_IRWXUGO & (*pbits_to_set));
472 		cifs_dbg(NOISY, "all perms\n");
473 		return;
474 	}
475 	if ((flags & GENERIC_WRITE) ||
476 			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
477 		*pmode |= (S_IWUGO & (*pbits_to_set));
478 	if ((flags & GENERIC_READ) ||
479 			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
480 		*pmode |= (S_IRUGO & (*pbits_to_set));
481 	if ((flags & GENERIC_EXECUTE) ||
482 			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
483 		*pmode |= (S_IXUGO & (*pbits_to_set));
484 
485 	cifs_dbg(NOISY, "access flags 0x%x mode now 0x%x\n", flags, *pmode);
486 	return;
487 }
488 
489 /*
490    Generate access flags to reflect permissions mode is the existing mode.
491    This function is called for every ACE in the DACL whose SID matches
492    with either owner or group or everyone.
493 */
494 
mode_to_access_flags(umode_t mode,umode_t bits_to_use,__u32 * pace_flags)495 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
496 				__u32 *pace_flags)
497 {
498 	/* reset access mask */
499 	*pace_flags = 0x0;
500 
501 	/* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
502 	mode &= bits_to_use;
503 
504 	/* check for R/W/X UGO since we do not know whose flags
505 	   is this but we have cleared all the bits sans RWX for
506 	   either user or group or other as per bits_to_use */
507 	if (mode & S_IRUGO)
508 		*pace_flags |= SET_FILE_READ_RIGHTS;
509 	if (mode & S_IWUGO)
510 		*pace_flags |= SET_FILE_WRITE_RIGHTS;
511 	if (mode & S_IXUGO)
512 		*pace_flags |= SET_FILE_EXEC_RIGHTS;
513 
514 	cifs_dbg(NOISY, "mode: 0x%x, access flags now 0x%x\n",
515 		 mode, *pace_flags);
516 	return;
517 }
518 
fill_ace_for_sid(struct cifs_ace * pntace,const struct cifs_sid * psid,__u64 nmode,umode_t bits)519 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
520 			const struct cifs_sid *psid, __u64 nmode, umode_t bits)
521 {
522 	int i;
523 	__u16 size = 0;
524 	__u32 access_req = 0;
525 
526 	pntace->type = ACCESS_ALLOWED;
527 	pntace->flags = 0x0;
528 	mode_to_access_flags(nmode, bits, &access_req);
529 	if (!access_req)
530 		access_req = SET_MINIMUM_RIGHTS;
531 	pntace->access_req = cpu_to_le32(access_req);
532 
533 	pntace->sid.revision = psid->revision;
534 	pntace->sid.num_subauth = psid->num_subauth;
535 	for (i = 0; i < NUM_AUTHS; i++)
536 		pntace->sid.authority[i] = psid->authority[i];
537 	for (i = 0; i < psid->num_subauth; i++)
538 		pntace->sid.sub_auth[i] = psid->sub_auth[i];
539 
540 	size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
541 	pntace->size = cpu_to_le16(size);
542 
543 	return size;
544 }
545 
546 
547 #ifdef CONFIG_CIFS_DEBUG2
dump_ace(struct cifs_ace * pace,char * end_of_acl)548 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
549 {
550 	int num_subauth;
551 
552 	/* validate that we do not go past end of acl */
553 
554 	if (le16_to_cpu(pace->size) < 16) {
555 		cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
556 		return;
557 	}
558 
559 	if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
560 		cifs_dbg(VFS, "ACL too small to parse ACE\n");
561 		return;
562 	}
563 
564 	num_subauth = pace->sid.num_subauth;
565 	if (num_subauth) {
566 		int i;
567 		cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
568 			 pace->sid.revision, pace->sid.num_subauth, pace->type,
569 			 pace->flags, le16_to_cpu(pace->size));
570 		for (i = 0; i < num_subauth; ++i) {
571 			cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
572 				 i, le32_to_cpu(pace->sid.sub_auth[i]));
573 		}
574 
575 		/* BB add length check to make sure that we do not have huge
576 			num auths and therefore go off the end */
577 	}
578 
579 	return;
580 }
581 #endif
582 
583 
parse_dacl(struct cifs_acl * pdacl,char * end_of_acl,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,struct cifs_fattr * fattr)584 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
585 		       struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
586 		       struct cifs_fattr *fattr)
587 {
588 	int i;
589 	int num_aces = 0;
590 	int acl_size;
591 	char *acl_base;
592 	struct cifs_ace **ppace;
593 
594 	/* BB need to add parm so we can store the SID BB */
595 
596 	if (!pdacl) {
597 		/* no DACL in the security descriptor, set
598 		   all the permissions for user/group/other */
599 		fattr->cf_mode |= S_IRWXUGO;
600 		return;
601 	}
602 
603 	/* validate that we do not go past end of acl */
604 	if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
605 		cifs_dbg(VFS, "ACL too small to parse DACL\n");
606 		return;
607 	}
608 
609 	cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
610 		 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
611 		 le32_to_cpu(pdacl->num_aces));
612 
613 	/* reset rwx permissions for user/group/other.
614 	   Also, if num_aces is 0 i.e. DACL has no ACEs,
615 	   user/group/other have no permissions */
616 	fattr->cf_mode &= ~(S_IRWXUGO);
617 
618 	acl_base = (char *)pdacl;
619 	acl_size = sizeof(struct cifs_acl);
620 
621 	num_aces = le32_to_cpu(pdacl->num_aces);
622 	if (num_aces > 0) {
623 		umode_t user_mask = S_IRWXU;
624 		umode_t group_mask = S_IRWXG;
625 		umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
626 
627 		if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
628 			return;
629 		ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
630 				GFP_KERNEL);
631 		if (!ppace)
632 			return;
633 
634 		for (i = 0; i < num_aces; ++i) {
635 			ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
636 #ifdef CONFIG_CIFS_DEBUG2
637 			dump_ace(ppace[i], end_of_acl);
638 #endif
639 			if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
640 				access_flags_to_mode(ppace[i]->access_req,
641 						     ppace[i]->type,
642 						     &fattr->cf_mode,
643 						     &user_mask);
644 			if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
645 				access_flags_to_mode(ppace[i]->access_req,
646 						     ppace[i]->type,
647 						     &fattr->cf_mode,
648 						     &group_mask);
649 			if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
650 				access_flags_to_mode(ppace[i]->access_req,
651 						     ppace[i]->type,
652 						     &fattr->cf_mode,
653 						     &other_mask);
654 			if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
655 				access_flags_to_mode(ppace[i]->access_req,
656 						     ppace[i]->type,
657 						     &fattr->cf_mode,
658 						     &other_mask);
659 
660 
661 /*			memcpy((void *)(&(cifscred->aces[i])),
662 				(void *)ppace[i],
663 				sizeof(struct cifs_ace)); */
664 
665 			acl_base = (char *)ppace[i];
666 			acl_size = le16_to_cpu(ppace[i]->size);
667 		}
668 
669 		kfree(ppace);
670 	}
671 
672 	return;
673 }
674 
675 
set_chmod_dacl(struct cifs_acl * pndacl,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,__u64 nmode)676 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
677 			struct cifs_sid *pgrpsid, __u64 nmode)
678 {
679 	u16 size = 0;
680 	struct cifs_acl *pnndacl;
681 
682 	pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
683 
684 	size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
685 					pownersid, nmode, S_IRWXU);
686 	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
687 					pgrpsid, nmode, S_IRWXG);
688 	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
689 					 &sid_everyone, nmode, S_IRWXO);
690 
691 	pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
692 	pndacl->num_aces = cpu_to_le32(3);
693 
694 	return 0;
695 }
696 
697 
parse_sid(struct cifs_sid * psid,char * end_of_acl)698 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
699 {
700 	/* BB need to add parm so we can store the SID BB */
701 
702 	/* validate that we do not go past end of ACL - sid must be at least 8
703 	   bytes long (assuming no sub-auths - e.g. the null SID */
704 	if (end_of_acl < (char *)psid + 8) {
705 		cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
706 		return -EINVAL;
707 	}
708 
709 #ifdef CONFIG_CIFS_DEBUG2
710 	if (psid->num_subauth) {
711 		int i;
712 		cifs_dbg(FYI, "SID revision %d num_auth %d\n",
713 			 psid->revision, psid->num_subauth);
714 
715 		for (i = 0; i < psid->num_subauth; i++) {
716 			cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
717 				 i, le32_to_cpu(psid->sub_auth[i]));
718 		}
719 
720 		/* BB add length check to make sure that we do not have huge
721 			num auths and therefore go off the end */
722 		cifs_dbg(FYI, "RID 0x%x\n",
723 			 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
724 	}
725 #endif
726 
727 	return 0;
728 }
729 
730 
731 /* 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)732 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
733 		struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr)
734 {
735 	int rc = 0;
736 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
737 	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
738 	char *end_of_acl = ((char *)pntsd) + acl_len;
739 	__u32 dacloffset;
740 
741 	if (pntsd == NULL)
742 		return -EIO;
743 
744 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
745 				le32_to_cpu(pntsd->osidoffset));
746 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
747 				le32_to_cpu(pntsd->gsidoffset));
748 	dacloffset = le32_to_cpu(pntsd->dacloffset);
749 	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
750 	cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
751 		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
752 		 le32_to_cpu(pntsd->gsidoffset),
753 		 le32_to_cpu(pntsd->sacloffset), dacloffset);
754 /*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
755 	rc = parse_sid(owner_sid_ptr, end_of_acl);
756 	if (rc) {
757 		cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
758 		return rc;
759 	}
760 	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
761 	if (rc) {
762 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
763 			 __func__, rc);
764 		return rc;
765 	}
766 
767 	rc = parse_sid(group_sid_ptr, end_of_acl);
768 	if (rc) {
769 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
770 			 __func__, rc);
771 		return rc;
772 	}
773 	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
774 	if (rc) {
775 		cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
776 			 __func__, rc);
777 		return rc;
778 	}
779 
780 	if (dacloffset)
781 		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
782 			   group_sid_ptr, fattr);
783 	else
784 		cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
785 
786 	return rc;
787 }
788 
789 /* 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,int * aclflag)790 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
791 	__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag)
792 {
793 	int rc = 0;
794 	__u32 dacloffset;
795 	__u32 ndacloffset;
796 	__u32 sidsoffset;
797 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
798 	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
799 	struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
800 	struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
801 
802 	if (nmode != NO_CHANGE_64) { /* chmod */
803 		owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
804 				le32_to_cpu(pntsd->osidoffset));
805 		group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
806 				le32_to_cpu(pntsd->gsidoffset));
807 		dacloffset = le32_to_cpu(pntsd->dacloffset);
808 		dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
809 		ndacloffset = sizeof(struct cifs_ntsd);
810 		ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
811 		ndacl_ptr->revision = dacl_ptr->revision;
812 		ndacl_ptr->size = 0;
813 		ndacl_ptr->num_aces = 0;
814 
815 		rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
816 					nmode);
817 		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
818 		/* copy sec desc control portion & owner and group sids */
819 		copy_sec_desc(pntsd, pnntsd, sidsoffset);
820 		*aclflag = CIFS_ACL_DACL;
821 	} else {
822 		memcpy(pnntsd, pntsd, secdesclen);
823 		if (uid_valid(uid)) { /* chown */
824 			uid_t id;
825 			owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
826 					le32_to_cpu(pnntsd->osidoffset));
827 			nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
828 								GFP_KERNEL);
829 			if (!nowner_sid_ptr)
830 				return -ENOMEM;
831 			id = from_kuid(&init_user_ns, uid);
832 			rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
833 			if (rc) {
834 				cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
835 					 __func__, rc, id);
836 				kfree(nowner_sid_ptr);
837 				return rc;
838 			}
839 			cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
840 			kfree(nowner_sid_ptr);
841 			*aclflag = CIFS_ACL_OWNER;
842 		}
843 		if (gid_valid(gid)) { /* chgrp */
844 			gid_t id;
845 			group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
846 					le32_to_cpu(pnntsd->gsidoffset));
847 			ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
848 								GFP_KERNEL);
849 			if (!ngroup_sid_ptr)
850 				return -ENOMEM;
851 			id = from_kgid(&init_user_ns, gid);
852 			rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
853 			if (rc) {
854 				cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
855 					 __func__, rc, id);
856 				kfree(ngroup_sid_ptr);
857 				return rc;
858 			}
859 			cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
860 			kfree(ngroup_sid_ptr);
861 			*aclflag = CIFS_ACL_GROUP;
862 		}
863 	}
864 
865 	return rc;
866 }
867 
get_cifs_acl_by_fid(struct cifs_sb_info * cifs_sb,__u16 fid,u32 * pacllen)868 static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
869 		__u16 fid, u32 *pacllen)
870 {
871 	struct cifs_ntsd *pntsd = NULL;
872 	unsigned int xid;
873 	int rc;
874 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
875 
876 	if (IS_ERR(tlink))
877 		return ERR_CAST(tlink);
878 
879 	xid = get_xid();
880 	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
881 	free_xid(xid);
882 
883 	cifs_put_tlink(tlink);
884 
885 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
886 	if (rc)
887 		return ERR_PTR(rc);
888 	return pntsd;
889 }
890 
get_cifs_acl_by_path(struct cifs_sb_info * cifs_sb,const char * path,u32 * pacllen)891 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
892 		const char *path, u32 *pacllen)
893 {
894 	struct cifs_ntsd *pntsd = NULL;
895 	int oplock = 0;
896 	unsigned int xid;
897 	int rc, create_options = 0;
898 	__u16 fid;
899 	struct cifs_tcon *tcon;
900 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
901 
902 	if (IS_ERR(tlink))
903 		return ERR_CAST(tlink);
904 
905 	tcon = tlink_tcon(tlink);
906 	xid = get_xid();
907 
908 	if (backup_cred(cifs_sb))
909 		create_options |= CREATE_OPEN_BACKUP_INTENT;
910 
911 	rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
912 			create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
913 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
914 	if (!rc) {
915 		rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
916 		CIFSSMBClose(xid, tcon, fid);
917 	}
918 
919 	cifs_put_tlink(tlink);
920 	free_xid(xid);
921 
922 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
923 	if (rc)
924 		return ERR_PTR(rc);
925 	return pntsd;
926 }
927 
928 /* Retrieve an ACL from the server */
get_cifs_acl(struct cifs_sb_info * cifs_sb,struct inode * inode,const char * path,u32 * pacllen)929 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
930 				      struct inode *inode, const char *path,
931 				      u32 *pacllen)
932 {
933 	struct cifs_ntsd *pntsd = NULL;
934 	struct cifsFileInfo *open_file = NULL;
935 
936 	if (inode)
937 		open_file = find_readable_file(CIFS_I(inode), true);
938 	if (!open_file)
939 		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
940 
941 	pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->fid.netfid, pacllen);
942 	cifsFileInfo_put(open_file);
943 	return pntsd;
944 }
945 
946  /* Set an ACL on the server */
set_cifs_acl(struct cifs_ntsd * pnntsd,__u32 acllen,struct inode * inode,const char * path,int aclflag)947 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
948 			struct inode *inode, const char *path, int aclflag)
949 {
950 	int oplock = 0;
951 	unsigned int xid;
952 	int rc, access_flags, create_options = 0;
953 	__u16 fid;
954 	struct cifs_tcon *tcon;
955 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
956 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
957 
958 	if (IS_ERR(tlink))
959 		return PTR_ERR(tlink);
960 
961 	tcon = tlink_tcon(tlink);
962 	xid = get_xid();
963 
964 	if (backup_cred(cifs_sb))
965 		create_options |= CREATE_OPEN_BACKUP_INTENT;
966 
967 	if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
968 		access_flags = WRITE_OWNER;
969 	else
970 		access_flags = WRITE_DAC;
971 
972 	rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, access_flags,
973 			create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
974 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
975 	if (rc) {
976 		cifs_dbg(VFS, "Unable to open file to set ACL\n");
977 		goto out;
978 	}
979 
980 	rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen, aclflag);
981 	cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
982 
983 	CIFSSMBClose(xid, tcon, fid);
984 out:
985 	free_xid(xid);
986 	cifs_put_tlink(tlink);
987 	return rc;
988 }
989 
990 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
991 int
cifs_acl_to_fattr(struct cifs_sb_info * cifs_sb,struct cifs_fattr * fattr,struct inode * inode,const char * path,const __u16 * pfid)992 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
993 		  struct inode *inode, const char *path, const __u16 *pfid)
994 {
995 	struct cifs_ntsd *pntsd = NULL;
996 	u32 acllen = 0;
997 	int rc = 0;
998 
999 	cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1000 
1001 	if (pfid)
1002 		pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
1003 	else
1004 		pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
1005 
1006 	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1007 	if (IS_ERR(pntsd)) {
1008 		rc = PTR_ERR(pntsd);
1009 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1010 	} else {
1011 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr);
1012 		kfree(pntsd);
1013 		if (rc)
1014 			cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1015 	}
1016 
1017 	return rc;
1018 }
1019 
1020 /* Convert mode bits to an ACL so we can update the ACL on the server */
1021 int
id_mode_to_cifs_acl(struct inode * inode,const char * path,__u64 nmode,kuid_t uid,kgid_t gid)1022 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1023 			kuid_t uid, kgid_t gid)
1024 {
1025 	int rc = 0;
1026 	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1027 	__u32 secdesclen = 0;
1028 	struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1029 	struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1030 
1031 	cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1032 
1033 	/* Get the security descriptor */
1034 	pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
1035 	if (IS_ERR(pntsd)) {
1036 		rc = PTR_ERR(pntsd);
1037 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1038 		goto out;
1039 	}
1040 
1041 	/*
1042 	 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1043 	 * as chmod disables ACEs and set the security descriptor. Allocate
1044 	 * memory for the smb header, set security descriptor request security
1045 	 * descriptor parameters, and secuirty descriptor itself
1046 	 */
1047 	secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1048 	pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1049 	if (!pnntsd) {
1050 		kfree(pntsd);
1051 		return -ENOMEM;
1052 	}
1053 
1054 	rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1055 				&aclflag);
1056 
1057 	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1058 
1059 	if (!rc) {
1060 		/* Set the security descriptor */
1061 		rc = set_cifs_acl(pnntsd, secdesclen, inode, path, aclflag);
1062 		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1063 	}
1064 
1065 	kfree(pnntsd);
1066 	kfree(pntsd);
1067 out:
1068 	return rc;
1069 }
1070