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 
704 
parse_dacl(struct cifs_acl * pdacl,char * end_of_acl,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,struct cifs_fattr * fattr)705 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
706 		       struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
707 		       struct cifs_fattr *fattr)
708 {
709 	int i;
710 	int num_aces = 0;
711 	int acl_size;
712 	char *acl_base;
713 	struct cifs_ace **ppace;
714 
715 	/* BB need to add parm so we can store the SID BB */
716 
717 	if (!pdacl) {
718 		/* no DACL in the security descriptor, set
719 		   all the permissions for user/group/other */
720 		fattr->cf_mode |= S_IRWXUGO;
721 		return;
722 	}
723 
724 	/* validate that we do not go past end of acl */
725 	if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
726 		cifs_dbg(VFS, "ACL too small to parse DACL\n");
727 		return;
728 	}
729 
730 	cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
731 		 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
732 		 le32_to_cpu(pdacl->num_aces));
733 
734 	/* reset rwx permissions for user/group/other.
735 	   Also, if num_aces is 0 i.e. DACL has no ACEs,
736 	   user/group/other have no permissions */
737 	fattr->cf_mode &= ~(S_IRWXUGO);
738 
739 	acl_base = (char *)pdacl;
740 	acl_size = sizeof(struct cifs_acl);
741 
742 	num_aces = le32_to_cpu(pdacl->num_aces);
743 	if (num_aces > 0) {
744 		umode_t user_mask = S_IRWXU;
745 		umode_t group_mask = S_IRWXG;
746 		umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
747 
748 		if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
749 			return;
750 		ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
751 				      GFP_KERNEL);
752 		if (!ppace)
753 			return;
754 
755 		for (i = 0; i < num_aces; ++i) {
756 			ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
757 #ifdef CONFIG_CIFS_DEBUG2
758 			dump_ace(ppace[i], end_of_acl);
759 #endif
760 			if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
761 				access_flags_to_mode(ppace[i]->access_req,
762 						     ppace[i]->type,
763 						     &fattr->cf_mode,
764 						     &user_mask);
765 			if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
766 				access_flags_to_mode(ppace[i]->access_req,
767 						     ppace[i]->type,
768 						     &fattr->cf_mode,
769 						     &group_mask);
770 			if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
771 				access_flags_to_mode(ppace[i]->access_req,
772 						     ppace[i]->type,
773 						     &fattr->cf_mode,
774 						     &other_mask);
775 			if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
776 				access_flags_to_mode(ppace[i]->access_req,
777 						     ppace[i]->type,
778 						     &fattr->cf_mode,
779 						     &other_mask);
780 
781 
782 /*			memcpy((void *)(&(cifscred->aces[i])),
783 				(void *)ppace[i],
784 				sizeof(struct cifs_ace)); */
785 
786 			acl_base = (char *)ppace[i];
787 			acl_size = le16_to_cpu(ppace[i]->size);
788 		}
789 
790 		kfree(ppace);
791 	}
792 
793 	return;
794 }
795 
796 
set_chmod_dacl(struct cifs_acl * pndacl,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,__u64 nmode)797 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
798 			struct cifs_sid *pgrpsid, __u64 nmode)
799 {
800 	u16 size = 0;
801 	struct cifs_acl *pnndacl;
802 
803 	pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
804 
805 	size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
806 					pownersid, nmode, S_IRWXU);
807 	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
808 					pgrpsid, nmode, S_IRWXG);
809 	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
810 					 &sid_everyone, nmode, S_IRWXO);
811 
812 	pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
813 	pndacl->num_aces = cpu_to_le32(3);
814 
815 	return 0;
816 }
817 
818 
parse_sid(struct cifs_sid * psid,char * end_of_acl)819 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
820 {
821 	/* BB need to add parm so we can store the SID BB */
822 
823 	/* validate that we do not go past end of ACL - sid must be at least 8
824 	   bytes long (assuming no sub-auths - e.g. the null SID */
825 	if (end_of_acl < (char *)psid + 8) {
826 		cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
827 		return -EINVAL;
828 	}
829 
830 #ifdef CONFIG_CIFS_DEBUG2
831 	if (psid->num_subauth) {
832 		int i;
833 		cifs_dbg(FYI, "SID revision %d num_auth %d\n",
834 			 psid->revision, psid->num_subauth);
835 
836 		for (i = 0; i < psid->num_subauth; i++) {
837 			cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
838 				 i, le32_to_cpu(psid->sub_auth[i]));
839 		}
840 
841 		/* BB add length check to make sure that we do not have huge
842 			num auths and therefore go off the end */
843 		cifs_dbg(FYI, "RID 0x%x\n",
844 			 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
845 	}
846 #endif
847 
848 	return 0;
849 }
850 
851 
852 /* 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)853 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
854 		struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr)
855 {
856 	int rc = 0;
857 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
858 	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
859 	char *end_of_acl = ((char *)pntsd) + acl_len;
860 	__u32 dacloffset;
861 
862 	if (pntsd == NULL)
863 		return -EIO;
864 
865 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
866 				le32_to_cpu(pntsd->osidoffset));
867 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
868 				le32_to_cpu(pntsd->gsidoffset));
869 	dacloffset = le32_to_cpu(pntsd->dacloffset);
870 	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
871 	cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
872 		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
873 		 le32_to_cpu(pntsd->gsidoffset),
874 		 le32_to_cpu(pntsd->sacloffset), dacloffset);
875 /*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
876 	rc = parse_sid(owner_sid_ptr, end_of_acl);
877 	if (rc) {
878 		cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
879 		return rc;
880 	}
881 	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
882 	if (rc) {
883 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
884 			 __func__, rc);
885 		return rc;
886 	}
887 
888 	rc = parse_sid(group_sid_ptr, end_of_acl);
889 	if (rc) {
890 		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
891 			 __func__, rc);
892 		return rc;
893 	}
894 	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
895 	if (rc) {
896 		cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
897 			 __func__, rc);
898 		return rc;
899 	}
900 
901 	if (dacloffset)
902 		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
903 			   group_sid_ptr, fattr);
904 	else
905 		cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
906 
907 	return rc;
908 }
909 
910 /* 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)911 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
912 	__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag)
913 {
914 	int rc = 0;
915 	__u32 dacloffset;
916 	__u32 ndacloffset;
917 	__u32 sidsoffset;
918 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
919 	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
920 	struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
921 	struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
922 
923 	if (nmode != NO_CHANGE_64) { /* chmod */
924 		owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
925 				le32_to_cpu(pntsd->osidoffset));
926 		group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
927 				le32_to_cpu(pntsd->gsidoffset));
928 		dacloffset = le32_to_cpu(pntsd->dacloffset);
929 		dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
930 		ndacloffset = sizeof(struct cifs_ntsd);
931 		ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
932 		ndacl_ptr->revision = dacl_ptr->revision;
933 		ndacl_ptr->size = 0;
934 		ndacl_ptr->num_aces = 0;
935 
936 		rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
937 					nmode);
938 		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
939 		/* copy sec desc control portion & owner and group sids */
940 		copy_sec_desc(pntsd, pnntsd, sidsoffset);
941 		*aclflag = CIFS_ACL_DACL;
942 	} else {
943 		memcpy(pnntsd, pntsd, secdesclen);
944 		if (uid_valid(uid)) { /* chown */
945 			uid_t id;
946 			owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
947 					le32_to_cpu(pnntsd->osidoffset));
948 			nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
949 								GFP_KERNEL);
950 			if (!nowner_sid_ptr)
951 				return -ENOMEM;
952 			id = from_kuid(&init_user_ns, uid);
953 			rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
954 			if (rc) {
955 				cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
956 					 __func__, rc, id);
957 				kfree(nowner_sid_ptr);
958 				return rc;
959 			}
960 			cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
961 			kfree(nowner_sid_ptr);
962 			*aclflag = CIFS_ACL_OWNER;
963 		}
964 		if (gid_valid(gid)) { /* chgrp */
965 			gid_t id;
966 			group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
967 					le32_to_cpu(pnntsd->gsidoffset));
968 			ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
969 								GFP_KERNEL);
970 			if (!ngroup_sid_ptr)
971 				return -ENOMEM;
972 			id = from_kgid(&init_user_ns, gid);
973 			rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
974 			if (rc) {
975 				cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
976 					 __func__, rc, id);
977 				kfree(ngroup_sid_ptr);
978 				return rc;
979 			}
980 			cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
981 			kfree(ngroup_sid_ptr);
982 			*aclflag = CIFS_ACL_GROUP;
983 		}
984 	}
985 
986 	return rc;
987 }
988 
get_cifs_acl_by_fid(struct cifs_sb_info * cifs_sb,const struct cifs_fid * cifsfid,u32 * pacllen)989 struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
990 		const struct cifs_fid *cifsfid, u32 *pacllen)
991 {
992 	struct cifs_ntsd *pntsd = NULL;
993 	unsigned int xid;
994 	int rc;
995 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
996 
997 	if (IS_ERR(tlink))
998 		return ERR_CAST(tlink);
999 
1000 	xid = get_xid();
1001 	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1002 				pacllen);
1003 	free_xid(xid);
1004 
1005 	cifs_put_tlink(tlink);
1006 
1007 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1008 	if (rc)
1009 		return ERR_PTR(rc);
1010 	return pntsd;
1011 }
1012 
get_cifs_acl_by_path(struct cifs_sb_info * cifs_sb,const char * path,u32 * pacllen)1013 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1014 		const char *path, u32 *pacllen)
1015 {
1016 	struct cifs_ntsd *pntsd = NULL;
1017 	int oplock = 0;
1018 	unsigned int xid;
1019 	int rc, create_options = 0;
1020 	struct cifs_tcon *tcon;
1021 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1022 	struct cifs_fid fid;
1023 	struct cifs_open_parms oparms;
1024 
1025 	if (IS_ERR(tlink))
1026 		return ERR_CAST(tlink);
1027 
1028 	tcon = tlink_tcon(tlink);
1029 	xid = get_xid();
1030 
1031 	if (backup_cred(cifs_sb))
1032 		create_options |= CREATE_OPEN_BACKUP_INTENT;
1033 
1034 	oparms.tcon = tcon;
1035 	oparms.cifs_sb = cifs_sb;
1036 	oparms.desired_access = READ_CONTROL;
1037 	oparms.create_options = create_options;
1038 	oparms.disposition = FILE_OPEN;
1039 	oparms.path = path;
1040 	oparms.fid = &fid;
1041 	oparms.reconnect = false;
1042 
1043 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1044 	if (!rc) {
1045 		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1046 		CIFSSMBClose(xid, tcon, fid.netfid);
1047 	}
1048 
1049 	cifs_put_tlink(tlink);
1050 	free_xid(xid);
1051 
1052 	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1053 	if (rc)
1054 		return ERR_PTR(rc);
1055 	return pntsd;
1056 }
1057 
1058 /* Retrieve an ACL from the server */
get_cifs_acl(struct cifs_sb_info * cifs_sb,struct inode * inode,const char * path,u32 * pacllen)1059 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1060 				      struct inode *inode, const char *path,
1061 				      u32 *pacllen)
1062 {
1063 	struct cifs_ntsd *pntsd = NULL;
1064 	struct cifsFileInfo *open_file = NULL;
1065 
1066 	if (inode)
1067 		open_file = find_readable_file(CIFS_I(inode), true);
1068 	if (!open_file)
1069 		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1070 
1071 	pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
1072 	cifsFileInfo_put(open_file);
1073 	return pntsd;
1074 }
1075 
1076  /* Set an ACL on the server */
set_cifs_acl(struct cifs_ntsd * pnntsd,__u32 acllen,struct inode * inode,const char * path,int aclflag)1077 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1078 			struct inode *inode, const char *path, int aclflag)
1079 {
1080 	int oplock = 0;
1081 	unsigned int xid;
1082 	int rc, access_flags, create_options = 0;
1083 	struct cifs_tcon *tcon;
1084 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1085 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1086 	struct cifs_fid fid;
1087 	struct cifs_open_parms oparms;
1088 
1089 	if (IS_ERR(tlink))
1090 		return PTR_ERR(tlink);
1091 
1092 	tcon = tlink_tcon(tlink);
1093 	xid = get_xid();
1094 
1095 	if (backup_cred(cifs_sb))
1096 		create_options |= CREATE_OPEN_BACKUP_INTENT;
1097 
1098 	if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1099 		access_flags = WRITE_OWNER;
1100 	else
1101 		access_flags = WRITE_DAC;
1102 
1103 	oparms.tcon = tcon;
1104 	oparms.cifs_sb = cifs_sb;
1105 	oparms.desired_access = access_flags;
1106 	oparms.create_options = create_options;
1107 	oparms.disposition = FILE_OPEN;
1108 	oparms.path = path;
1109 	oparms.fid = &fid;
1110 	oparms.reconnect = false;
1111 
1112 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1113 	if (rc) {
1114 		cifs_dbg(VFS, "Unable to open file to set ACL\n");
1115 		goto out;
1116 	}
1117 
1118 	rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1119 	cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1120 
1121 	CIFSSMBClose(xid, tcon, fid.netfid);
1122 out:
1123 	free_xid(xid);
1124 	cifs_put_tlink(tlink);
1125 	return rc;
1126 }
1127 
1128 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1129 int
cifs_acl_to_fattr(struct cifs_sb_info * cifs_sb,struct cifs_fattr * fattr,struct inode * inode,const char * path,const struct cifs_fid * pfid)1130 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1131 		  struct inode *inode, const char *path,
1132 		  const struct cifs_fid *pfid)
1133 {
1134 	struct cifs_ntsd *pntsd = NULL;
1135 	u32 acllen = 0;
1136 	int rc = 0;
1137 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1138 	struct smb_version_operations *ops;
1139 
1140 	cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1141 
1142 	if (IS_ERR(tlink))
1143 		return PTR_ERR(tlink);
1144 
1145 	ops = tlink_tcon(tlink)->ses->server->ops;
1146 
1147 	if (pfid && (ops->get_acl_by_fid))
1148 		pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
1149 	else if (ops->get_acl)
1150 		pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
1151 	else {
1152 		cifs_put_tlink(tlink);
1153 		return -EOPNOTSUPP;
1154 	}
1155 	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1156 	if (IS_ERR(pntsd)) {
1157 		rc = PTR_ERR(pntsd);
1158 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1159 	} else {
1160 		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr);
1161 		kfree(pntsd);
1162 		if (rc)
1163 			cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1164 	}
1165 
1166 	cifs_put_tlink(tlink);
1167 
1168 	return rc;
1169 }
1170 
1171 /* Convert mode bits to an ACL so we can update the ACL on the server */
1172 int
id_mode_to_cifs_acl(struct inode * inode,const char * path,__u64 nmode,kuid_t uid,kgid_t gid)1173 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1174 			kuid_t uid, kgid_t gid)
1175 {
1176 	int rc = 0;
1177 	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1178 	__u32 secdesclen = 0;
1179 	struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1180 	struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1181 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1182 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1183 	struct smb_version_operations *ops;
1184 
1185 	if (IS_ERR(tlink))
1186 		return PTR_ERR(tlink);
1187 
1188 	ops = tlink_tcon(tlink)->ses->server->ops;
1189 
1190 	cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1191 
1192 	/* Get the security descriptor */
1193 
1194 	if (ops->get_acl == NULL) {
1195 		cifs_put_tlink(tlink);
1196 		return -EOPNOTSUPP;
1197 	}
1198 
1199 	pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
1200 	if (IS_ERR(pntsd)) {
1201 		rc = PTR_ERR(pntsd);
1202 		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1203 		cifs_put_tlink(tlink);
1204 		return rc;
1205 	}
1206 
1207 	/*
1208 	 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1209 	 * as chmod disables ACEs and set the security descriptor. Allocate
1210 	 * memory for the smb header, set security descriptor request security
1211 	 * descriptor parameters, and secuirty descriptor itself
1212 	 */
1213 	secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1214 	pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1215 	if (!pnntsd) {
1216 		kfree(pntsd);
1217 		cifs_put_tlink(tlink);
1218 		return -ENOMEM;
1219 	}
1220 
1221 	rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1222 				&aclflag);
1223 
1224 	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1225 
1226 	if (ops->set_acl == NULL)
1227 		rc = -EOPNOTSUPP;
1228 
1229 	if (!rc) {
1230 		/* Set the security descriptor */
1231 		rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
1232 		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1233 	}
1234 	cifs_put_tlink(tlink);
1235 
1236 	kfree(pnntsd);
1237 	kfree(pntsd);
1238 	return rc;
1239 }
1240