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}, {__constant_cpu_to_le32(11)} };
  42/* group users */
  43static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
  44
  45const struct cred *root_cred;
  46
  47static void
  48shrink_idmap_tree(struct rb_root *root, int nr_to_scan, int *nr_rem,
  49			int *nr_del)
  50{
  51	struct rb_node *node;
  52	struct rb_node *tmp;
  53	struct cifs_sid_id *psidid;
  54
  55	node = rb_first(root);
  56	while (node) {
  57		tmp = node;
  58		node = rb_next(tmp);
  59		psidid = rb_entry(tmp, struct cifs_sid_id, rbnode);
  60		if (nr_to_scan == 0 || *nr_del == nr_to_scan)
  61			++(*nr_rem);
  62		else {
  63			if (time_after(jiffies, psidid->time + SID_MAP_EXPIRE)
  64						&& psidid->refcount == 0) {
  65				rb_erase(tmp, root);
  66				++(*nr_del);
  67			} else
  68				++(*nr_rem);
  69		}
  70	}
  71}
  72
  73/*
  74 * Run idmap cache shrinker.
  75 */
  76static int
  77cifs_idmap_shrinker(struct shrinker *shrink, struct shrink_control *sc)
  78{
  79	int nr_to_scan = sc->nr_to_scan;
  80	int nr_del = 0;
  81	int nr_rem = 0;
  82	struct rb_root *root;
  83
  84	root = &uidtree;
  85	spin_lock(&siduidlock);
  86	shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
  87	spin_unlock(&siduidlock);
  88
  89	root = &gidtree;
  90	spin_lock(&sidgidlock);
  91	shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
  92	spin_unlock(&sidgidlock);
  93
  94	root = &siduidtree;
  95	spin_lock(&uidsidlock);
  96	shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
  97	spin_unlock(&uidsidlock);
  98
  99	root = &sidgidtree;
 100	spin_lock(&gidsidlock);
 101	shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
 102	spin_unlock(&gidsidlock);
 103
 104	return nr_rem;
 105}
 106
 107static void
 108sid_rb_insert(struct rb_root *root, unsigned long cid,
 109		struct cifs_sid_id **psidid, char *typestr)
 110{
 111	char *strptr;
 112	struct rb_node *node = root->rb_node;
 113	struct rb_node *parent = NULL;
 114	struct rb_node **linkto = &(root->rb_node);
 115	struct cifs_sid_id *lsidid;
 116
 117	while (node) {
 118		lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
 119		parent = node;
 120		if (cid > lsidid->id) {
 121			linkto = &(node->rb_left);
 122			node = node->rb_left;
 123		}
 124		if (cid < lsidid->id) {
 125			linkto = &(node->rb_right);
 126			node = node->rb_right;
 127		}
 128	}
 129
 130	(*psidid)->id = cid;
 131	(*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
 132	(*psidid)->refcount = 0;
 133
 134	sprintf((*psidid)->sidstr, "%s", typestr);
 135	strptr = (*psidid)->sidstr + strlen((*psidid)->sidstr);
 136	sprintf(strptr, "%ld", cid);
 137
 138	clear_bit(SID_ID_PENDING, &(*psidid)->state);
 139	clear_bit(SID_ID_MAPPED, &(*psidid)->state);
 140
 141	rb_link_node(&(*psidid)->rbnode, parent, linkto);
 142	rb_insert_color(&(*psidid)->rbnode, root);
 143}
 144
 145static struct cifs_sid_id *
 146sid_rb_search(struct rb_root *root, unsigned long cid)
 147{
 148	struct rb_node *node = root->rb_node;
 149	struct cifs_sid_id *lsidid;
 150
 151	while (node) {
 152		lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
 153		if (cid > lsidid->id)
 154			node = node->rb_left;
 155		else if (cid < lsidid->id)
 156			node = node->rb_right;
 157		else /* node found */
 158			return lsidid;
 159	}
 160
 161	return NULL;
 162}
 163
 164static struct shrinker cifs_shrinker = {
 165	.shrink = cifs_idmap_shrinker,
 166	.seeks = DEFAULT_SEEKS,
 167};
 168
 169static int
 170cifs_idmap_key_instantiate(struct key *key, const void *data, size_t datalen)
 171{
 172	char *payload;
 173
 174	payload = kmalloc(datalen, GFP_KERNEL);
 175	if (!payload)
 176		return -ENOMEM;
 177
 178	memcpy(payload, data, datalen);
 179	key->payload.data = payload;
 180	key->datalen = datalen;
 181	return 0;
 182}
 183
 184static inline void
 185cifs_idmap_key_destroy(struct key *key)
 186{
 187	kfree(key->payload.data);
 
 188}
 189
 190struct key_type cifs_idmap_key_type = {
 191	.name        = "cifs.idmap",
 192	.instantiate = cifs_idmap_key_instantiate,
 193	.destroy     = cifs_idmap_key_destroy,
 194	.describe    = user_describe,
 195	.match       = user_match,
 196};
 197
 198static void
 199sid_to_str(struct cifs_sid *sidptr, char *sidstr)
 200{
 201	int i;
 202	unsigned long saval;
 203	char *strptr;
 
 
 
 
 
 
 
 
 204
 205	strptr = sidstr;
 
 
 
 
 
 
 
 
 
 
 
 206
 207	sprintf(strptr, "%s", "S");
 208	strptr = sidstr + strlen(sidstr);
 209
 210	sprintf(strptr, "-%d", sidptr->revision);
 211	strptr = sidstr + strlen(sidstr);
 
 
 
 212
 213	for (i = 0; i < 6; ++i) {
 214		if (sidptr->authority[i]) {
 215			sprintf(strptr, "-%d", sidptr->authority[i]);
 216			strptr = sidstr + strlen(sidstr);
 217		}
 218	}
 219
 220	for (i = 0; i < sidptr->num_subauth; ++i) {
 221		saval = le32_to_cpu(sidptr->sub_auth[i]);
 222		sprintf(strptr, "-%ld", saval);
 223		strptr = sidstr + strlen(sidstr);
 224	}
 
 
 225}
 226
 227static void
 228id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
 229		struct cifs_sid_id **psidid, char *typestr)
 
 
 
 230{
 231	int rc;
 232	char *strptr;
 233	struct rb_node *node = root->rb_node;
 234	struct rb_node *parent = NULL;
 235	struct rb_node **linkto = &(root->rb_node);
 236	struct cifs_sid_id *lsidid;
 237
 238	while (node) {
 239		lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
 240		parent = node;
 241		rc = compare_sids(sidptr, &((lsidid)->sid));
 242		if (rc > 0) {
 243			linkto = &(node->rb_left);
 244			node = node->rb_left;
 245		} else if (rc < 0) {
 246			linkto = &(node->rb_right);
 247			node = node->rb_right;
 248		}
 249	}
 250
 251	memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid));
 252	(*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
 253	(*psidid)->refcount = 0;
 254
 255	sprintf((*psidid)->sidstr, "%s", typestr);
 256	strptr = (*psidid)->sidstr + strlen((*psidid)->sidstr);
 257	sid_to_str(&(*psidid)->sid, strptr);
 
 
 
 
 258
 259	clear_bit(SID_ID_PENDING, &(*psidid)->state);
 260	clear_bit(SID_ID_MAPPED, &(*psidid)->state);
 
 
 
 
 
 
 
 261
 262	rb_link_node(&(*psidid)->rbnode, parent, linkto);
 263	rb_insert_color(&(*psidid)->rbnode, root);
 264}
 265
 266static struct cifs_sid_id *
 267id_rb_search(struct rb_root *root, struct cifs_sid *sidptr)
 268{
 269	int rc;
 270	struct rb_node *node = root->rb_node;
 271	struct cifs_sid_id *lsidid;
 272
 273	while (node) {
 274		lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
 275		rc = compare_sids(sidptr, &((lsidid)->sid));
 276		if (rc > 0) {
 277			node = node->rb_left;
 278		} else if (rc < 0) {
 279			node = node->rb_right;
 280		} else /* node found */
 281			return lsidid;
 282	}
 283
 284	return NULL;
 285}
 286
 287static int
 288sidid_pending_wait(void *unused)
 289{
 290	schedule();
 291	return signal_pending(current) ? -ERESTARTSYS : 0;
 
 
 
 
 
 
 292}
 293
 294static int
 295id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
 296{
 297	int rc = 0;
 298	struct key *sidkey;
 
 
 
 299	const struct cred *saved_cred;
 300	struct cifs_sid *lsid;
 301	struct cifs_sid_id *psidid, *npsidid;
 302	struct rb_root *cidtree;
 303	spinlock_t *cidlock;
 304
 305	if (sidtype == SIDOWNER) {
 306		cidlock = &siduidlock;
 307		cidtree = &uidtree;
 308	} else if (sidtype == SIDGROUP) {
 309		cidlock = &sidgidlock;
 310		cidtree = &gidtree;
 311	} else
 312		return -EINVAL;
 313
 314	spin_lock(cidlock);
 315	psidid = sid_rb_search(cidtree, cid);
 316
 317	if (!psidid) { /* node does not exist, allocate one & attempt adding */
 318		spin_unlock(cidlock);
 319		npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL);
 320		if (!npsidid)
 321			return -ENOMEM;
 322
 323		npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL);
 324		if (!npsidid->sidstr) {
 325			kfree(npsidid);
 326			return -ENOMEM;
 327		}
 328
 329		spin_lock(cidlock);
 330		psidid = sid_rb_search(cidtree, cid);
 331		if (psidid) { /* node happened to get inserted meanwhile */
 332			++psidid->refcount;
 333			spin_unlock(cidlock);
 334			kfree(npsidid->sidstr);
 335			kfree(npsidid);
 336		} else {
 337			psidid = npsidid;
 338			sid_rb_insert(cidtree, cid, &psidid,
 339					sidtype == SIDOWNER ? "oi:" : "gi:");
 340			++psidid->refcount;
 341			spin_unlock(cidlock);
 342		}
 343	} else {
 344		++psidid->refcount;
 345		spin_unlock(cidlock);
 346	}
 347
 348	/*
 349	 * If we are here, it is safe to access psidid and its fields
 350	 * since a reference was taken earlier while holding the spinlock.
 351	 * A reference on the node is put without holding the spinlock
 352	 * and it is OK to do so in this case, shrinker will not erase
 353	 * this node until all references are put and we do not access
 354	 * any fields of the node after a reference is put .
 355	 */
 356	if (test_bit(SID_ID_MAPPED, &psidid->state)) {
 357		memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
 358		psidid->time = jiffies; /* update ts for accessing */
 359		goto id_sid_out;
 360	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 361
 362	if (time_after(psidid->time + SID_MAP_RETRY, jiffies)) {
 363		rc = -EINVAL;
 364		goto id_sid_out;
 365	}
 366
 367	if (!test_and_set_bit(SID_ID_PENDING, &psidid->state)) {
 368		saved_cred = override_creds(root_cred);
 369		sidkey = request_key(&cifs_idmap_key_type, psidid->sidstr, "");
 370		if (IS_ERR(sidkey)) {
 371			rc = -EINVAL;
 372			cFYI(1, "%s: Can't map and id to a SID", __func__);
 373		} else {
 374			lsid = (struct cifs_sid *)sidkey->payload.data;
 375			memcpy(&psidid->sid, lsid,
 376				sidkey->datalen < sizeof(struct cifs_sid) ?
 377				sidkey->datalen : sizeof(struct cifs_sid));
 378			memcpy(ssid, &psidid->sid,
 379				sidkey->datalen < sizeof(struct cifs_sid) ?
 380				sidkey->datalen : sizeof(struct cifs_sid));
 381			set_bit(SID_ID_MAPPED, &psidid->state);
 382			key_put(sidkey);
 383			kfree(psidid->sidstr);
 384		}
 385		psidid->time = jiffies; /* update ts for accessing */
 386		revert_creds(saved_cred);
 387		clear_bit(SID_ID_PENDING, &psidid->state);
 388		wake_up_bit(&psidid->state, SID_ID_PENDING);
 389	} else {
 390		rc = wait_on_bit(&psidid->state, SID_ID_PENDING,
 391				sidid_pending_wait, TASK_INTERRUPTIBLE);
 392		if (rc) {
 393			cFYI(1, "%s: sidid_pending_wait interrupted %d",
 394					__func__, rc);
 395			--psidid->refcount;
 396			return rc;
 397		}
 398		if (test_bit(SID_ID_MAPPED, &psidid->state))
 399			memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
 400		else
 401			rc = -EINVAL;
 402	}
 403id_sid_out:
 404	--psidid->refcount;
 405	return rc;
 406}
 407
 408static int
 409sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
 410		struct cifs_fattr *fattr, uint sidtype)
 411{
 412	int rc;
 413	unsigned long cid;
 414	struct key *idkey;
 415	const struct cred *saved_cred;
 416	struct cifs_sid_id *psidid, *npsidid;
 417	struct rb_root *cidtree;
 418	spinlock_t *cidlock;
 419
 420	if (sidtype == SIDOWNER) {
 421		cid = cifs_sb->mnt_uid; /* default uid, in case upcall fails */
 422		cidlock = &siduidlock;
 423		cidtree = &uidtree;
 424	} else if (sidtype == SIDGROUP) {
 425		cid = cifs_sb->mnt_gid; /* default gid, in case upcall fails */
 426		cidlock = &sidgidlock;
 427		cidtree = &gidtree;
 428	} else
 429		return -ENOENT;
 430
 431	spin_lock(cidlock);
 432	psidid = id_rb_search(cidtree, psid);
 433
 434	if (!psidid) { /* node does not exist, allocate one & attempt adding */
 435		spin_unlock(cidlock);
 436		npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL);
 437		if (!npsidid)
 438			return -ENOMEM;
 439
 440		npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL);
 441		if (!npsidid->sidstr) {
 442			kfree(npsidid);
 443			return -ENOMEM;
 444		}
 445
 446		spin_lock(cidlock);
 447		psidid = id_rb_search(cidtree, psid);
 448		if (psidid) { /* node happened to get inserted meanwhile */
 449			++psidid->refcount;
 450			spin_unlock(cidlock);
 451			kfree(npsidid->sidstr);
 452			kfree(npsidid);
 453		} else {
 454			psidid = npsidid;
 455			id_rb_insert(cidtree, psid, &psidid,
 456					sidtype == SIDOWNER ? "os:" : "gs:");
 457			++psidid->refcount;
 458			spin_unlock(cidlock);
 459		}
 460	} else {
 461		++psidid->refcount;
 462		spin_unlock(cidlock);
 463	}
 464
 465	/*
 466	 * If we are here, it is safe to access psidid and its fields
 467	 * since a reference was taken earlier while holding the spinlock.
 468	 * A reference on the node is put without holding the spinlock
 469	 * and it is OK to do so in this case, shrinker will not erase
 470	 * this node until all references are put and we do not access
 471	 * any fields of the node after a reference is put .
 472	 */
 473	if (test_bit(SID_ID_MAPPED, &psidid->state)) {
 474		cid = psidid->id;
 475		psidid->time = jiffies; /* update ts for accessing */
 476		goto sid_to_id_out;
 477	}
 478
 479	if (time_after(psidid->time + SID_MAP_RETRY, jiffies))
 480		goto sid_to_id_out;
 481
 482	if (!test_and_set_bit(SID_ID_PENDING, &psidid->state)) {
 483		saved_cred = override_creds(root_cred);
 484		idkey = request_key(&cifs_idmap_key_type, psidid->sidstr, "");
 485		if (IS_ERR(idkey))
 486			cFYI(1, "%s: Can't map SID to an id", __func__);
 487		else {
 488			cid = *(unsigned long *)idkey->payload.value;
 489			psidid->id = cid;
 490			set_bit(SID_ID_MAPPED, &psidid->state);
 491			key_put(idkey);
 492			kfree(psidid->sidstr);
 493		}
 494		revert_creds(saved_cred);
 495		psidid->time = jiffies; /* update ts for accessing */
 496		clear_bit(SID_ID_PENDING, &psidid->state);
 497		wake_up_bit(&psidid->state, SID_ID_PENDING);
 498	} else {
 499		rc = wait_on_bit(&psidid->state, SID_ID_PENDING,
 500				sidid_pending_wait, TASK_INTERRUPTIBLE);
 501		if (rc) {
 502			cFYI(1, "%s: sidid_pending_wait interrupted %d",
 503					__func__, rc);
 504			--psidid->refcount; /* decremented without spinlock */
 505			return rc;
 506		}
 507		if (test_bit(SID_ID_MAPPED, &psidid->state))
 508			cid = psidid->id;
 509	}
 510
 511sid_to_id_out:
 512	--psidid->refcount; /* decremented without spinlock */
 
 
 
 
 
 
 
 
 513	if (sidtype == SIDOWNER)
 514		fattr->cf_uid = cid;
 515	else
 516		fattr->cf_gid = cid;
 517
 518	return 0;
 519}
 520
 521int
 522init_cifs_idmap(void)
 523{
 524	struct cred *cred;
 525	struct key *keyring;
 526	int ret;
 527
 528	cFYI(1, "Registering the %s key type\n", cifs_idmap_key_type.name);
 
 529
 530	/* create an override credential set with a special thread keyring in
 531	 * which requests are cached
 532	 *
 533	 * this is used to prevent malicious redirections from being installed
 534	 * with add_key().
 535	 */
 536	cred = prepare_kernel_cred(NULL);
 537	if (!cred)
 538		return -ENOMEM;
 539
 540	keyring = key_alloc(&key_type_keyring, ".cifs_idmap", 0, 0, cred,
 541			    (KEY_POS_ALL & ~KEY_POS_SETATTR) |
 542			    KEY_USR_VIEW | KEY_USR_READ,
 543			    KEY_ALLOC_NOT_IN_QUOTA);
 
 544	if (IS_ERR(keyring)) {
 545		ret = PTR_ERR(keyring);
 546		goto failed_put_cred;
 547	}
 548
 549	ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL);
 550	if (ret < 0)
 551		goto failed_put_key;
 552
 553	ret = register_key_type(&cifs_idmap_key_type);
 554	if (ret < 0)
 555		goto failed_put_key;
 556
 557	/* instruct request_key() to use this special keyring as a cache for
 558	 * the results it looks up */
 559	set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
 560	cred->thread_keyring = keyring;
 561	cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
 562	root_cred = cred;
 563
 564	spin_lock_init(&siduidlock);
 565	uidtree = RB_ROOT;
 566	spin_lock_init(&sidgidlock);
 567	gidtree = RB_ROOT;
 568
 569	spin_lock_init(&uidsidlock);
 570	siduidtree = RB_ROOT;
 571	spin_lock_init(&gidsidlock);
 572	sidgidtree = RB_ROOT;
 573	register_shrinker(&cifs_shrinker);
 574
 575	cFYI(1, "cifs idmap keyring: %d\n", key_serial(keyring));
 576	return 0;
 577
 578failed_put_key:
 579	key_put(keyring);
 580failed_put_cred:
 581	put_cred(cred);
 582	return ret;
 583}
 584
 585void
 586exit_cifs_idmap(void)
 587{
 588	key_revoke(root_cred->thread_keyring);
 589	unregister_key_type(&cifs_idmap_key_type);
 590	put_cred(root_cred);
 591	unregister_shrinker(&cifs_shrinker);
 592	cFYI(1, "Unregistered %s key type\n", cifs_idmap_key_type.name);
 593}
 594
 595void
 596cifs_destroy_idmaptrees(void)
 597{
 598	struct rb_root *root;
 599	struct rb_node *node;
 600
 601	root = &uidtree;
 602	spin_lock(&siduidlock);
 603	while ((node = rb_first(root)))
 604		rb_erase(node, root);
 605	spin_unlock(&siduidlock);
 606
 607	root = &gidtree;
 608	spin_lock(&sidgidlock);
 609	while ((node = rb_first(root)))
 610		rb_erase(node, root);
 611	spin_unlock(&sidgidlock);
 612
 613	root = &siduidtree;
 614	spin_lock(&uidsidlock);
 615	while ((node = rb_first(root)))
 616		rb_erase(node, root);
 617	spin_unlock(&uidsidlock);
 618
 619	root = &sidgidtree;
 620	spin_lock(&gidsidlock);
 621	while ((node = rb_first(root)))
 622		rb_erase(node, root);
 623	spin_unlock(&gidsidlock);
 624}
 625
 626/* if the two SIDs (roughly equivalent to a UUID for a user or group) are
 627   the same returns 1, if they do not match returns 0 */
 628int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
 629{
 630	int i;
 631	int num_subauth, num_sat, num_saw;
 632
 633	if ((!ctsid) || (!cwsid))
 634		return 1;
 635
 636	/* compare the revision */
 637	if (ctsid->revision != cwsid->revision) {
 638		if (ctsid->revision > cwsid->revision)
 639			return 1;
 640		else
 641			return -1;
 642	}
 643
 644	/* compare all of the six auth values */
 645	for (i = 0; i < 6; ++i) {
 646		if (ctsid->authority[i] != cwsid->authority[i]) {
 647			if (ctsid->authority[i] > cwsid->authority[i])
 648				return 1;
 649			else
 650				return -1;
 651		}
 652	}
 653
 654	/* compare all of the subauth values if any */
 655	num_sat = ctsid->num_subauth;
 656	num_saw = cwsid->num_subauth;
 657	num_subauth = num_sat < num_saw ? num_sat : num_saw;
 658	if (num_subauth) {
 659		for (i = 0; i < num_subauth; ++i) {
 660			if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
 661				if (le32_to_cpu(ctsid->sub_auth[i]) >
 662					le32_to_cpu(cwsid->sub_auth[i]))
 663					return 1;
 664				else
 665					return -1;
 666			}
 667		}
 668	}
 669
 670	return 0; /* sids compare/match */
 671}
 672
 673
 674/* copy ntsd, owner sid, and group sid from a security descriptor to another */
 675static void copy_sec_desc(const struct cifs_ntsd *pntsd,
 676				struct cifs_ntsd *pnntsd, __u32 sidsoffset)
 677{
 678	int i;
 679
 680	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
 681	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
 682
 683	/* copy security descriptor control portion */
 684	pnntsd->revision = pntsd->revision;
 685	pnntsd->type = pntsd->type;
 686	pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
 687	pnntsd->sacloffset = 0;
 688	pnntsd->osidoffset = cpu_to_le32(sidsoffset);
 689	pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
 690
 691	/* copy owner sid */
 692	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
 693				le32_to_cpu(pntsd->osidoffset));
 694	nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
 695
 696	nowner_sid_ptr->revision = owner_sid_ptr->revision;
 697	nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
 698	for (i = 0; i < 6; i++)
 699		nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
 700	for (i = 0; i < 5; i++)
 701		nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
 702
 703	/* copy group sid */
 704	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
 705				le32_to_cpu(pntsd->gsidoffset));
 706	ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
 707					sizeof(struct cifs_sid));
 708
 709	ngroup_sid_ptr->revision = group_sid_ptr->revision;
 710	ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
 711	for (i = 0; i < 6; i++)
 712		ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
 713	for (i = 0; i < 5; i++)
 714		ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
 715
 716	return;
 717}
 718
 719
 720/*
 721   change posix mode to reflect permissions
 722   pmode is the existing mode (we only want to overwrite part of this
 723   bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
 724*/
 725static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
 726				 umode_t *pbits_to_set)
 727{
 728	__u32 flags = le32_to_cpu(ace_flags);
 729	/* the order of ACEs is important.  The canonical order is to begin with
 730	   DENY entries followed by ALLOW, otherwise an allow entry could be
 731	   encountered first, making the subsequent deny entry like "dead code"
 732	   which would be superflous since Windows stops when a match is made
 733	   for the operation you are trying to perform for your user */
 734
 735	/* For deny ACEs we change the mask so that subsequent allow access
 736	   control entries do not turn on the bits we are denying */
 737	if (type == ACCESS_DENIED) {
 738		if (flags & GENERIC_ALL)
 739			*pbits_to_set &= ~S_IRWXUGO;
 740
 741		if ((flags & GENERIC_WRITE) ||
 742			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
 743			*pbits_to_set &= ~S_IWUGO;
 744		if ((flags & GENERIC_READ) ||
 745			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
 746			*pbits_to_set &= ~S_IRUGO;
 747		if ((flags & GENERIC_EXECUTE) ||
 748			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
 749			*pbits_to_set &= ~S_IXUGO;
 750		return;
 751	} else if (type != ACCESS_ALLOWED) {
 752		cERROR(1, "unknown access control type %d", type);
 753		return;
 754	}
 755	/* else ACCESS_ALLOWED type */
 756
 757	if (flags & GENERIC_ALL) {
 758		*pmode |= (S_IRWXUGO & (*pbits_to_set));
 759		cFYI(DBG2, "all perms");
 760		return;
 761	}
 762	if ((flags & GENERIC_WRITE) ||
 763			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
 764		*pmode |= (S_IWUGO & (*pbits_to_set));
 765	if ((flags & GENERIC_READ) ||
 766			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
 767		*pmode |= (S_IRUGO & (*pbits_to_set));
 768	if ((flags & GENERIC_EXECUTE) ||
 769			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
 770		*pmode |= (S_IXUGO & (*pbits_to_set));
 771
 772	cFYI(DBG2, "access flags 0x%x mode now 0x%x", flags, *pmode);
 773	return;
 774}
 775
 776/*
 777   Generate access flags to reflect permissions mode is the existing mode.
 778   This function is called for every ACE in the DACL whose SID matches
 779   with either owner or group or everyone.
 780*/
 781
 782static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
 783				__u32 *pace_flags)
 784{
 785	/* reset access mask */
 786	*pace_flags = 0x0;
 787
 788	/* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
 789	mode &= bits_to_use;
 790
 791	/* check for R/W/X UGO since we do not know whose flags
 792	   is this but we have cleared all the bits sans RWX for
 793	   either user or group or other as per bits_to_use */
 794	if (mode & S_IRUGO)
 795		*pace_flags |= SET_FILE_READ_RIGHTS;
 796	if (mode & S_IWUGO)
 797		*pace_flags |= SET_FILE_WRITE_RIGHTS;
 798	if (mode & S_IXUGO)
 799		*pace_flags |= SET_FILE_EXEC_RIGHTS;
 800
 801	cFYI(DBG2, "mode: 0x%x, access flags now 0x%x", mode, *pace_flags);
 
 802	return;
 803}
 804
 805static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
 806			const struct cifs_sid *psid, __u64 nmode, umode_t bits)
 807{
 808	int i;
 809	__u16 size = 0;
 810	__u32 access_req = 0;
 811
 812	pntace->type = ACCESS_ALLOWED;
 813	pntace->flags = 0x0;
 814	mode_to_access_flags(nmode, bits, &access_req);
 815	if (!access_req)
 816		access_req = SET_MINIMUM_RIGHTS;
 817	pntace->access_req = cpu_to_le32(access_req);
 818
 819	pntace->sid.revision = psid->revision;
 820	pntace->sid.num_subauth = psid->num_subauth;
 821	for (i = 0; i < 6; i++)
 822		pntace->sid.authority[i] = psid->authority[i];
 823	for (i = 0; i < psid->num_subauth; i++)
 824		pntace->sid.sub_auth[i] = psid->sub_auth[i];
 825
 826	size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
 827	pntace->size = cpu_to_le16(size);
 828
 829	return size;
 830}
 831
 832
 833#ifdef CONFIG_CIFS_DEBUG2
 834static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
 835{
 836	int num_subauth;
 837
 838	/* validate that we do not go past end of acl */
 839
 840	if (le16_to_cpu(pace->size) < 16) {
 841		cERROR(1, "ACE too small %d", le16_to_cpu(pace->size));
 842		return;
 843	}
 844
 845	if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
 846		cERROR(1, "ACL too small to parse ACE");
 847		return;
 848	}
 849
 850	num_subauth = pace->sid.num_subauth;
 851	if (num_subauth) {
 852		int i;
 853		cFYI(1, "ACE revision %d num_auth %d type %d flags %d size %d",
 854			pace->sid.revision, pace->sid.num_subauth, pace->type,
 855			pace->flags, le16_to_cpu(pace->size));
 856		for (i = 0; i < num_subauth; ++i) {
 857			cFYI(1, "ACE sub_auth[%d]: 0x%x", i,
 858				le32_to_cpu(pace->sid.sub_auth[i]));
 859		}
 860
 861		/* BB add length check to make sure that we do not have huge
 862			num auths and therefore go off the end */
 863	}
 864
 865	return;
 866}
 867#endif
 868
 869
 870static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
 871		       struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
 872		       struct cifs_fattr *fattr)
 873{
 874	int i;
 875	int num_aces = 0;
 876	int acl_size;
 877	char *acl_base;
 878	struct cifs_ace **ppace;
 879
 880	/* BB need to add parm so we can store the SID BB */
 881
 882	if (!pdacl) {
 883		/* no DACL in the security descriptor, set
 884		   all the permissions for user/group/other */
 885		fattr->cf_mode |= S_IRWXUGO;
 886		return;
 887	}
 888
 889	/* validate that we do not go past end of acl */
 890	if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
 891		cERROR(1, "ACL too small to parse DACL");
 892		return;
 893	}
 894
 895	cFYI(DBG2, "DACL revision %d size %d num aces %d",
 896		le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
 897		le32_to_cpu(pdacl->num_aces));
 898
 899	/* reset rwx permissions for user/group/other.
 900	   Also, if num_aces is 0 i.e. DACL has no ACEs,
 901	   user/group/other have no permissions */
 902	fattr->cf_mode &= ~(S_IRWXUGO);
 903
 904	acl_base = (char *)pdacl;
 905	acl_size = sizeof(struct cifs_acl);
 906
 907	num_aces = le32_to_cpu(pdacl->num_aces);
 908	if (num_aces > 0) {
 909		umode_t user_mask = S_IRWXU;
 910		umode_t group_mask = S_IRWXG;
 911		umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
 912
 913		if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
 914			return;
 915		ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
 916				GFP_KERNEL);
 917		if (!ppace) {
 918			cERROR(1, "DACL memory allocation error");
 919			return;
 920		}
 921
 922		for (i = 0; i < num_aces; ++i) {
 923			ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
 924#ifdef CONFIG_CIFS_DEBUG2
 925			dump_ace(ppace[i], end_of_acl);
 926#endif
 927			if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
 928				access_flags_to_mode(ppace[i]->access_req,
 929						     ppace[i]->type,
 930						     &fattr->cf_mode,
 931						     &user_mask);
 932			if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
 933				access_flags_to_mode(ppace[i]->access_req,
 934						     ppace[i]->type,
 935						     &fattr->cf_mode,
 936						     &group_mask);
 937			if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
 938				access_flags_to_mode(ppace[i]->access_req,
 939						     ppace[i]->type,
 940						     &fattr->cf_mode,
 941						     &other_mask);
 942			if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
 943				access_flags_to_mode(ppace[i]->access_req,
 944						     ppace[i]->type,
 945						     &fattr->cf_mode,
 946						     &other_mask);
 947
 948
 949/*			memcpy((void *)(&(cifscred->aces[i])),
 950				(void *)ppace[i],
 951				sizeof(struct cifs_ace)); */
 952
 953			acl_base = (char *)ppace[i];
 954			acl_size = le16_to_cpu(ppace[i]->size);
 955		}
 956
 957		kfree(ppace);
 958	}
 959
 960	return;
 961}
 962
 963
 964static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
 965			struct cifs_sid *pgrpsid, __u64 nmode)
 966{
 967	u16 size = 0;
 968	struct cifs_acl *pnndacl;
 969
 970	pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
 971
 972	size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
 973					pownersid, nmode, S_IRWXU);
 974	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
 975					pgrpsid, nmode, S_IRWXG);
 976	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
 977					 &sid_everyone, nmode, S_IRWXO);
 978
 979	pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
 980	pndacl->num_aces = cpu_to_le32(3);
 981
 982	return 0;
 983}
 984
 985
 986static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
 987{
 988	/* BB need to add parm so we can store the SID BB */
 989
 990	/* validate that we do not go past end of ACL - sid must be at least 8
 991	   bytes long (assuming no sub-auths - e.g. the null SID */
 992	if (end_of_acl < (char *)psid + 8) {
 993		cERROR(1, "ACL too small to parse SID %p", psid);
 994		return -EINVAL;
 995	}
 996
 
 997	if (psid->num_subauth) {
 998#ifdef CONFIG_CIFS_DEBUG2
 999		int i;
1000		cFYI(1, "SID revision %d num_auth %d",
1001			psid->revision, psid->num_subauth);
1002
1003		for (i = 0; i < psid->num_subauth; i++) {
1004			cFYI(1, "SID sub_auth[%d]: 0x%x ", i,
1005				le32_to_cpu(psid->sub_auth[i]));
1006		}
1007
1008		/* BB add length check to make sure that we do not have huge
1009			num auths and therefore go off the end */
1010		cFYI(1, "RID 0x%x",
1011			le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
 
1012#endif
1013	}
1014
1015	return 0;
1016}
1017
1018
1019/* Convert CIFS ACL to POSIX form */
1020static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1021		struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr)
1022{
1023	int rc = 0;
1024	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1025	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
1026	char *end_of_acl = ((char *)pntsd) + acl_len;
1027	__u32 dacloffset;
1028
1029	if (pntsd == NULL)
1030		return -EIO;
1031
1032	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1033				le32_to_cpu(pntsd->osidoffset));
1034	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1035				le32_to_cpu(pntsd->gsidoffset));
1036	dacloffset = le32_to_cpu(pntsd->dacloffset);
1037	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1038	cFYI(DBG2, "revision %d type 0x%x ooffset 0x%x goffset 0x%x "
1039		 "sacloffset 0x%x dacloffset 0x%x",
1040		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1041		 le32_to_cpu(pntsd->gsidoffset),
1042		 le32_to_cpu(pntsd->sacloffset), dacloffset);
1043/*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1044	rc = parse_sid(owner_sid_ptr, end_of_acl);
1045	if (rc) {
1046		cFYI(1, "%s: Error %d parsing Owner SID", __func__, rc);
1047		return rc;
1048	}
1049	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1050	if (rc) {
1051		cFYI(1, "%s: Error %d mapping Owner SID to uid", __func__, rc);
 
1052		return rc;
1053	}
1054
1055	rc = parse_sid(group_sid_ptr, end_of_acl);
1056	if (rc) {
1057		cFYI(1, "%s: Error %d mapping Owner SID to gid", __func__, rc);
 
1058		return rc;
1059	}
1060	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1061	if (rc) {
1062		cFYI(1, "%s: Error %d mapping Group SID to gid", __func__, rc);
 
1063		return rc;
1064	}
1065
1066	if (dacloffset)
1067		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1068			   group_sid_ptr, fattr);
1069	else
1070		cFYI(1, "no ACL"); /* BB grant all or default perms? */
1071
1072	return rc;
1073}
1074
1075/* Convert permission bits from mode to equivalent CIFS ACL */
1076static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1077	__u32 secdesclen, __u64 nmode, uid_t uid, gid_t gid, int *aclflag)
1078{
1079	int rc = 0;
1080	__u32 dacloffset;
1081	__u32 ndacloffset;
1082	__u32 sidsoffset;
1083	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1084	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
1085	struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
1086	struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1087
1088	if (nmode != NO_CHANGE_64) { /* chmod */
1089		owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1090				le32_to_cpu(pntsd->osidoffset));
1091		group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1092				le32_to_cpu(pntsd->gsidoffset));
1093		dacloffset = le32_to_cpu(pntsd->dacloffset);
1094		dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1095		ndacloffset = sizeof(struct cifs_ntsd);
1096		ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1097		ndacl_ptr->revision = dacl_ptr->revision;
1098		ndacl_ptr->size = 0;
1099		ndacl_ptr->num_aces = 0;
1100
1101		rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1102					nmode);
1103		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1104		/* copy sec desc control portion & owner and group sids */
1105		copy_sec_desc(pntsd, pnntsd, sidsoffset);
1106		*aclflag = CIFS_ACL_DACL;
1107	} else {
1108		memcpy(pnntsd, pntsd, secdesclen);
1109		if (uid != NO_CHANGE_32) { /* chown */
 
1110			owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1111					le32_to_cpu(pnntsd->osidoffset));
1112			nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1113								GFP_KERNEL);
1114			if (!nowner_sid_ptr)
1115				return -ENOMEM;
1116			rc = id_to_sid(uid, SIDOWNER, nowner_sid_ptr);
 
