• 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 /* group users */
43 static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
44 
45 /* S-1-22-1 Unmapped Unix users */
46 static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
47 		{cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
48 
49 /* S-1-22-2 Unmapped Unix groups */
50 static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
51 		{cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
52 
53 /*
54  * See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
55  */
56 
57 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
58 
59 /* S-1-5-88-1 Unix uid */
60 static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
61 	{cpu_to_le32(88),
62 	 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
63 
64 /* S-1-5-88-2 Unix gid */
65 static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
66 	{cpu_to_le32(88),
67 	 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
68 
69 /* S-1-5-88-3 Unix mode */
70 static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
71 	{cpu_to_le32(88),
72 	 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
73 
74 static const struct cred *root_cred;
75 
76 static int
cifs_idmap_key_instantiate(struct key * key,struct key_preparsed_payload * prep)77 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
78 {
79 	char *payload;
80 
81 	/*
82 	 * If the payload is less than or equal to the size of a pointer, then
83 	 * an allocation here is wasteful. Just copy the data directly to the
84 	 * payload.value union member instead.
85 	 *
86 	 * With this however, you must check the datalen before trying to
87 	 * dereference payload.data!
88 	 */
89 	if (prep->datalen <= sizeof(key->payload)) {
90 		key->payload.data[0] = NULL;
91 		memcpy(&key->payload, prep->data, prep->datalen);
92 	} else {
93 		payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
94 		if (!payload)
95 			return -ENOMEM;
96 		key->payload.data[0] = payload;
97 	}
98 
99 	key->datalen = prep->datalen;
100 	return 0;
101 }
102 
103 static inline void
cifs_idmap_key_destroy(struct key * key)104 cifs_idmap_key_destroy(struct key *key)
105 {
106 	if (key->datalen > sizeof(key->payload))
107 		kfree(key->payload.data[0]);
108 }
109 
110 static struct key_type cifs_idmap_key_type = {
111 	.name        = "cifs.idmap",
112 	.instantiate = cifs_idmap_key_instantiate,
113 	.destroy     = cifs_idmap_key_destroy,
114 	.describe    = user_describe,
115 };
116 
117 static char *
sid_to_key_str(struct cifs_sid * sidptr,unsigned int type)118 sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
119 {
120 	int i, len;
121 	unsigned int saval;
122 	char *sidstr, *strptr;
123 	unsigned long long id_auth_val;
124 
125 	/* 3 bytes for prefix */
126 	sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
127 			 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
128 			 GFP_KERNEL);
129 	if (!sidstr)
130 		return sidstr;
131 
132 	strptr = sidstr;
133 	len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
134 			sidptr->revision);
135 	strptr += len;
136 
137 	/* The authority field is a single 48-bit number */
138 	id_auth_val = (unsigned long long)sidptr->authority[5];
139 	id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
140 	id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
141 	id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
142 	id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
143 	id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
144 
145 	/*
146 	 * MS-DTYP states that if the authority is >= 2^32, then it should be
147 	 * expressed as a hex value.
148 	 */
149 	if (id_auth_val <= UINT_MAX)
150 		len = sprintf(strptr, "-%llu", id_auth_val);
151 	else
152 		len = sprintf(strptr, "-0x%llx", id_auth_val);
153 
154 	strptr += len;
155 
156 	for (i = 0; i < sidptr->num_subauth; ++i) {
157 		saval = le32_to_cpu(sidptr->sub_auth[i]);
158 		len = sprintf(strptr, "-%u", saval);
159 		strptr += len;
160 	}
161 
162 	return sidstr;
163 }
164 
165 /*
166  * if the two SIDs (roughly equivalent to a UUID for a user or group) are
167  * the same returns zero, if they do not match returns non-zero.
168  */
169 static int
compare_sids(const struct cifs_sid * ctsid,const struct cifs_sid * cwsid)170 compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
171 {
172 	int i;
173 	int num_subauth, num_sat, num_saw;
174 
175 	if ((!ctsid) || (!cwsid))
176 		return 1;
177 
178 	/* compare the revision */
179 	if (ctsid->revision != cwsid->revision) {
180 		if (ctsid->revision > cwsid->revision)
181 			return 1;
182 		else
183 			return -1;
184 	}
185 
186 	/* compare all of the six auth values */
187 	for (i = 0; i < NUM_AUTHS; ++i) {
188 		if (ctsid->authority[i] != cwsid->authority[i]) {
189 			if (ctsid->authority[i] > cwsid->authority[i])
190 				return 1;
191 			else
192 				return -1;
193 		}
194 	}
195 
196 	/* compare all of the subauth values if any */
197 	num_sat = ctsid->num_subauth;
198 	num_saw = cwsid->num_subauth;
199 	num_subauth = num_sat < num_saw ? num_sat : num_saw;
200 	if (num_subauth) {
201 		for (i = 0; i < num_subauth; ++i) {
202 			if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
203 				if (le32_to_cpu(ctsid->sub_auth[i]) >
204 					le32_to_cpu(cwsid->sub_auth[i]))
205 					return 1;
206 				else
207 					return -1;
208 			}
209 		}
210 	}
211 
212 	return 0; /* sids compare/match */
213 }
214 
215 static bool
is_well_known_sid(const struct cifs_sid * psid,uint32_t * puid,bool is_group)216 is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
217 {
218 	int i;
219 	int num_subauth;
220 	const struct cifs_sid *pwell_known_sid;
221 
222 	if (!psid || (puid == NULL))
223 		return false;
224 
225 	num_subauth = psid->num_subauth;
226 
227 	/* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
228 	if (num_subauth == 2) {
229 		if (is_group)
230 			pwell_known_sid = &sid_unix_groups;
231 		else
232 			pwell_known_sid = &sid_unix_users;
233 	} else if (num_subauth == 3) {
234 		if (is_group)
235 			pwell_known_sid = &sid_unix_NFS_groups;
236 		else
237 			pwell_known_sid = &sid_unix_NFS_users;
238 	} else
239 		return false;
240 
241 	/* compare the revision */
242 	if (psid->revision != pwell_known_sid->revision)
243 		return false;
244 
245 	/* compare all of the six auth values */
246 	for (i = 0; i < NUM_AUTHS; ++i) {
247 		if (psid->authority[i] != pwell_known_sid->authority[i]) {
248 			cifs_dbg(FYI, "auth %d did not match\n", i);
249 			return false;
250 		}
251 	}
252 
253 	if (num_subauth == 2) {
254 		if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
255 			return false;
256 
257 		*puid = le32_to_cpu(psid->sub_auth[1]);
258 	} else /* 3 subauths, ie Windows/Mac style */ {
259 		*puid = le32_to_cpu(psid->sub_auth[0]);
260 		if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
261 		    (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
262 			return false;
263 
264 		*puid = le32_to_cpu(psid->sub_auth[2]);
265 	}
266 
267 	cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
268 	return true; /* well known sid found, uid returned */
269 }
270 
271 static void
cifs_copy_sid(struct cifs_sid * dst,const struct cifs_sid * src)272 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
273 {
274 	int i;
275 
276 	dst->revision = src->revision;
277 	dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
278 	for (i = 0; i < NUM_AUTHS; ++i)
279 		dst->authority[i] = src->authority[i];
280 	for (i = 0; i < dst->num_subauth; ++i)
281 		dst->sub_auth[i] = src->sub_auth[i];
282 }
283 
284 static int
id_to_sid(unsigned int cid,uint sidtype,struct cifs_sid * ssid)285 id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
286 {
287 	int rc;
288 	struct key *sidkey;
289 	struct cifs_sid *ksid;
290 	unsigned int ksid_size;
291 	char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
292 	const struct cred *saved_cred;
293 
294 	rc = snprintf(desc, sizeof(desc), "%ci:%u",
295 			sidtype == SIDOWNER ? 'o' : 'g', cid);
296 	if (rc >= sizeof(desc))
297 		return -EINVAL;
298 
299 	rc = 0;
300 	saved_cred = override_creds(root_cred);
301 	sidkey = request_key(&cifs_idmap_key_type, desc, "");
302 	if (IS_ERR(sidkey)) {
303 		rc = -EINVAL;
304 		cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
305 			 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
306 		goto out_revert_creds;
307 	} else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
308 		rc = -EIO;
309 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
310 			 __func__, sidkey->datalen);
311 		goto invalidate_key;
312 	}
313 
314 	/*
315 	 * A sid is usually too large to be embedded in payload.value, but if
316 	 * there are no subauthorities and the host has 8-byte pointers, then
317 	 * it could be.
318 	 */
319 	ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
320 		(struct cifs_sid *)&sidkey->payload :
321 		(struct cifs_sid *)sidkey->payload.data[0];
322 
323 	ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
324 	if (ksid_size > sidkey->datalen) {
325 		rc = -EIO;
326 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
327 			 __func__, sidkey->datalen, ksid_size);
328 		goto invalidate_key;
329 	}
330 
331 	cifs_copy_sid(ssid, ksid);
332 out_key_put:
333 	key_put(sidkey);
334 out_revert_creds:
335 	revert_creds(saved_cred);
336 	return rc;
337 
338 invalidate_key:
339 	key_invalidate(sidkey);
340 	goto out_key_put;
341 }
342 
343 static int
sid_to_id(struct cifs_sb_info * cifs_sb,struct cifs_sid * psid,struct cifs_fattr * fattr,uint sidtype)344 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
345 		struct cifs_fattr *fattr, uint sidtype)
346 {
347 	int rc;
348 	struct key *sidkey;
349 	char *sidstr;
350 	const struct cred *saved_cred;
351 	kuid_t fuid = cifs_sb->mnt_uid;
352 	kgid_t fgid = cifs_sb->mnt_gid;
353 
354 	/*
355 	 * If we have too many subauthorities, then something is really wrong.
356 	 * Just return an error.
357 	 */
358 	if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
359 		cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
360 			 __func__, psid->num_subauth);
361 		return -EIO;
362 	}
363 
364 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) {
365 		uint32_t unix_id;
366 		bool is_group;
367 
368 		if (sidtype != SIDOWNER)
369 			is_group = true;
370 		else
371 			is_group = false;
372 
373 		if (is_well_known_sid(psid, &unix_id, is_group) == false)
374 			goto try_upcall_to_get_id;
375 
376 		if (is_group) {
377 			kgid_t gid;
378 			gid_t id;
379 
380 			id = (gid_t)unix_id;
381 			gid = make_kgid(&init_user_ns, id);
382 			if (gid_valid(gid)) {
383 				fgid = gid;
384 				goto got_valid_id;
385 			}
386 		} else {
387 			kuid_t uid;
388 			uid_t id;
389 
390 			id = (uid_t)unix_id;
391 			uid = make_kuid(&init_user_ns, id);
392 			if (uid_valid(uid)) {
393 				fuid = uid;
394 				goto got_valid_id;
395 			}
396 		}
397 		/* If unable to find uid/gid easily from SID try via upcall */
398 	}
399 
400 try_upcall_to_get_id:
401 	sidstr = sid_to_key_str(psid, sidtype);
402 	if (!sidstr)
403 		return -ENOMEM;
404 
405 	saved_cred = override_creds(root_cred);
406 	sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
407 	if (IS_ERR(sidkey)) {
408 		rc = -EINVAL;
409 		cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
410 			 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
411 		goto out_revert_creds;
412 	}
413 
414 	/*
415 	 * FIXME: Here we assume that uid_t and gid_t are same size. It's
416 	 * probably a safe assumption but might be better to check based on
417 	 * sidtype.
418 	 */
419 	BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
420 	if (sidkey->datalen != sizeof(uid_t)) {
421 		rc = -EIO;
422 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
423 			 __func__, sidkey->datalen);
424 		key_invalidate(sidkey);
425 		goto out_key_put;
426 	}
427 
428 	if (sidtype == SIDOWNER) {
429 		kuid_t uid;
430 		uid_t id;
431 		memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
432 		uid = make_kuid(&init_user_ns, id);
433 		if (uid_valid(uid))
434 			fuid = uid;
435 	} else {
436 		kgid_t gid;
437 		gid_t id;
438 		memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
439 		gid = make_kgid(&init_user_ns, id);
440 		if (gid_valid(gid))
441 			fgid = gid;
442 	}
443 
444 out_key_put:
445 	key_put(sidkey);
446 out_revert_creds:
447 	revert_creds(saved_cred);
448 	kfree(sidstr);
449 
450 	/*
451 	 * Note that we return 0 here unconditionally. If the mapping
452 	 * fails then we just fall back to using the mnt_uid/mnt_gid.
453 	 */
454 got_valid_id:
455 	if (sidtype == SIDOWNER)
456 		fattr->cf_uid = fuid;
457 	else
458 		fattr->cf_gid = fgid;
459 	return 0;
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 0x%x\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: 0x%x, 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 
807 
set_chmod_dacl(struct cifs_acl * pndacl,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,__u64 nmode,bool modefromsid)808 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
809 			struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
810 {
811 	u16 size = 0;
812 	u32 num_aces = 0;
813 	struct cifs_acl *pnndacl;
814 
815 	pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
816 
817 	if (modefromsid) {
818 		struct cifs_ace *pntace =
819 			(struct cifs_ace *)((char *)pnndacl + size);
820 		int i;
821 
822 		pntace->type = ACCESS_ALLOWED;
823 		pntace->flags = 0x0;
824 		pntace->access_req = 0;
825 		pntace->sid.num_subauth = 3;
826 		pntace->sid.revision = 1;
827 		for (i = 0; i < NUM_AUTHS; i++)
828 			pntace->sid.authority[i] =
829 				sid_unix_NFS_mode.authority[i];
830 		pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
831 		pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
832 		pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
833 
834 		/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
835 		pntace->size = cpu_to_le16(28);
836 		size += 28;
837 		num_aces++;
838 	}
839 
840 	size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
841 					pownersid, nmode, S_IRWXU);
842 	num_aces++;
843 	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
844 					pgrpsid, nmode, S_IRWXG);
845 	num_aces++;
846 	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
847 					 &sid_everyone, nmode, S_IRWXO);
848 	num_aces++;
849 
850 	pndacl->num_aces = cpu_to_le32(num_aces);
851 	pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
852 
853 	return 0;
854 }
855 
856 
parse_sid(struct cifs_sid * psid,char * end_of_acl)857 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
858 {
859 	/* BB need to add parm so we can store the SID BB */
860 
861 	/* validate that we do not go past end of ACL - sid must be at least 8
862 	   bytes long (assuming no sub-auths - e.g. the null SID */
863 	if (end_of_acl < (char *)psid + 8) {
864 		cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
865 		return -EINVAL;
866 	}
867 
868 #ifdef CONFIG_CIFS_DEBUG2
869 	if (psid->num_subauth) {
870 		int i;
871 		cifs_dbg(FYI, "SID revision %d num_auth %d\n",
872 			 psid->revision, psid->num_subauth);
873 
874 		for (i = 0; i < psid->num_subauth; i++) {
875 			cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
876 				 i, le32_to_cpu(psid->sub_auth[i]));
877 		}
878 
879 		/* BB add length check to make sure that we do not have huge
880 			num auths and therefore go off the end */
881 		cifs_dbg(FYI, "RID 0x%x\n",
882 			 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
883 	}
884 #endif
885 
886 	return 0;
887 }
888 
889 
890 /* 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)891 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
892 		struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
893 		bool get_mode_from_special_sid)
894 {
895 	int rc = 0;
896 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
897 	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
898 	char *end_of_acl = ((char *)pntsd) + acl_len;
899 	__u32 dacloffset;
900 
901 	if (pntsd == NULL)
902 		return -EIO;
903 
904 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
905 				le32_to_cpu(pntsd->osidoffset));
906 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
907 				le32_to_cpu(pntsd->gsidoffset));
908 	dacloffset = le32_to_cpu(pntsd->dacloffset);
909 	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
910 	cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
911 		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
912 		 le32_to_cpu(pntsd->gsidoffset),
913 		 le32_to_cpu(pntsd->sacloffset), dacloffset);
914 /*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
915 	rc = parse_sid(owner_sid_ptr, end_of_acl);
916 	if (rc) {
917 		cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
918 		return rc;
919 	}
920 	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
921 	if (rc) {
922 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
923 			 __func__, rc);
924 		return rc;
925 	}
926 
927 	rc = parse_sid(group_sid_ptr, end_of_acl);
928 	if (rc) {
929 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
930 			 __func__, rc);
931 		return rc;
932 	}
933 	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
934 	if (rc) {
935 		cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
936 			 __func__, rc);
937 		return rc;
938 	}
939 
940 	if (dacloffset)
941 		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
942 			   group_sid_ptr, fattr, get_mode_from_special_sid);
943 	else
944 		cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
945 
946 	return rc;
947 }
948 
949 /* 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,int * aclflag)950 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
951 	__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid,
952 	bool mode_from_sid, int *aclflag)
953 {
954 	int rc = 0;
955 	__u32 dacloffset;
956 	__u32 ndacloffset;
957 	__u32 sidsoffset;
958 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
959 	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
960 	struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
961 	struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
962 
963 	if (nmode != NO_CHANGE_64) { /* chmod */
964 		owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
965 				le32_to_cpu(pntsd->osidoffset));
966 		group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
967 				le32_to_cpu(pntsd->gsidoffset));
968 		dacloffset = le32_to_cpu(pntsd->dacloffset);
969 		dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
970 		ndacloffset = sizeof(struct cifs_ntsd);
971 		ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
972 		ndacl_ptr->revision = dacl_ptr->revision;
973 		ndacl_ptr->size = 0;
974 		ndacl_ptr->num_aces = 0;
975 
976 		rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
977 				    nmode, mode_from_sid);
978 		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
979 		/* copy sec desc control portion & owner and group sids */
980 		copy_sec_desc(pntsd, pnntsd, sidsoffset);
981 		*aclflag = CIFS_ACL_DACL;
982 	} else {
983 		memcpy(pnntsd, pntsd, secdesclen);
984 		if (uid_valid(uid)) { /* chown */
985 			uid_t id;
986 			owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
987 					le32_to_cpu(pnntsd->osidoffset));
988 			nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
989 								GFP_KERNEL);
990 			if (!nowner_sid_ptr)
991 				return -ENOMEM;
992 			id = from_kuid(&init_user_ns, uid);
993 			rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
994 			if (rc) {
995 				cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
996 					 __func__, rc, id);
997 				kfree(nowner_sid_ptr);
998 				return rc;
999 			}
1000 			cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
1001 			kfree(nowner_sid_ptr);
1002 			*aclflag = CIFS_ACL_OWNER;
1003 		}
1004 		if (gid_valid(gid)) { /* chgrp */
1005 			gid_t id;
1006 			group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1007 					le32_to_cpu(pnntsd->gsidoffset));
1008 			ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1009 								GFP_KERNEL);
1010 			if (!ngroup_sid_ptr)
1011 				return -ENOMEM;
1012 			id = from_kgid(&init_user_ns, gid);
1013 			rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1014 			if (rc) {
1015 				cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1016 					 __func__, rc, id);
1017 				kfree(ngroup_sid_ptr);
1018 				return rc;
1019 			}
1020 			cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
1021 			kfree(ngroup_sid_ptr);
1022 			*aclflag = CIFS_ACL_GROUP;
1023 		}
1024 	}
1025 
1026 	return rc;
1027 }
1028 
get_cifs_acl_by_fid(struct cifs_sb_info * cifs_sb,const struct cifs_fid * cifsfid,u32 * pacllen)1029 struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1030 		const struct cifs_fid *cifsfid, u32 *pacllen)
1031 {
1032 	struct cifs_ntsd *pntsd = NULL;
1033 	unsigned int xid;
1034 	int rc;
1035 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1036 
1037 	if (IS_ERR(tlink))
1038 		return ERR_CAST(tlink);
1039 
1040 	xid = get_xid();
1041 	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1042 				pacllen);
1043 	free_xid(xid);
1044 
1045 	cifs_put_tlink(tlink);
1046 
1047 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1048 	if (rc)
1049 		return ERR_PTR(rc);
1050 	return pntsd;
1051 }
1052 
get_cifs_acl_by_path(struct cifs_sb_info * cifs_sb,const char * path,u32 * pacllen)1053 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1054 		const char *path, u32 *pacllen)
1055 {
1056 	struct cifs_ntsd *pntsd = NULL;
1057 	int oplock = 0;
1058 	unsigned int xid;
1059 	int rc, create_options = 0;
1060 	struct cifs_tcon *tcon;
1061 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1062 	struct cifs_fid fid;
1063 	struct cifs_open_parms oparms;
1064 
1065 	if (IS_ERR(tlink))
1066 		return ERR_CAST(tlink);
1067 
1068 	tcon = tlink_tcon(tlink);
1069 	xid = get_xid();
1070 
1071 	if (backup_cred(cifs_sb))
1072 		create_options |= CREATE_OPEN_BACKUP_INTENT;
1073 
1074 	oparms.tcon = tcon;
1075 	oparms.cifs_sb = cifs_sb;
1076 	oparms.desired_access = READ_CONTROL;
1077 	oparms.create_options = create_options;
1078 	oparms.disposition = FILE_OPEN;
1079 	oparms.path = path;
1080 	oparms.fid = &fid;
1081 	oparms.reconnect = false;
1082 
1083 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1084 	if (!rc) {
1085 		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1086 		CIFSSMBClose(xid, tcon, fid.netfid);
1087 	}
1088 
1089 	cifs_put_tlink(tlink);
1090 	free_xid(xid);
1091 
1092 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1093 	if (rc)
1094 		return ERR_PTR(rc);
1095 	return pntsd;
1096 }
1097 
1098 /* Retrieve an ACL from the server */
get_cifs_acl(struct cifs_sb_info * cifs_sb,struct inode * inode,const char * path,u32 * pacllen)1099 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1100 				      struct inode *inode, const char *path,
1101 				      u32 *pacllen)
1102 {
1103 	struct cifs_ntsd *pntsd = NULL;
1104 	struct cifsFileInfo *open_file = NULL;
1105 
1106 	if (inode)
1107 		open_file = find_readable_file(CIFS_I(inode), true);
1108 	if (!open_file)
1109 		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1110 
1111 	pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
1112 	cifsFileInfo_put(open_file);
1113 	return pntsd;
1114 }
1115 
1116  /* Set an ACL on the server */
set_cifs_acl(struct cifs_ntsd * pnntsd,__u32 acllen,struct inode * inode,const char * path,int aclflag)1117 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1118 			struct inode *inode, const char *path, int aclflag)
1119 {
1120 	int oplock = 0;
1121 	unsigned int xid;
1122 	int rc, access_flags, create_options = 0;
1123 	struct cifs_tcon *tcon;
1124 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1125 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1126 	struct cifs_fid fid;
1127 	struct cifs_open_parms oparms;
1128 
1129 	if (IS_ERR(tlink))
1130 		return PTR_ERR(tlink);
1131 
1132 	tcon = tlink_tcon(tlink);
1133 	xid = get_xid();
1134 
1135 	if (backup_cred(cifs_sb))
1136 		create_options |= CREATE_OPEN_BACKUP_INTENT;
1137 
1138 	if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1139 		access_flags = WRITE_OWNER;
1140 	else
1141 		access_flags = WRITE_DAC;
1142 
1143 	oparms.tcon = tcon;
1144 	oparms.cifs_sb = cifs_sb;
1145 	oparms.desired_access = access_flags;
1146 	oparms.create_options = create_options;
1147 	oparms.disposition = FILE_OPEN;
1148 	oparms.path = path;
1149 	oparms.fid = &fid;
1150 	oparms.reconnect = false;
1151 
1152 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1153 	if (rc) {
1154 		cifs_dbg(VFS, "Unable to open file to set ACL\n");
1155 		goto out;
1156 	}
1157 
1158 	rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1159 	cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1160 
1161 	CIFSSMBClose(xid, tcon, fid.netfid);
1162 out:
1163 	free_xid(xid);
1164 	cifs_put_tlink(tlink);
1165 	return rc;
1166 }
1167 
1168 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1169 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)1170 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1171 		  struct inode *inode, bool mode_from_special_sid,
1172 		  const char *path, const struct cifs_fid *pfid)
1173 {
1174 	struct cifs_ntsd *pntsd = NULL;
1175 	u32 acllen = 0;
1176 	int rc = 0;
1177 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1178 	struct smb_version_operations *ops;
1179 
1180 	cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1181 
1182 	if (IS_ERR(tlink))
1183 		return PTR_ERR(tlink);
1184 
1185 	ops = tlink_tcon(tlink)->ses->server->ops;
1186 
1187 	if (pfid && (ops->get_acl_by_fid))
1188 		pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
1189 	else if (ops->get_acl)
1190 		pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
1191 	else {
1192 		cifs_put_tlink(tlink);
1193 		return -EOPNOTSUPP;
1194 	}
1195 	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1196 	if (IS_ERR(pntsd)) {
1197 		rc = PTR_ERR(pntsd);
1198 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1199 	} else if (mode_from_special_sid) {
1200 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1201 	} else {
1202 		/* get approximated mode from ACL */
1203 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1204 		kfree(pntsd);
1205 		if (rc)
1206 			cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1207 	}
1208 
1209 	cifs_put_tlink(tlink);
1210 
1211 	return rc;
1212 }
1213 
1214 /* Convert mode bits to an ACL so we can update the ACL on the server */
1215 int
id_mode_to_cifs_acl(struct inode * inode,const char * path,__u64 nmode,kuid_t uid,kgid_t gid)1216 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1217 			kuid_t uid, kgid_t gid)
1218 {
1219 	int rc = 0;
1220 	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1221 	__u32 secdesclen = 0;
1222 	struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1223 	struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1224 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1225 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1226 	struct smb_version_operations *ops;
1227 	bool mode_from_sid;
1228 
1229 	if (IS_ERR(tlink))
1230 		return PTR_ERR(tlink);
1231 
1232 	ops = tlink_tcon(tlink)->ses->server->ops;
1233 
1234 	cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1235 
1236 	/* Get the security descriptor */
1237 
1238 	if (ops->get_acl == NULL) {
1239 		cifs_put_tlink(tlink);
1240 		return -EOPNOTSUPP;
1241 	}
1242 
1243 	pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
1244 	if (IS_ERR(pntsd)) {
1245 		rc = PTR_ERR(pntsd);
1246 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1247 		cifs_put_tlink(tlink);
1248 		return rc;
1249 	}
1250 
1251 	/*
1252 	 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1253 	 * as chmod disables ACEs and set the security descriptor. Allocate
1254 	 * memory for the smb header, set security descriptor request security
1255 	 * descriptor parameters, and secuirty descriptor itself
1256 	 */
1257 	secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1258 	pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1259 	if (!pnntsd) {
1260 		kfree(pntsd);
1261 		cifs_put_tlink(tlink);
1262 		return -ENOMEM;
1263 	}
1264 
1265 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1266 		mode_from_sid = true;
1267 	else
1268 		mode_from_sid = false;
1269 
1270 	rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1271 			    mode_from_sid, &aclflag);
1272 
1273 	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1274 
1275 	if (ops->set_acl == NULL)
1276 		rc = -EOPNOTSUPP;
1277 
1278 	if (!rc) {
1279 		/* Set the security descriptor */
1280 		rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
1281 		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1282 	}
1283 	cifs_put_tlink(tlink);
1284 
1285 	kfree(pnntsd);
1286 	kfree(pntsd);
1287 	return rc;
1288 }
1289