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