1117			if (rc) {
1118				cFYI(1, "%s: Mapping error %d for owner id %d",
1119						__func__, rc, uid);
1120				kfree(nowner_sid_ptr);
1121				return rc;
1122			}
1123			memcpy(owner_sid_ptr, nowner_sid_ptr,
1124					sizeof(struct cifs_sid));
1125			kfree(nowner_sid_ptr);
1126			*aclflag = CIFS_ACL_OWNER;
1127		}
1128		if (gid != NO_CHANGE_32) { /* chgrp */
 
1129			group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1130					le32_to_cpu(pnntsd->gsidoffset));
1131			ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1132								GFP_KERNEL);
1133			if (!ngroup_sid_ptr)
1134				return -ENOMEM;
1135			rc = id_to_sid(gid, SIDGROUP, ngroup_sid_ptr);
 
1136			if (rc) {
1137				cFYI(1, "%s: Mapping error %d for group id %d",
1138						__func__, rc, gid);
1139				kfree(ngroup_sid_ptr);
1140				return rc;
1141			}
1142			memcpy(group_sid_ptr, ngroup_sid_ptr,
1143					sizeof(struct cifs_sid));
1144			kfree(ngroup_sid_ptr);
1145			*aclflag = CIFS_ACL_GROUP;
1146		}
1147	}
1148
1149	return rc;
1150}
1151
1152static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1153		__u16 fid, u32 *pacllen)
1154{
1155	struct cifs_ntsd *pntsd = NULL;
1156	int xid, rc;
 
1157	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1158
1159	if (IS_ERR(tlink))
1160		return ERR_CAST(tlink);
1161
1162	xid = GetXid();
1163	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
1164	FreeXid(xid);
 
1165
1166	cifs_put_tlink(tlink);
1167
1168	cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
1169	if (rc)
1170		return ERR_PTR(rc);
1171	return pntsd;
1172}
1173
1174static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1175		const char *path, u32 *pacllen)
1176{
1177	struct cifs_ntsd *pntsd = NULL;
1178	int oplock = 0;
1179	int xid, rc, create_options = 0;
1180	__u16 fid;
1181	struct cifs_tcon *tcon;
1182	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
 
 
1183
1184	if (IS_ERR(tlink))
1185		return ERR_CAST(tlink);
1186
1187	tcon = tlink_tcon(tlink);
1188	xid = GetXid();
1189
1190	if (backup_cred(cifs_sb))
1191		create_options |= CREATE_OPEN_BACKUP_INTENT;
1192
1193	rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
1194			create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
1195			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 
 
 
 
 
 
 
1196	if (!rc) {
1197		rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
1198		CIFSSMBClose(xid, tcon, fid);
1199	}
1200
1201	cifs_put_tlink(tlink);
1202	FreeXid(xid);
1203
1204	cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
1205	if (rc)
1206		return ERR_PTR(rc);
1207	return pntsd;
1208}
1209
1210/* Retrieve an ACL from the server */
1211struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1212				      struct inode *inode, const char *path,
1213				      u32 *pacllen)
1214{
1215	struct cifs_ntsd *pntsd = NULL;
1216	struct cifsFileInfo *open_file = NULL;
1217
1218	if (inode)
1219		open_file = find_readable_file(CIFS_I(inode), true);
1220	if (!open_file)
1221		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1222
1223	pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen);
1224	cifsFileInfo_put(open_file);
1225	return pntsd;
1226}
1227
1228 /* Set an ACL on the server */
1229int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1230			struct inode *inode, const char *path, int aclflag)
1231{
1232	int oplock = 0;
1233	int xid, rc, access_flags, create_options = 0;
1234	__u16 fid;
1235	struct cifs_tcon *tcon;
1236	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1237	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
 
 
1238
1239	if (IS_ERR(tlink))
1240		return PTR_ERR(tlink);
1241
1242	tcon = tlink_tcon(tlink);
1243	xid = GetXid();
1244
1245	if (backup_cred(cifs_sb))
1246		create_options |= CREATE_OPEN_BACKUP_INTENT;
1247
1248	if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1249		access_flags = WRITE_OWNER;
1250	else
1251		access_flags = WRITE_DAC;
1252
1253	rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, access_flags,
1254			create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
1255			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 
 
 
 
 
 
 
1256	if (rc) {
1257		cERROR(1, "Unable to open file to set ACL");
1258		goto out;
1259	}
1260
1261	rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen, aclflag);
1262	cFYI(DBG2, "SetCIFSACL rc = %d", rc);
1263
1264	CIFSSMBClose(xid, tcon, fid);
1265out:
1266	FreeXid(xid);
1267	cifs_put_tlink(tlink);
1268	return rc;
1269}
1270
1271/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
1272int
1273cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1274		  struct inode *inode, const char *path, const __u16 *pfid)
 
