Linux Audio

Check our new training course

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