Linux Audio

Check our new training course

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