1275{
1276	struct cifs_ntsd *pntsd = NULL;
1277	u32 acllen = 0;
1278	int rc = 0;
 
 
1279
1280	cFYI(DBG2, "converting ACL to mode for %s", path);
1281
1282	if (pfid)
1283		pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
1284	else
1285		pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
1286
 
 
 
 
 
 
 
 
 
 
1287	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1288	if (IS_ERR(pntsd)) {
1289		rc = PTR_ERR(pntsd);
1290		cERROR(1, "%s: error %d getting sec desc", __func__, rc);
1291	} else {
1292		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr);
1293		kfree(pntsd);
1294		if (rc)
1295			cERROR(1, "parse sec desc failed rc = %d", rc);
1296	}
1297
 
 
1298	return rc;
1299}
1300
1301/* Convert mode bits to an ACL so we can update the ACL on the server */
1302int
1303id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1304			uid_t uid, gid_t gid)
1305{
1306	int rc = 0;
1307	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1308	__u32 secdesclen = 0;
1309	struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1310	struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
 
 
 
1311
1312	cFYI(DBG2, "set ACL from mode for %s", path);
 
 
 
 
1313
1314	/* Get the security descriptor */
1315	pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
1316
1317	/* Add three ACEs for owner, group, everyone getting rid of
1318	   other ACEs as chmod disables ACEs and set the security descriptor */
 
 
1319
 
 
1320	if (IS_ERR(pntsd)) {
1321		rc = PTR_ERR(pntsd);
1322		cERROR(1, "%s: error %d getting sec desc", __func__, rc);
1323	} else {
1324		/* allocate memory for the smb header,
1325		   set security descriptor request security descriptor
1326		   parameters, and secuirty descriptor itself */
1327
1328		secdesclen = secdesclen < DEFSECDESCLEN ?
1329					DEFSECDESCLEN : secdesclen;
1330		pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1331		if (!pnntsd) {
1332			cERROR(1, "Unable to allocate security descriptor");
1333			kfree(pntsd);
1334			return -ENOMEM;
1335		}
 
 
 
 
1336
1337		rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1338					&aclflag);
1339
1340		cFYI(DBG2, "build_sec_desc rc: %d", rc);
1341
1342		if (!rc) {
1343			/* Set the security descriptor */
1344			rc = set_cifs_acl(pnntsd, secdesclen, inode,
1345						path, aclflag);
1346			cFYI(DBG2, "set_cifs_acl rc: %d", rc);
1347		}
1348
1349		kfree(pnntsd);
1350		kfree(pntsd);
 
 
 
1351	}
 
1352
 
 
1353	return rc;
1354}