Linux Audio

Check our new training course

Loading...
v6.2
   1// SPDX-License-Identifier: LGPL-2.1
   2/*
 
   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 */
  10
  11#include <linux/fs.h>
  12#include <linux/slab.h>
  13#include <linux/string.h>
  14#include <linux/keyctl.h>
  15#include <linux/key-type.h>
  16#include <uapi/linux/posix_acl.h>
  17#include <linux/posix_acl.h>
  18#include <linux/posix_acl_xattr.h>
  19#include <keys/user-type.h>
  20#include "cifspdu.h"
  21#include "cifsglob.h"
  22#include "cifsacl.h"
  23#include "cifsproto.h"
  24#include "cifs_debug.h"
  25#include "fs_context.h"
  26#include "cifs_fs_sb.h"
  27#include "cifs_unicode.h"
  28
  29/* security id for everyone/world system group */
  30static const struct cifs_sid sid_everyone = {
  31	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
  32/* security id for Authenticated Users system group */
  33static const struct cifs_sid sid_authusers = {
  34	1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
 
 
  35
  36/* S-1-22-1 Unmapped Unix users */
  37static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
  38		{cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  39
  40/* S-1-22-2 Unmapped Unix groups */
  41static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
  42		{cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  43
  44/*
  45 * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
  46 */
  47
  48/* S-1-5-88 MS NFS and Apple style UID/GID/mode */
  49
  50/* S-1-5-88-1 Unix uid */
  51static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
  52	{cpu_to_le32(88),
  53	 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  54
  55/* S-1-5-88-2 Unix gid */
  56static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
  57	{cpu_to_le32(88),
  58	 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  59
  60/* S-1-5-88-3 Unix mode */
  61static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
  62	{cpu_to_le32(88),
  63	 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  64
  65static const struct cred *root_cred;
  66
  67static int
  68cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
  69{
  70	char *payload;
  71
  72	/*
  73	 * If the payload is less than or equal to the size of a pointer, then
  74	 * an allocation here is wasteful. Just copy the data directly to the
  75	 * payload.value union member instead.
  76	 *
  77	 * With this however, you must check the datalen before trying to
  78	 * dereference payload.data!
  79	 */
  80	if (prep->datalen <= sizeof(key->payload)) {
  81		key->payload.data[0] = NULL;
  82		memcpy(&key->payload, prep->data, prep->datalen);
  83	} else {
  84		payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
  85		if (!payload)
  86			return -ENOMEM;
  87		key->payload.data[0] = payload;
  88	}
  89
  90	key->datalen = prep->datalen;
  91	return 0;
  92}
  93
  94static inline void
  95cifs_idmap_key_destroy(struct key *key)
  96{
  97	if (key->datalen > sizeof(key->payload))
  98		kfree(key->payload.data[0]);
  99}
 100
 101static struct key_type cifs_idmap_key_type = {
 102	.name        = "cifs.idmap",
 103	.instantiate = cifs_idmap_key_instantiate,
 104	.destroy     = cifs_idmap_key_destroy,
 105	.describe    = user_describe,
 106};
 107
 108static char *
 109sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
 110{
 111	int i, len;
 112	unsigned int saval;
 113	char *sidstr, *strptr;
 114	unsigned long long id_auth_val;
 115
 116	/* 3 bytes for prefix */
 117	sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
 118			 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
 119			 GFP_KERNEL);
 120	if (!sidstr)
 121		return sidstr;
 122
 123	strptr = sidstr;
 124	len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
 125			sidptr->revision);
 126	strptr += len;
 127
 128	/* The authority field is a single 48-bit number */
 129	id_auth_val = (unsigned long long)sidptr->authority[5];
 130	id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
 131	id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
 132	id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
 133	id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
 134	id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
 135
 136	/*
 137	 * MS-DTYP states that if the authority is >= 2^32, then it should be
 138	 * expressed as a hex value.
 139	 */
 140	if (id_auth_val <= UINT_MAX)
 141		len = sprintf(strptr, "-%llu", id_auth_val);
 142	else
 143		len = sprintf(strptr, "-0x%llx", id_auth_val);
 144
 145	strptr += len;
 146
 147	for (i = 0; i < sidptr->num_subauth; ++i) {
 148		saval = le32_to_cpu(sidptr->sub_auth[i]);
 149		len = sprintf(strptr, "-%u", saval);
 150		strptr += len;
 151	}
 152
 153	return sidstr;
 154}
 155
 156/*
 157 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
 158 * the same returns zero, if they do not match returns non-zero.
 159 */
 160static int
 161compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
 162{
 163	int i;
 164	int num_subauth, num_sat, num_saw;
 165
 166	if ((!ctsid) || (!cwsid))
 167		return 1;
 168
 169	/* compare the revision */
 170	if (ctsid->revision != cwsid->revision) {
 171		if (ctsid->revision > cwsid->revision)
 172			return 1;
 173		else
 174			return -1;
 175	}
 176
 177	/* compare all of the six auth values */
 178	for (i = 0; i < NUM_AUTHS; ++i) {
 179		if (ctsid->authority[i] != cwsid->authority[i]) {
 180			if (ctsid->authority[i] > cwsid->authority[i])
 181				return 1;
 182			else
 183				return -1;
 184		}
 185	}
 186
 187	/* compare all of the subauth values if any */
 188	num_sat = ctsid->num_subauth;
 189	num_saw = cwsid->num_subauth;
 190	num_subauth = num_sat < num_saw ? num_sat : num_saw;
 191	if (num_subauth) {
 192		for (i = 0; i < num_subauth; ++i) {
 193			if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
 194				if (le32_to_cpu(ctsid->sub_auth[i]) >
 195					le32_to_cpu(cwsid->sub_auth[i]))
 196					return 1;
 197				else
 198					return -1;
 199			}
 200		}
 201	}
 202
 203	return 0; /* sids compare/match */
 204}
 205
 206static bool
 207is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
 208{
 209	int i;
 210	int num_subauth;
 211	const struct cifs_sid *pwell_known_sid;
 212
 213	if (!psid || (puid == NULL))
 214		return false;
 215
 216	num_subauth = psid->num_subauth;
 217
 218	/* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
 219	if (num_subauth == 2) {
 220		if (is_group)
 221			pwell_known_sid = &sid_unix_groups;
 222		else
 223			pwell_known_sid = &sid_unix_users;
 224	} else if (num_subauth == 3) {
 225		if (is_group)
 226			pwell_known_sid = &sid_unix_NFS_groups;
 227		else
 228			pwell_known_sid = &sid_unix_NFS_users;
 229	} else
 230		return false;
 231
 232	/* compare the revision */
 233	if (psid->revision != pwell_known_sid->revision)
 234		return false;
 235
 236	/* compare all of the six auth values */
 237	for (i = 0; i < NUM_AUTHS; ++i) {
 238		if (psid->authority[i] != pwell_known_sid->authority[i]) {
 239			cifs_dbg(FYI, "auth %d did not match\n", i);
 240			return false;
 241		}
 242	}
 243
 244	if (num_subauth == 2) {
 245		if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
 246			return false;
 247
 248		*puid = le32_to_cpu(psid->sub_auth[1]);
 249	} else /* 3 subauths, ie Windows/Mac style */ {
 250		*puid = le32_to_cpu(psid->sub_auth[0]);
 251		if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
 252		    (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
 253			return false;
 254
 255		*puid = le32_to_cpu(psid->sub_auth[2]);
 256	}
 257
 258	cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
 259	return true; /* well known sid found, uid returned */
 260}
 261
 262static __u16
 263cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
 264{
 265	int i;
 266	__u16 size = 1 + 1 + 6;
 267
 268	dst->revision = src->revision;
 269	dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
 270	for (i = 0; i < NUM_AUTHS; ++i)
 271		dst->authority[i] = src->authority[i];
 272	for (i = 0; i < dst->num_subauth; ++i)
 273		dst->sub_auth[i] = src->sub_auth[i];
 274	size += (dst->num_subauth * 4);
 275
 276	return size;
 277}
 278
 279static int
 280id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
 281{
 282	int rc;
 283	struct key *sidkey;
 284	struct cifs_sid *ksid;
 285	unsigned int ksid_size;
 286	char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
 287	const struct cred *saved_cred;
 288
 289	rc = snprintf(desc, sizeof(desc), "%ci:%u",
 290			sidtype == SIDOWNER ? 'o' : 'g', cid);
 291	if (rc >= sizeof(desc))
 292		return -EINVAL;
 293
 294	rc = 0;
 295	saved_cred = override_creds(root_cred);
 296	sidkey = request_key(&cifs_idmap_key_type, desc, "");
 297	if (IS_ERR(sidkey)) {
 298		rc = -EINVAL;
 299		cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
 300			 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
 301		goto out_revert_creds;
 302	} else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
 303		rc = -EIO;
 304		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
 305			 __func__, sidkey->datalen);
 306		goto invalidate_key;
 307	}
 308
 309	/*
 310	 * A sid is usually too large to be embedded in payload.value, but if
 311	 * there are no subauthorities and the host has 8-byte pointers, then
 312	 * it could be.
 313	 */
 314	ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
 315		(struct cifs_sid *)&sidkey->payload :
 316		(struct cifs_sid *)sidkey->payload.data[0];
 317
 318	ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
 319	if (ksid_size > sidkey->datalen) {
 320		rc = -EIO;
 321		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
 322			 __func__, sidkey->datalen, ksid_size);
 323		goto invalidate_key;
 324	}
 325
 326	cifs_copy_sid(ssid, ksid);
 327out_key_put:
 328	key_put(sidkey);
 329out_revert_creds:
 330	revert_creds(saved_cred);
 331	return rc;
 332
 333invalidate_key:
 334	key_invalidate(sidkey);
 335	goto out_key_put;
 336}
 337
 338int
 339sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
 340		struct cifs_fattr *fattr, uint sidtype)
 341{
 342	int rc = 0;
 343	struct key *sidkey;
 344	char *sidstr;
 345	const struct cred *saved_cred;
 346	kuid_t fuid = cifs_sb->ctx->linux_uid;
 347	kgid_t fgid = cifs_sb->ctx->linux_gid;
 348
 349	/*
 350	 * If we have too many subauthorities, then something is really wrong.
 351	 * Just return an error.
 352	 */
 353	if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
 354		cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
 355			 __func__, psid->num_subauth);
 356		return -EIO;
 357	}
 358
 359	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
 360	    (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
 361		uint32_t unix_id;
 362		bool is_group;
 363
 364		if (sidtype != SIDOWNER)
 365			is_group = true;
 366		else
 367			is_group = false;
 368
 369		if (is_well_known_sid(psid, &unix_id, is_group) == false)
 370			goto try_upcall_to_get_id;
 371
 372		if (is_group) {
 373			kgid_t gid;
 374			gid_t id;
 375
 376			id = (gid_t)unix_id;
 377			gid = make_kgid(&init_user_ns, id);
 378			if (gid_valid(gid)) {
 379				fgid = gid;
 380				goto got_valid_id;
 381			}
 382		} else {
 383			kuid_t uid;
 384			uid_t id;
 385
 386			id = (uid_t)unix_id;
 387			uid = make_kuid(&init_user_ns, id);
 388			if (uid_valid(uid)) {
 389				fuid = uid;
 390				goto got_valid_id;
 391			}
 392		}
 393		/* If unable to find uid/gid easily from SID try via upcall */
 394	}
 395
 396try_upcall_to_get_id:
 397	sidstr = sid_to_key_str(psid, sidtype);
 398	if (!sidstr)
 399		return -ENOMEM;
 400
 401	saved_cred = override_creds(root_cred);
 402	sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
 403	if (IS_ERR(sidkey)) {
 
 404		cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
 405			 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
 406		goto out_revert_creds;
 407	}
 408
 409	/*
 410	 * FIXME: Here we assume that uid_t and gid_t are same size. It's
 411	 * probably a safe assumption but might be better to check based on
 412	 * sidtype.
 413	 */
 414	BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
 415	if (sidkey->datalen != sizeof(uid_t)) {
 
 416		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
 417			 __func__, sidkey->datalen);
 418		key_invalidate(sidkey);
 419		goto out_key_put;
 420	}
 421
 422	if (sidtype == SIDOWNER) {
 423		kuid_t uid;
 424		uid_t id;
 425		memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
 426		uid = make_kuid(&init_user_ns, id);
 427		if (uid_valid(uid))
 428			fuid = uid;
 429	} else {
 430		kgid_t gid;
 431		gid_t id;
 432		memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
 433		gid = make_kgid(&init_user_ns, id);
 434		if (gid_valid(gid))
 435			fgid = gid;
 436	}
 437
 438out_key_put:
 439	key_put(sidkey);
 440out_revert_creds:
 441	revert_creds(saved_cred);
 442	kfree(sidstr);
 443
 444	/*
 445	 * Note that we return 0 here unconditionally. If the mapping
 446	 * fails then we just fall back to using the ctx->linux_uid/linux_gid.
 447	 */
 448got_valid_id:
 449	rc = 0;
 450	if (sidtype == SIDOWNER)
 451		fattr->cf_uid = fuid;
 452	else
 453		fattr->cf_gid = fgid;
 454	return rc;
 455}
 456
 457int
 458init_cifs_idmap(void)
 459{
 460	struct cred *cred;
 461	struct key *keyring;
 462	int ret;
 463
 464	cifs_dbg(FYI, "Registering the %s key type\n",
 465		 cifs_idmap_key_type.name);
 466
 467	/* create an override credential set with a special thread keyring in
 468	 * which requests are cached
 469	 *
 470	 * this is used to prevent malicious redirections from being installed
 471	 * with add_key().
 472	 */
 473	cred = prepare_kernel_cred(&init_task);
 474	if (!cred)
 475		return -ENOMEM;
 476
 477	keyring = keyring_alloc(".cifs_idmap",
 478				GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
 479				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
 480				KEY_USR_VIEW | KEY_USR_READ,
 481				KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
 482	if (IS_ERR(keyring)) {
 483		ret = PTR_ERR(keyring);
 484		goto failed_put_cred;
 485	}
 486
 487	ret = register_key_type(&cifs_idmap_key_type);
 488	if (ret < 0)
 489		goto failed_put_key;
 490
 491	/* instruct request_key() to use this special keyring as a cache for
 492	 * the results it looks up */
 493	set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
 494	cred->thread_keyring = keyring;
 495	cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
 496	root_cred = cred;
 497
 498	cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
 499	return 0;
 500
 501failed_put_key:
 502	key_put(keyring);
 503failed_put_cred:
 504	put_cred(cred);
 505	return ret;
 506}
 507
 508void
 509exit_cifs_idmap(void)
 510{
 511	key_revoke(root_cred->thread_keyring);
 512	unregister_key_type(&cifs_idmap_key_type);
 513	put_cred(root_cred);
 514	cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
 515}
 516
 517/* copy ntsd, owner sid, and group sid from a security descriptor to another */
 518static __u32 copy_sec_desc(const struct cifs_ntsd *pntsd,
 519				struct cifs_ntsd *pnntsd,
 520				__u32 sidsoffset,
 521				struct cifs_sid *pownersid,
 522				struct cifs_sid *pgrpsid)
 523{
 524	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
 525	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
 526
 527	/* copy security descriptor control portion */
 528	pnntsd->revision = pntsd->revision;
 529	pnntsd->type = pntsd->type;
 530	pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
 531	pnntsd->sacloffset = 0;
 532	pnntsd->osidoffset = cpu_to_le32(sidsoffset);
 533	pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
 534
 535	/* copy owner sid */
 536	if (pownersid)
 537		owner_sid_ptr = pownersid;
 538	else
 539		owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
 540				le32_to_cpu(pntsd->osidoffset));
 541	nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
 542	cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
 543
 544	/* copy group sid */
 545	if (pgrpsid)
 546		group_sid_ptr = pgrpsid;
 547	else
 548		group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
 549				le32_to_cpu(pntsd->gsidoffset));
 550	ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
 551					sizeof(struct cifs_sid));
 552	cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
 553
 554	return sidsoffset + (2 * sizeof(struct cifs_sid));
 555}
 556
 557
 558/*
 559   change posix mode to reflect permissions
 560   pmode is the existing mode (we only want to overwrite part of this
 561   bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
 562*/
 563static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
 564				 umode_t *pdenied, umode_t mask)
 565{
 566	__u32 flags = le32_to_cpu(ace_flags);
 567	/*
 568	 * Do not assume "preferred" or "canonical" order.
 569	 * The first DENY or ALLOW ACE which matches perfectly is
 570	 * the permission to be used. Once allowed or denied, same
 571	 * permission in later ACEs do not matter.
 572	 */
 573
 574	/* If not already allowed, deny these bits */
 
 575	if (type == ACCESS_DENIED) {
 576		if (flags & GENERIC_ALL &&
 577				!(*pmode & mask & 0777))
 578			*pdenied |= mask & 0777;
 579
 580		if (((flags & GENERIC_WRITE) ||
 581				((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
 582				!(*pmode & mask & 0222))
 583			*pdenied |= mask & 0222;
 584
 585		if (((flags & GENERIC_READ) ||
 586				((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
 587				!(*pmode & mask & 0444))
 588			*pdenied |= mask & 0444;
 589
 590		if (((flags & GENERIC_EXECUTE) ||
 591				((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
 592				!(*pmode & mask & 0111))
 593			*pdenied |= mask & 0111;
 594
 
 
 
 
 
 
 
 
 
 595		return;
 596	} else if (type != ACCESS_ALLOWED) {
 597		cifs_dbg(VFS, "unknown access control type %d\n", type);
 598		return;
 599	}
 600	/* else ACCESS_ALLOWED type */
 601
 602	if ((flags & GENERIC_ALL) &&
 603			!(*pdenied & mask & 0777)) {
 604		*pmode |= mask & 0777;
 605		cifs_dbg(NOISY, "all perms\n");
 606		return;
 607	}
 
 
 
 
 
 
 
 
 
 608
 609	if (((flags & GENERIC_WRITE) ||
 610			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
 611			!(*pdenied & mask & 0222))
 612		*pmode |= mask & 0222;
 613
 614	if (((flags & GENERIC_READ) ||
 615			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
 616			!(*pdenied & mask & 0444))
 617		*pmode |= mask & 0444;
 618
 619	if (((flags & GENERIC_EXECUTE) ||
 620			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
 621			!(*pdenied & mask & 0111))
 622		*pmode |= mask & 0111;
 623
 624	/* If DELETE_CHILD is set only on an owner ACE, set sticky bit */
 625	if (flags & FILE_DELETE_CHILD) {
 626		if (mask == ACL_OWNER_MASK) {
 627			if (!(*pdenied & 01000))
 628				*pmode |= 01000;
 629		} else if (!(*pdenied & 01000)) {
 630			*pmode &= ~01000;
 631			*pdenied |= 01000;
 632		}
 633	}
 634
 635	cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
 636	return;
 637}
 638
 639/*
 640   Generate access flags to reflect permissions mode is the existing mode.
 641   This function is called for every ACE in the DACL whose SID matches
 642   with either owner or group or everyone.
 643*/
 644
 645static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
 646				__u32 *pace_flags)
 647{
 648	/* reset access mask */
 649	*pace_flags = 0x0;
 650
 651	/* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
 652	mode &= bits_to_use;
 653
 654	/* check for R/W/X UGO since we do not know whose flags
 655	   is this but we have cleared all the bits sans RWX for
 656	   either user or group or other as per bits_to_use */
 657	if (mode & S_IRUGO)
 658		*pace_flags |= SET_FILE_READ_RIGHTS;
 659	if (mode & S_IWUGO)
 660		*pace_flags |= SET_FILE_WRITE_RIGHTS;
 661	if (mode & S_IXUGO)
 662		*pace_flags |= SET_FILE_EXEC_RIGHTS;
 663
 664	cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
 665		 mode, *pace_flags);
 666	return;
 667}
 668
 669static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct cifs_sid *psid)
 670{
 671	__u16 size = 1 + 1 + 2 + 4;
 672
 673	dst->type = src->type;
 674	dst->flags = src->flags;
 675	dst->access_req = src->access_req;
 676
 677	/* Check if there's a replacement sid specified */
 678	if (psid)
 679		size += cifs_copy_sid(&dst->sid, psid);
 680	else
 681		size += cifs_copy_sid(&dst->sid, &src->sid);
 682
 683	dst->size = cpu_to_le16(size);
 684
 685	return size;
 686}
 687
 688static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
 689			const struct cifs_sid *psid, __u64 nmode,
 690			umode_t bits, __u8 access_type,
 691			bool allow_delete_child)
 692{
 693	int i;
 694	__u16 size = 0;
 695	__u32 access_req = 0;
 696
 697	pntace->type = access_type;
 698	pntace->flags = 0x0;
 699	mode_to_access_flags(nmode, bits, &access_req);
 700
 701	if (access_type == ACCESS_ALLOWED && allow_delete_child)
 702		access_req |= FILE_DELETE_CHILD;
 703
 704	if (access_type == ACCESS_ALLOWED && !access_req)
 705		access_req = SET_MINIMUM_RIGHTS;
 706	else if (access_type == ACCESS_DENIED)
 707		access_req &= ~SET_MINIMUM_RIGHTS;
 708
 709	pntace->access_req = cpu_to_le32(access_req);
 710
 711	pntace->sid.revision = psid->revision;
 712	pntace->sid.num_subauth = psid->num_subauth;
 713	for (i = 0; i < NUM_AUTHS; i++)
 714		pntace->sid.authority[i] = psid->authority[i];
 715	for (i = 0; i < psid->num_subauth; i++)
 716		pntace->sid.sub_auth[i] = psid->sub_auth[i];
 717
 718	size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
 719	pntace->size = cpu_to_le16(size);
 720
 721	return size;
 722}
 723
 724
 725#ifdef CONFIG_CIFS_DEBUG2
 726static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
 727{
 728	int num_subauth;
 729
 730	/* validate that we do not go past end of acl */
 731
 732	if (le16_to_cpu(pace->size) < 16) {
 733		cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
 734		return;
 735	}
 736
 737	if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
 738		cifs_dbg(VFS, "ACL too small to parse ACE\n");
 739		return;
 740	}
 741
 742	num_subauth = pace->sid.num_subauth;
 743	if (num_subauth) {
 744		int i;
 745		cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
 746			 pace->sid.revision, pace->sid.num_subauth, pace->type,
 747			 pace->flags, le16_to_cpu(pace->size));
 748		for (i = 0; i < num_subauth; ++i) {
 749			cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
 750				 i, le32_to_cpu(pace->sid.sub_auth[i]));
 751		}
 752
 753		/* BB add length check to make sure that we do not have huge
 754			num auths and therefore go off the end */
 755	}
 756
 757	return;
 758}
 759#endif
 760
 761static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
 762		       struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
 763		       struct cifs_fattr *fattr, bool mode_from_special_sid)
 764{
 765	int i;
 766	int num_aces = 0;
 767	int acl_size;
 768	char *acl_base;
 769	struct cifs_ace **ppace;
 770
 771	/* BB need to add parm so we can store the SID BB */
 772
 773	if (!pdacl) {
 774		/* no DACL in the security descriptor, set
 775		   all the permissions for user/group/other */
 776		fattr->cf_mode |= 0777;
 777		return;
 778	}
 779
 780	/* validate that we do not go past end of acl */
 781	if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
 782		cifs_dbg(VFS, "ACL too small to parse DACL\n");
 783		return;
 784	}
 785
 786	cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
 787		 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
 788		 le32_to_cpu(pdacl->num_aces));
 789
 790	/* reset rwx permissions for user/group/other.
 791	   Also, if num_aces is 0 i.e. DACL has no ACEs,
 792	   user/group/other have no permissions */
 793	fattr->cf_mode &= ~(0777);
 794
 795	acl_base = (char *)pdacl;
 796	acl_size = sizeof(struct cifs_acl);
 797
 798	num_aces = le32_to_cpu(pdacl->num_aces);
 799	if (num_aces > 0) {
 800		umode_t denied_mode = 0;
 
 
 801
 802		if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
 803			return;
 804		ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
 805				      GFP_KERNEL);
 806		if (!ppace)
 807			return;
 808
 809		for (i = 0; i < num_aces; ++i) {
 810			ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
 811#ifdef CONFIG_CIFS_DEBUG2
 812			dump_ace(ppace[i], end_of_acl);
 813#endif
 814			if (mode_from_special_sid &&
 815			    (compare_sids(&(ppace[i]->sid),
 816					  &sid_unix_NFS_mode) == 0)) {
 817				/*
 818				 * Full permissions are:
 819				 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
 820				 *         S_IRWXU | S_IRWXG | S_IRWXO
 821				 */
 822				fattr->cf_mode &= ~07777;
 823				fattr->cf_mode |=
 824					le32_to_cpu(ppace[i]->sid.sub_auth[2]);
 825				break;
 826			} else {
 827				if (compare_sids(&(ppace[i]->sid), pownersid) == 0) {
 828					access_flags_to_mode(ppace[i]->access_req,
 829							ppace[i]->type,
 830							&fattr->cf_mode,
 831							&denied_mode,
 832							ACL_OWNER_MASK);
 833				} else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) {
 834					access_flags_to_mode(ppace[i]->access_req,
 835							ppace[i]->type,
 836							&fattr->cf_mode,
 837							&denied_mode,
 838							ACL_GROUP_MASK);
 839				} else if ((compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) ||
 840						(compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)) {
 841					access_flags_to_mode(ppace[i]->access_req,
 842							ppace[i]->type,
 843							&fattr->cf_mode,
 844							&denied_mode,
 845							ACL_EVERYONE_MASK);
 846				}
 847			}
 848
 849
 850/*			memcpy((void *)(&(cifscred->aces[i])),
 851				(void *)ppace[i],
 852				sizeof(struct cifs_ace)); */
 853
 854			acl_base = (char *)ppace[i];
 855			acl_size = le16_to_cpu(ppace[i]->size);
 856		}
 857
 858		kfree(ppace);
 859	}
 860
 861	return;
 862}
 863
 864unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
 865{
 866	int i;
 867	unsigned int ace_size = 20;
 868
 869	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
 870	pntace->flags = 0x0;
 871	pntace->access_req = cpu_to_le32(GENERIC_ALL);
 872	pntace->sid.num_subauth = 1;
 873	pntace->sid.revision = 1;
 874	for (i = 0; i < NUM_AUTHS; i++)
 875		pntace->sid.authority[i] =  sid_authusers.authority[i];
 876
 877	pntace->sid.sub_auth[0] =  sid_authusers.sub_auth[0];
 878
 879	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
 880	pntace->size = cpu_to_le16(ace_size);
 881	return ace_size;
 882}
 883
 884/*
 885 * Fill in the special SID based on the mode. See
 886 * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
 887 */
 888unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
 889{
 890	int i;
 891	unsigned int ace_size = 28;
 892
 893	pntace->type = ACCESS_DENIED_ACE_TYPE;
 894	pntace->flags = 0x0;
 895	pntace->access_req = 0;
 896	pntace->sid.num_subauth = 3;
 897	pntace->sid.revision = 1;
 898	for (i = 0; i < NUM_AUTHS; i++)
 899		pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
 900
 901	pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
 902	pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
 903	pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
 904
 905	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
 906	pntace->size = cpu_to_le16(ace_size);
 907	return ace_size;
 908}
 909
 910unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
 911{
 912	int i;
 913	unsigned int ace_size = 28;
 914
 915	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
 916	pntace->flags = 0x0;
 917	pntace->access_req = cpu_to_le32(GENERIC_ALL);
 918	pntace->sid.num_subauth = 3;
 919	pntace->sid.revision = 1;
 920	for (i = 0; i < NUM_AUTHS; i++)
 921		pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
 922
 923	pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
 924	pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
 925	pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
 926
 927	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
 928	pntace->size = cpu_to_le16(ace_size);
 929	return ace_size;
 930}
 931
 932static void populate_new_aces(char *nacl_base,
 933		struct cifs_sid *pownersid,
 934		struct cifs_sid *pgrpsid,
 935		__u64 *pnmode, u32 *pnum_aces, u16 *pnsize,
 936		bool modefromsid)
 937{
 938	__u64 nmode;
 939	u32 num_aces = 0;
 940	u16 nsize = 0;
 941	__u64 user_mode;
 942	__u64 group_mode;
 943	__u64 other_mode;
 944	__u64 deny_user_mode = 0;
 945	__u64 deny_group_mode = 0;
 946	bool sticky_set = false;
 947	struct cifs_ace *pnntace = NULL;
 948
 949	nmode = *pnmode;
 950	num_aces = *pnum_aces;
 951	nsize = *pnsize;
 952
 953	if (modefromsid) {
 954		pnntace = (struct cifs_ace *) (nacl_base + nsize);
 955		nsize += setup_special_mode_ACE(pnntace, nmode);
 956		num_aces++;
 957		pnntace = (struct cifs_ace *) (nacl_base + nsize);
 958		nsize += setup_authusers_ACE(pnntace);
 959		num_aces++;
 960		goto set_size;
 961	}
 962
 963	/*
 964	 * We'll try to keep the mode as requested by the user.
 965	 * But in cases where we cannot meaningfully convert that
 966	 * into ACL, return back the updated mode, so that it is
 967	 * updated in the inode.
 968	 */
 969
 970	if (!memcmp(pownersid, pgrpsid, sizeof(struct cifs_sid))) {
 971		/*
 972		 * Case when owner and group SIDs are the same.
 973		 * Set the more restrictive of the two modes.
 974		 */
 975		user_mode = nmode & (nmode << 3) & 0700;
 976		group_mode = nmode & (nmode >> 3) & 0070;
 977	} else {
 978		user_mode = nmode & 0700;
 979		group_mode = nmode & 0070;
 980	}
 981
 982	other_mode = nmode & 0007;
 983
 984	/* We need DENY ACE when the perm is more restrictive than the next sets. */
 985	deny_user_mode = ~(user_mode) & ((group_mode << 3) | (other_mode << 6)) & 0700;
 986	deny_group_mode = ~(group_mode) & (other_mode << 3) & 0070;
 987
 988	*pnmode = user_mode | group_mode | other_mode | (nmode & ~0777);
 989
 990	/* This tells if we should allow delete child for group and everyone. */
 991	if (nmode & 01000)
 992		sticky_set = true;
 993
 994	if (deny_user_mode) {
 995		pnntace = (struct cifs_ace *) (nacl_base + nsize);
 996		nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode,
 997				0700, ACCESS_DENIED, false);
 998		num_aces++;
 999	}
1000
1001	/* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/
1002	if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) {
1003		pnntace = (struct cifs_ace *) (nacl_base + nsize);
1004		nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1005				0070, ACCESS_DENIED, false);
 
 
 
 
 
 
 
 
 
 
1006		num_aces++;
1007	}
1008
1009	pnntace = (struct cifs_ace *) (nacl_base + nsize);
1010	nsize += fill_ace_for_sid(pnntace, pownersid, user_mode,
1011			0700, ACCESS_ALLOWED, true);
1012	num_aces++;
1013
1014	/* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */
1015	if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) {
1016		pnntace = (struct cifs_ace *) (nacl_base + nsize);
1017		nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1018				0070, ACCESS_DENIED, false);
1019		num_aces++;
1020	}
1021
1022	pnntace = (struct cifs_ace *) (nacl_base + nsize);
1023	nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode,
1024			0070, ACCESS_ALLOWED, !sticky_set);
1025	num_aces++;
1026
1027	pnntace = (struct cifs_ace *) (nacl_base + nsize);
1028	nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode,
1029			0007, ACCESS_ALLOWED, !sticky_set);
1030	num_aces++;
1031
1032set_size:
1033	*pnum_aces = num_aces;
1034	*pnsize = nsize;
1035}
1036
1037static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
1038		struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
1039		struct cifs_sid *pnownersid, struct cifs_sid *pngrpsid)
1040{
1041	int i;
1042	u16 size = 0;
1043	struct cifs_ace *pntace = NULL;
1044	char *acl_base = NULL;
1045	u32 src_num_aces = 0;
1046	u16 nsize = 0;
1047	struct cifs_ace *pnntace = NULL;
1048	char *nacl_base = NULL;
1049	u16 ace_size = 0;
1050
1051	acl_base = (char *)pdacl;
1052	size = sizeof(struct cifs_acl);
1053	src_num_aces = le32_to_cpu(pdacl->num_aces);
1054
1055	nacl_base = (char *)pndacl;
1056	nsize = sizeof(struct cifs_acl);
1057
1058	/* Go through all the ACEs */
1059	for (i = 0; i < src_num_aces; ++i) {
1060		pntace = (struct cifs_ace *) (acl_base + size);
1061		pnntace = (struct cifs_ace *) (nacl_base + nsize);
1062
1063		if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0)
1064			ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
1065		else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0)
1066			ace_size = cifs_copy_ace(pnntace, pntace, pngrpsid);
1067		else
1068			ace_size = cifs_copy_ace(pnntace, pntace, NULL);
1069
1070		size += le16_to_cpu(pntace->size);
1071		nsize += ace_size;
1072	}
1073
1074	return nsize;
1075}
1076
1077static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
1078		struct cifs_sid *pownersid,	struct cifs_sid *pgrpsid,
1079		__u64 *pnmode, bool mode_from_sid)
1080{
1081	int i;
1082	u16 size = 0;
1083	struct cifs_ace *pntace = NULL;
1084	char *acl_base = NULL;
1085	u32 src_num_aces = 0;
1086	u16 nsize = 0;
1087	struct cifs_ace *pnntace = NULL;
1088	char *nacl_base = NULL;
1089	u32 num_aces = 0;
1090	bool new_aces_set = false;
1091
1092	/* Assuming that pndacl and pnmode are never NULL */
1093	nacl_base = (char *)pndacl;
1094	nsize = sizeof(struct cifs_acl);
1095
1096	/* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
1097	if (!pdacl) {
1098		populate_new_aces(nacl_base,
1099				pownersid, pgrpsid,
1100				pnmode, &num_aces, &nsize,
1101				mode_from_sid);
1102		goto finalize_dacl;
1103	}
1104
1105	acl_base = (char *)pdacl;
1106	size = sizeof(struct cifs_acl);
1107	src_num_aces = le32_to_cpu(pdacl->num_aces);
1108
1109	/* Retain old ACEs which we can retain */
1110	for (i = 0; i < src_num_aces; ++i) {
1111		pntace = (struct cifs_ace *) (acl_base + size);
1112
1113		if (!new_aces_set && (pntace->flags & INHERITED_ACE)) {
1114			/* Place the new ACEs in between existing explicit and inherited */
1115			populate_new_aces(nacl_base,
1116					pownersid, pgrpsid,
1117					pnmode, &num_aces, &nsize,
1118					mode_from_sid);
1119
1120			new_aces_set = true;
1121		}
1122
1123		/* If it's any one of the ACE we're replacing, skip! */
1124		if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
1125				(compare_sids(&pntace->sid, pownersid) == 0) ||
1126				(compare_sids(&pntace->sid, pgrpsid) == 0) ||
1127				(compare_sids(&pntace->sid, &sid_everyone) == 0) ||
1128				(compare_sids(&pntace->sid, &sid_authusers) == 0))) {
1129			goto next_ace;
1130		}
1131
1132		/* update the pointer to the next ACE to populate*/
1133		pnntace = (struct cifs_ace *) (nacl_base + nsize);
1134
1135		nsize += cifs_copy_ace(pnntace, pntace, NULL);
1136		num_aces++;
1137
1138next_ace:
1139		size += le16_to_cpu(pntace->size);
1140	}
1141
1142	/* If inherited ACEs are not present, place the new ones at the tail */
1143	if (!new_aces_set) {
1144		populate_new_aces(nacl_base,
1145				pownersid, pgrpsid,
1146				pnmode, &num_aces, &nsize,
1147				mode_from_sid);
1148
1149		new_aces_set = true;
1150	}
1151
1152finalize_dacl:
1153	pndacl->num_aces = cpu_to_le32(num_aces);
1154	pndacl->size = cpu_to_le16(nsize);
1155
1156	return 0;
1157}
1158
 
1159static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
1160{
1161	/* BB need to add parm so we can store the SID BB */
1162
1163	/* validate that we do not go past end of ACL - sid must be at least 8
1164	   bytes long (assuming no sub-auths - e.g. the null SID */
1165	if (end_of_acl < (char *)psid + 8) {
1166		cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
1167		return -EINVAL;
1168	}
1169
1170#ifdef CONFIG_CIFS_DEBUG2
1171	if (psid->num_subauth) {
1172		int i;
1173		cifs_dbg(FYI, "SID revision %d num_auth %d\n",
1174			 psid->revision, psid->num_subauth);
1175
1176		for (i = 0; i < psid->num_subauth; i++) {
1177			cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
1178				 i, le32_to_cpu(psid->sub_auth[i]));
1179		}
1180
1181		/* BB add length check to make sure that we do not have huge
1182			num auths and therefore go off the end */
1183		cifs_dbg(FYI, "RID 0x%x\n",
1184			 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1185	}
1186#endif
1187
1188	return 0;
1189}
1190
1191
1192/* Convert CIFS ACL to POSIX form */
1193static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1194		struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
1195		bool get_mode_from_special_sid)
1196{
1197	int rc = 0;
1198	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1199	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
1200	char *end_of_acl = ((char *)pntsd) + acl_len;
1201	__u32 dacloffset;
1202
1203	if (pntsd == NULL)
1204		return -EIO;
1205
1206	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1207				le32_to_cpu(pntsd->osidoffset));
1208	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1209				le32_to_cpu(pntsd->gsidoffset));
1210	dacloffset = le32_to_cpu(pntsd->dacloffset);
1211	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1212	cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1213		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1214		 le32_to_cpu(pntsd->gsidoffset),
1215		 le32_to_cpu(pntsd->sacloffset), dacloffset);
1216/*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1217	rc = parse_sid(owner_sid_ptr, end_of_acl);
1218	if (rc) {
1219		cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1220		return rc;
1221	}
1222	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1223	if (rc) {
1224		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1225			 __func__, rc);
1226		return rc;
1227	}
1228
1229	rc = parse_sid(group_sid_ptr, end_of_acl);
1230	if (rc) {
1231		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
1232			 __func__, rc);
1233		return rc;
1234	}
1235	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1236	if (rc) {
1237		cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1238			 __func__, rc);
1239		return rc;
1240	}
1241
1242	if (dacloffset)
1243		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1244			   group_sid_ptr, fattr, get_mode_from_special_sid);
1245	else
1246		cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
1247
1248	return rc;
1249}
1250
1251/* Convert permission bits from mode to equivalent CIFS ACL */
1252static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1253	__u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
1254	bool mode_from_sid, bool id_from_sid, int *aclflag)
1255{
1256	int rc = 0;
1257	__u32 dacloffset;
1258	__u32 ndacloffset;
1259	__u32 sidsoffset;
1260	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1261	struct cifs_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
1262	struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
1263	struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1264	char *end_of_acl = ((char *)pntsd) + secdesclen;
1265	u16 size = 0;
1266
1267	dacloffset = le32_to_cpu(pntsd->dacloffset);
1268	if (dacloffset) {
 
 
 
 
1269		dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1270		if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) {
1271			cifs_dbg(VFS, "Server returned illegal ACL size\n");
1272			return -EINVAL;
1273		}
1274	}
1275
1276	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1277			le32_to_cpu(pntsd->osidoffset));
1278	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1279			le32_to_cpu(pntsd->gsidoffset));
1280
1281	if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1282		ndacloffset = sizeof(struct cifs_ntsd);
1283		ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1284		ndacl_ptr->revision =
1285			dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1286
1287		ndacl_ptr->size = cpu_to_le16(0);
1288		ndacl_ptr->num_aces = cpu_to_le32(0);
1289
1290		rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1291				    pnmode, mode_from_sid);
1292
 
 
1293		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1294		/* copy the non-dacl portion of secdesc */
1295		*pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1296				NULL, NULL);
1297
1298		*aclflag |= CIFS_ACL_DACL;
1299	} else {
1300		ndacloffset = sizeof(struct cifs_ntsd);
1301		ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1302		ndacl_ptr->revision =
1303			dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1304		ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0;
1305
1306		if (uid_valid(uid)) { /* chown */
1307			uid_t id;
1308			nowner_sid_ptr = kzalloc(sizeof(struct cifs_sid),
 
 
1309								GFP_KERNEL);
1310			if (!nowner_sid_ptr) {
1311				rc = -ENOMEM;
1312				goto chown_chgrp_exit;
1313			}
1314			id = from_kuid(&init_user_ns, uid);
1315			if (id_from_sid) {
1316				struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1317				/* Populate the user ownership fields S-1-5-88-1 */
1318				osid->Revision = 1;
1319				osid->NumAuth = 3;
1320				osid->Authority[5] = 5;
1321				osid->SubAuthorities[0] = cpu_to_le32(88);
1322				osid->SubAuthorities[1] = cpu_to_le32(1);
1323				osid->SubAuthorities[2] = cpu_to_le32(id);
1324
1325			} else { /* lookup sid with upcall */
1326				rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1327				if (rc) {
1328					cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1329						 __func__, rc, id);
1330					goto chown_chgrp_exit;
1331				}
1332			}
1333			*aclflag |= CIFS_ACL_OWNER;
 
 
1334		}
1335		if (gid_valid(gid)) { /* chgrp */
1336			gid_t id;
1337			ngroup_sid_ptr = kzalloc(sizeof(struct cifs_sid),
 
 
1338								GFP_KERNEL);
1339			if (!ngroup_sid_ptr) {
1340				rc = -ENOMEM;
1341				goto chown_chgrp_exit;
1342			}
1343			id = from_kgid(&init_user_ns, gid);
1344			if (id_from_sid) {
1345				struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1346				/* Populate the group ownership fields S-1-5-88-2 */
1347				gsid->Revision = 1;
1348				gsid->NumAuth = 3;
1349				gsid->Authority[5] = 5;
1350				gsid->SubAuthorities[0] = cpu_to_le32(88);
1351				gsid->SubAuthorities[1] = cpu_to_le32(2);
1352				gsid->SubAuthorities[2] = cpu_to_le32(id);
1353
1354			} else { /* lookup sid with upcall */
1355				rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1356				if (rc) {
1357					cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1358						 __func__, rc, id);
1359					goto chown_chgrp_exit;
1360				}
1361			}
1362			*aclflag |= CIFS_ACL_GROUP;
1363		}
1364
1365		if (dacloffset) {
1366			/* Replace ACEs for old owner with new one */
1367			size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1368					owner_sid_ptr, group_sid_ptr,
1369					nowner_sid_ptr, ngroup_sid_ptr);
1370			ndacl_ptr->size = cpu_to_le16(size);
1371		}
1372
1373		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1374		/* copy the non-dacl portion of secdesc */
1375		*pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1376				nowner_sid_ptr, ngroup_sid_ptr);
1377
1378chown_chgrp_exit:
1379		/* errors could jump here. So make sure we return soon after this */
1380		kfree(nowner_sid_ptr);
1381		kfree(ngroup_sid_ptr);
1382	}
1383
1384	return rc;
1385}
1386
1387#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1388struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1389				      const struct cifs_fid *cifsfid, u32 *pacllen,
1390				      u32 __maybe_unused unused)
1391{
1392	struct cifs_ntsd *pntsd = NULL;
1393	unsigned int xid;
1394	int rc;
1395	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1396
1397	if (IS_ERR(tlink))
1398		return ERR_CAST(tlink);
1399
1400	xid = get_xid();
1401	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1402				pacllen);
1403	free_xid(xid);
1404
1405	cifs_put_tlink(tlink);
1406
1407	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1408	if (rc)
1409		return ERR_PTR(rc);
1410	return pntsd;
1411}
1412
1413static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1414		const char *path, u32 *pacllen)
1415{
1416	struct cifs_ntsd *pntsd = NULL;
1417	int oplock = 0;
1418	unsigned int xid;
1419	int rc;
1420	struct cifs_tcon *tcon;
1421	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1422	struct cifs_fid fid;
1423	struct cifs_open_parms oparms;
1424
1425	if (IS_ERR(tlink))
1426		return ERR_CAST(tlink);
1427
1428	tcon = tlink_tcon(tlink);
1429	xid = get_xid();
1430
 
 
 
1431	oparms.tcon = tcon;
1432	oparms.cifs_sb = cifs_sb;
1433	oparms.desired_access = READ_CONTROL;
1434	oparms.create_options = cifs_create_options(cifs_sb, 0);
1435	oparms.disposition = FILE_OPEN;
1436	oparms.path = path;
1437	oparms.fid = &fid;
1438	oparms.reconnect = false;
1439
1440	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1441	if (!rc) {
1442		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1443		CIFSSMBClose(xid, tcon, fid.netfid);
1444	}
1445
1446	cifs_put_tlink(tlink);
1447	free_xid(xid);
1448
1449	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1450	if (rc)
1451		return ERR_PTR(rc);
1452	return pntsd;
1453}
1454
1455/* Retrieve an ACL from the server */
1456struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1457				      struct inode *inode, const char *path,
1458			       u32 *pacllen, u32 info)
1459{
1460	struct cifs_ntsd *pntsd = NULL;
1461	struct cifsFileInfo *open_file = NULL;
1462
1463	if (inode)
1464		open_file = find_readable_file(CIFS_I(inode), true);
1465	if (!open_file)
1466		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1467
1468	pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1469	cifsFileInfo_put(open_file);
1470	return pntsd;
1471}
1472
1473 /* Set an ACL on the server */
1474int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1475			struct inode *inode, const char *path, int aclflag)
1476{
1477	int oplock = 0;
1478	unsigned int xid;
1479	int rc, access_flags;
1480	struct cifs_tcon *tcon;
1481	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1482	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1483	struct cifs_fid fid;
1484	struct cifs_open_parms oparms;
1485
1486	if (IS_ERR(tlink))
1487		return PTR_ERR(tlink);
1488
1489	tcon = tlink_tcon(tlink);
1490	xid = get_xid();
1491
 
 
 
1492	if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1493		access_flags = WRITE_OWNER;
1494	else
1495		access_flags = WRITE_DAC;
1496
1497	oparms.tcon = tcon;
1498	oparms.cifs_sb = cifs_sb;
1499	oparms.desired_access = access_flags;
1500	oparms.create_options = cifs_create_options(cifs_sb, 0);
1501	oparms.disposition = FILE_OPEN;
1502	oparms.path = path;
1503	oparms.fid = &fid;
1504	oparms.reconnect = false;
1505
1506	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1507	if (rc) {
1508		cifs_dbg(VFS, "Unable to open file to set ACL\n");
1509		goto out;
1510	}
1511
1512	rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1513	cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1514
1515	CIFSSMBClose(xid, tcon, fid.netfid);
1516out:
1517	free_xid(xid);
1518	cifs_put_tlink(tlink);
1519	return rc;
1520}
1521#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1522
1523/* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1524int
1525cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1526		  struct inode *inode, bool mode_from_special_sid,
1527		  const char *path, const struct cifs_fid *pfid)
1528{
1529	struct cifs_ntsd *pntsd = NULL;
1530	u32 acllen = 0;
1531	int rc = 0;
1532	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1533	struct smb_version_operations *ops;
1534	const u32 info = 0;
1535
1536	cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1537
1538	if (IS_ERR(tlink))
1539		return PTR_ERR(tlink);
1540
1541	ops = tlink_tcon(tlink)->ses->server->ops;
1542
1543	if (pfid && (ops->get_acl_by_fid))
1544		pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1545	else if (ops->get_acl)
1546		pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1547	else {
1548		cifs_put_tlink(tlink);
1549		return -EOPNOTSUPP;
1550	}
1551	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1552	if (IS_ERR(pntsd)) {
1553		rc = PTR_ERR(pntsd);
1554		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1555	} else if (mode_from_special_sid) {
1556		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1557		kfree(pntsd);
1558	} else {
1559		/* get approximated mode from ACL */
1560		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1561		kfree(pntsd);
1562		if (rc)
1563			cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1564	}
1565
1566	cifs_put_tlink(tlink);
1567
1568	return rc;
1569}
1570
1571/* Convert mode bits to an ACL so we can update the ACL on the server */
1572int
1573id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1574			kuid_t uid, kgid_t gid)
1575{
1576	int rc = 0;
1577	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1578	__u32 secdesclen = 0;
1579	__u32 nsecdesclen = 0;
1580	__u32 dacloffset = 0;
1581	struct cifs_acl *dacl_ptr = NULL;
1582	struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1583	struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1584	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1585	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1586	struct smb_version_operations *ops;
1587	bool mode_from_sid, id_from_sid;
1588	const u32 info = 0;
1589
1590	if (IS_ERR(tlink))
1591		return PTR_ERR(tlink);
1592
1593	ops = tlink_tcon(tlink)->ses->server->ops;
1594
1595	cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1596
1597	/* Get the security descriptor */
1598
1599	if (ops->get_acl == NULL) {
1600		cifs_put_tlink(tlink);
1601		return -EOPNOTSUPP;
1602	}
1603
1604	pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1605	if (IS_ERR(pntsd)) {
1606		rc = PTR_ERR(pntsd);
1607		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1608		cifs_put_tlink(tlink);
1609		return rc;
1610	}
1611
1612	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1613		mode_from_sid = true;
1614	else
1615		mode_from_sid = false;
1616
1617	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1618		id_from_sid = true;
1619	else
1620		id_from_sid = false;
1621
1622	/* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1623	nsecdesclen = secdesclen;
1624	if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1625		if (mode_from_sid)
1626			nsecdesclen += 2 * sizeof(struct cifs_ace);
1627		else /* cifsacl */
1628			nsecdesclen += 5 * sizeof(struct cifs_ace);
1629	} else { /* chown */
1630		/* When ownership changes, changes new owner sid length could be different */
1631		nsecdesclen = sizeof(struct cifs_ntsd) + (sizeof(struct cifs_sid) * 2);
1632		dacloffset = le32_to_cpu(pntsd->dacloffset);
1633		if (dacloffset) {
1634			dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1635			if (mode_from_sid)
1636				nsecdesclen +=
1637					le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace);
1638			else /* cifsacl */
1639				nsecdesclen += le16_to_cpu(dacl_ptr->size);
1640		}
1641	}
1642
1643	/*
1644	 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1645	 * as chmod disables ACEs and set the security descriptor. Allocate
1646	 * memory for the smb header, set security descriptor request security
1647	 * descriptor parameters, and security descriptor itself
1648	 */
1649	nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1650	pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);
1651	if (!pnntsd) {
1652		kfree(pntsd);
1653		cifs_put_tlink(tlink);
1654		return -ENOMEM;
1655	}
1656
1657	rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1658			    mode_from_sid, id_from_sid, &aclflag);
 
 
 
 
 
1659
1660	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1661
1662	if (ops->set_acl == NULL)
1663		rc = -EOPNOTSUPP;
1664
1665	if (!rc) {
1666		/* Set the security descriptor */
1667		rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1668		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1669	}
1670	cifs_put_tlink(tlink);
1671
1672	kfree(pnntsd);
1673	kfree(pntsd);
1674	return rc;
1675}
1676
1677struct posix_acl *cifs_get_acl(struct user_namespace *mnt_userns,
1678			       struct dentry *dentry, int type)
1679{
1680#if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1681	struct posix_acl *acl = NULL;
1682	ssize_t rc = -EOPNOTSUPP;
1683	unsigned int xid;
1684	struct super_block *sb = dentry->d_sb;
1685	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1686	struct tcon_link *tlink;
1687	struct cifs_tcon *pTcon;
1688	const char *full_path;
1689	void *page;
1690
1691	tlink = cifs_sb_tlink(cifs_sb);
1692	if (IS_ERR(tlink))
1693		return ERR_CAST(tlink);
1694	pTcon = tlink_tcon(tlink);
1695
1696	xid = get_xid();
1697	page = alloc_dentry_path();
1698
1699	full_path = build_path_from_dentry(dentry, page);
1700	if (IS_ERR(full_path)) {
1701		acl = ERR_CAST(full_path);
1702		goto out;
1703	}
1704
1705	/* return alt name if available as pseudo attr */
1706	switch (type) {
1707	case ACL_TYPE_ACCESS:
1708		if (sb->s_flags & SB_POSIXACL)
1709			rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1710					     ACL_TYPE_ACCESS,
1711					     cifs_sb->local_nls,
1712					     cifs_remap(cifs_sb));
1713		break;
1714
1715	case ACL_TYPE_DEFAULT:
1716		if (sb->s_flags & SB_POSIXACL)
1717			rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1718					     ACL_TYPE_DEFAULT,
1719					     cifs_sb->local_nls,
1720					     cifs_remap(cifs_sb));
1721		break;
1722	}
1723
1724	if (rc < 0) {
1725		if (rc == -EINVAL)
1726			acl = ERR_PTR(-EOPNOTSUPP);
1727		else
1728			acl = ERR_PTR(rc);
1729	}
1730
1731out:
1732	free_dentry_path(page);
1733	free_xid(xid);
1734	cifs_put_tlink(tlink);
1735	return acl;
1736#else
1737	return ERR_PTR(-EOPNOTSUPP);
1738#endif
1739}
1740
1741int cifs_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
1742		 struct posix_acl *acl, int type)
1743{
1744#if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1745	int rc = -EOPNOTSUPP;
1746	unsigned int xid;
1747	struct super_block *sb = dentry->d_sb;
1748	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1749	struct tcon_link *tlink;
1750	struct cifs_tcon *pTcon;
1751	const char *full_path;
1752	void *page;
1753
1754	tlink = cifs_sb_tlink(cifs_sb);
1755	if (IS_ERR(tlink))
1756		return PTR_ERR(tlink);
1757	pTcon = tlink_tcon(tlink);
1758
1759	xid = get_xid();
1760	page = alloc_dentry_path();
1761
1762	full_path = build_path_from_dentry(dentry, page);
1763	if (IS_ERR(full_path)) {
1764		rc = PTR_ERR(full_path);
1765		goto out;
1766	}
1767
1768	if (!acl)
1769		goto out;
1770
1771	/* return dos attributes as pseudo xattr */
1772	/* return alt name if available as pseudo attr */
1773
1774	/* if proc/fs/cifs/streamstoxattr is set then
1775		search server for EAs or streams to
1776		returns as xattrs */
1777	if (posix_acl_xattr_size(acl->a_count) > CIFSMaxBufSize) {
1778		cifs_dbg(FYI, "size of EA value too large\n");
1779		rc = -EOPNOTSUPP;
1780		goto out;
1781	}
1782
1783	switch (type) {
1784	case ACL_TYPE_ACCESS:
1785		if (sb->s_flags & SB_POSIXACL)
1786			rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1787					     ACL_TYPE_ACCESS,
1788					     cifs_sb->local_nls,
1789					     cifs_remap(cifs_sb));
1790		break;
1791
1792	case ACL_TYPE_DEFAULT:
1793		if (sb->s_flags & SB_POSIXACL)
1794			rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1795					     ACL_TYPE_DEFAULT,
1796					     cifs_sb->local_nls,
1797					     cifs_remap(cifs_sb));
1798		break;
1799	}
1800
1801out:
1802	free_dentry_path(page);
1803	free_xid(xid);
1804	cifs_put_tlink(tlink);
1805	return rc;
1806#else
1807	return -EOPNOTSUPP;
1808#endif
1809}
v5.4
 
   1/*
   2 *   fs/cifs/cifsacl.c
   3 *
   4 *   Copyright (C) International Business Machines  Corp., 2007,2008
   5 *   Author(s): Steve French (sfrench@us.ibm.com)
   6 *
   7 *   Contains the routines for mapping CIFS/NTFS ACLs
   8 *
   9 *   This library is free software; you can redistribute it and/or modify
  10 *   it under the terms of the GNU Lesser General Public License as published
  11 *   by the Free Software Foundation; either version 2.1 of the License, or
  12 *   (at your option) any later version.
  13 *
  14 *   This library is distributed in the hope that it will be useful,
  15 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  17 *   the GNU Lesser General Public License for more details.
  18 *
  19 *   You should have received a copy of the GNU Lesser General Public License
  20 *   along with this library; if not, write to the Free Software
  21 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 */
  23
  24#include <linux/fs.h>
  25#include <linux/slab.h>
  26#include <linux/string.h>
  27#include <linux/keyctl.h>
  28#include <linux/key-type.h>
 
 
 
  29#include <keys/user-type.h>
  30#include "cifspdu.h"
  31#include "cifsglob.h"
  32#include "cifsacl.h"
  33#include "cifsproto.h"
  34#include "cifs_debug.h"
 
 
 
  35
  36/* security id for everyone/world system group */
  37static const struct cifs_sid sid_everyone = {
  38	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
  39/* security id for Authenticated Users system group */
  40static const struct cifs_sid sid_authusers = {
  41	1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
  42/* group users */
  43static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
  44
  45/* S-1-22-1 Unmapped Unix users */
  46static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
  47		{cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  48
  49/* S-1-22-2 Unmapped Unix groups */
  50static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
  51		{cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  52
  53/*
  54 * See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
  55 */
  56
  57/* S-1-5-88 MS NFS and Apple style UID/GID/mode */
  58
  59/* S-1-5-88-1 Unix uid */
  60static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
  61	{cpu_to_le32(88),
  62	 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  63
  64/* S-1-5-88-2 Unix gid */
  65static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
  66	{cpu_to_le32(88),
  67	 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  68
  69/* S-1-5-88-3 Unix mode */
  70static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
  71	{cpu_to_le32(88),
  72	 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  73
  74static const struct cred *root_cred;
  75
  76static int
  77cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
  78{
  79	char *payload;
  80
  81	/*
  82	 * If the payload is less than or equal to the size of a pointer, then
  83	 * an allocation here is wasteful. Just copy the data directly to the
  84	 * payload.value union member instead.
  85	 *
  86	 * With this however, you must check the datalen before trying to
  87	 * dereference payload.data!
  88	 */
  89	if (prep->datalen <= sizeof(key->payload)) {
  90		key->payload.data[0] = NULL;
  91		memcpy(&key->payload, prep->data, prep->datalen);
  92	} else {
  93		payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
  94		if (!payload)
  95			return -ENOMEM;
  96		key->payload.data[0] = payload;
  97	}
  98
  99	key->datalen = prep->datalen;
 100	return 0;
 101}
 102
 103static inline void
 104cifs_idmap_key_destroy(struct key *key)
 105{
 106	if (key->datalen > sizeof(key->payload))
 107		kfree(key->payload.data[0]);
 108}
 109
 110static struct key_type cifs_idmap_key_type = {
 111	.name        = "cifs.idmap",
 112	.instantiate = cifs_idmap_key_instantiate,
 113	.destroy     = cifs_idmap_key_destroy,
 114	.describe    = user_describe,
 115};
 116
 117static char *
 118sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
 119{
 120	int i, len;
 121	unsigned int saval;
 122	char *sidstr, *strptr;
 123	unsigned long long id_auth_val;
 124
 125	/* 3 bytes for prefix */
 126	sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
 127			 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
 128			 GFP_KERNEL);
 129	if (!sidstr)
 130		return sidstr;
 131
 132	strptr = sidstr;
 133	len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
 134			sidptr->revision);
 135	strptr += len;
 136
 137	/* The authority field is a single 48-bit number */
 138	id_auth_val = (unsigned long long)sidptr->authority[5];
 139	id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
 140	id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
 141	id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
 142	id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
 143	id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
 144
 145	/*
 146	 * MS-DTYP states that if the authority is >= 2^32, then it should be
 147	 * expressed as a hex value.
 148	 */
 149	if (id_auth_val <= UINT_MAX)
 150		len = sprintf(strptr, "-%llu", id_auth_val);
 151	else
 152		len = sprintf(strptr, "-0x%llx", id_auth_val);
 153
 154	strptr += len;
 155
 156	for (i = 0; i < sidptr->num_subauth; ++i) {
 157		saval = le32_to_cpu(sidptr->sub_auth[i]);
 158		len = sprintf(strptr, "-%u", saval);
 159		strptr += len;
 160	}
 161
 162	return sidstr;
 163}
 164
 165/*
 166 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
 167 * the same returns zero, if they do not match returns non-zero.
 168 */
 169static int
 170compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
 171{
 172	int i;
 173	int num_subauth, num_sat, num_saw;
 174
 175	if ((!ctsid) || (!cwsid))
 176		return 1;
 177
 178	/* compare the revision */
 179	if (ctsid->revision != cwsid->revision) {
 180		if (ctsid->revision > cwsid->revision)
 181			return 1;
 182		else
 183			return -1;
 184	}
 185
 186	/* compare all of the six auth values */
 187	for (i = 0; i < NUM_AUTHS; ++i) {
 188		if (ctsid->authority[i] != cwsid->authority[i]) {
 189			if (ctsid->authority[i] > cwsid->authority[i])
 190				return 1;
 191			else
 192				return -1;
 193		}
 194	}
 195
 196	/* compare all of the subauth values if any */
 197	num_sat = ctsid->num_subauth;
 198	num_saw = cwsid->num_subauth;
 199	num_subauth = num_sat < num_saw ? num_sat : num_saw;
 200	if (num_subauth) {
 201		for (i = 0; i < num_subauth; ++i) {
 202			if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
 203				if (le32_to_cpu(ctsid->sub_auth[i]) >
 204					le32_to_cpu(cwsid->sub_auth[i]))
 205					return 1;
 206				else
 207					return -1;
 208			}
 209		}
 210	}
 211
 212	return 0; /* sids compare/match */
 213}
 214
 215static bool
 216is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
 217{
 218	int i;
 219	int num_subauth;
 220	const struct cifs_sid *pwell_known_sid;
 221
 222	if (!psid || (puid == NULL))
 223		return false;
 224
 225	num_subauth = psid->num_subauth;
 226
 227	/* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
 228	if (num_subauth == 2) {
 229		if (is_group)
 230			pwell_known_sid = &sid_unix_groups;
 231		else
 232			pwell_known_sid = &sid_unix_users;
 233	} else if (num_subauth == 3) {
 234		if (is_group)
 235			pwell_known_sid = &sid_unix_NFS_groups;
 236		else
 237			pwell_known_sid = &sid_unix_NFS_users;
 238	} else
 239		return false;
 240
 241	/* compare the revision */
 242	if (psid->revision != pwell_known_sid->revision)
 243		return false;
 244
 245	/* compare all of the six auth values */
 246	for (i = 0; i < NUM_AUTHS; ++i) {
 247		if (psid->authority[i] != pwell_known_sid->authority[i]) {
 248			cifs_dbg(FYI, "auth %d did not match\n", i);
 249			return false;
 250		}
 251	}
 252
 253	if (num_subauth == 2) {
 254		if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
 255			return false;
 256
 257		*puid = le32_to_cpu(psid->sub_auth[1]);
 258	} else /* 3 subauths, ie Windows/Mac style */ {
 259		*puid = le32_to_cpu(psid->sub_auth[0]);
 260		if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
 261		    (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
 262			return false;
 263
 264		*puid = le32_to_cpu(psid->sub_auth[2]);
 265	}
 266
 267	cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
 268	return true; /* well known sid found, uid returned */
 269}
 270
 271static void
 272cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
 273{
 274	int i;
 
 275
 276	dst->revision = src->revision;
 277	dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
 278	for (i = 0; i < NUM_AUTHS; ++i)
 279		dst->authority[i] = src->authority[i];
 280	for (i = 0; i < dst->num_subauth; ++i)
 281		dst->sub_auth[i] = src->sub_auth[i];
 
 
 
 282}
 283
 284static int
 285id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
 286{
 287	int rc;
 288	struct key *sidkey;
 289	struct cifs_sid *ksid;
 290	unsigned int ksid_size;
 291	char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
 292	const struct cred *saved_cred;
 293
 294	rc = snprintf(desc, sizeof(desc), "%ci:%u",
 295			sidtype == SIDOWNER ? 'o' : 'g', cid);
 296	if (rc >= sizeof(desc))
 297		return -EINVAL;
 298
 299	rc = 0;
 300	saved_cred = override_creds(root_cred);
 301	sidkey = request_key(&cifs_idmap_key_type, desc, "");
 302	if (IS_ERR(sidkey)) {
 303		rc = -EINVAL;
 304		cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
 305			 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
 306		goto out_revert_creds;
 307	} else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
 308		rc = -EIO;
 309		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
 310			 __func__, sidkey->datalen);
 311		goto invalidate_key;
 312	}
 313
 314	/*
 315	 * A sid is usually too large to be embedded in payload.value, but if
 316	 * there are no subauthorities and the host has 8-byte pointers, then
 317	 * it could be.
 318	 */
 319	ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
 320		(struct cifs_sid *)&sidkey->payload :
 321		(struct cifs_sid *)sidkey->payload.data[0];
 322
 323	ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
 324	if (ksid_size > sidkey->datalen) {
 325		rc = -EIO;
 326		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
 327			 __func__, sidkey->datalen, ksid_size);
 328		goto invalidate_key;
 329	}
 330
 331	cifs_copy_sid(ssid, ksid);
 332out_key_put:
 333	key_put(sidkey);
 334out_revert_creds:
 335	revert_creds(saved_cred);
 336	return rc;
 337
 338invalidate_key:
 339	key_invalidate(sidkey);
 340	goto out_key_put;
 341}
 342
 343static int
 344sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
 345		struct cifs_fattr *fattr, uint sidtype)
 346{
 347	int rc;
 348	struct key *sidkey;
 349	char *sidstr;
 350	const struct cred *saved_cred;
 351	kuid_t fuid = cifs_sb->mnt_uid;
 352	kgid_t fgid = cifs_sb->mnt_gid;
 353
 354	/*
 355	 * If we have too many subauthorities, then something is really wrong.
 356	 * Just return an error.
 357	 */
 358	if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
 359		cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
 360			 __func__, psid->num_subauth);
 361		return -EIO;
 362	}
 363
 364	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) {
 
 365		uint32_t unix_id;
 366		bool is_group;
 367
 368		if (sidtype != SIDOWNER)
 369			is_group = true;
 370		else
 371			is_group = false;
 372
 373		if (is_well_known_sid(psid, &unix_id, is_group) == false)
 374			goto try_upcall_to_get_id;
 375
 376		if (is_group) {
 377			kgid_t gid;
 378			gid_t id;
 379
 380			id = (gid_t)unix_id;
 381			gid = make_kgid(&init_user_ns, id);
 382			if (gid_valid(gid)) {
 383				fgid = gid;
 384				goto got_valid_id;
 385			}
 386		} else {
 387			kuid_t uid;
 388			uid_t id;
 389
 390			id = (uid_t)unix_id;
 391			uid = make_kuid(&init_user_ns, id);
 392			if (uid_valid(uid)) {
 393				fuid = uid;
 394				goto got_valid_id;
 395			}
 396		}
 397		/* If unable to find uid/gid easily from SID try via upcall */
 398	}
 399
 400try_upcall_to_get_id:
 401	sidstr = sid_to_key_str(psid, sidtype);
 402	if (!sidstr)
 403		return -ENOMEM;
 404
 405	saved_cred = override_creds(root_cred);
 406	sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
 407	if (IS_ERR(sidkey)) {
 408		rc = -EINVAL;
 409		cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
 410			 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
 411		goto out_revert_creds;
 412	}
 413
 414	/*
 415	 * FIXME: Here we assume that uid_t and gid_t are same size. It's
 416	 * probably a safe assumption but might be better to check based on
 417	 * sidtype.
 418	 */
 419	BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
 420	if (sidkey->datalen != sizeof(uid_t)) {
 421		rc = -EIO;
 422		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
 423			 __func__, sidkey->datalen);
 424		key_invalidate(sidkey);
 425		goto out_key_put;
 426	}
 427
 428	if (sidtype == SIDOWNER) {
 429		kuid_t uid;
 430		uid_t id;
 431		memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
 432		uid = make_kuid(&init_user_ns, id);
 433		if (uid_valid(uid))
 434			fuid = uid;
 435	} else {
 436		kgid_t gid;
 437		gid_t id;
 438		memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
 439		gid = make_kgid(&init_user_ns, id);
 440		if (gid_valid(gid))
 441			fgid = gid;
 442	}
 443
 444out_key_put:
 445	key_put(sidkey);
 446out_revert_creds:
 447	revert_creds(saved_cred);
 448	kfree(sidstr);
 449
 450	/*
 451	 * Note that we return 0 here unconditionally. If the mapping
 452	 * fails then we just fall back to using the mnt_uid/mnt_gid.
 453	 */
 454got_valid_id:
 
 455	if (sidtype == SIDOWNER)
 456		fattr->cf_uid = fuid;
 457	else
 458		fattr->cf_gid = fgid;
 459	return 0;
 460}
 461
 462int
 463init_cifs_idmap(void)
 464{
 465	struct cred *cred;
 466	struct key *keyring;
 467	int ret;
 468
 469	cifs_dbg(FYI, "Registering the %s key type\n",
 470		 cifs_idmap_key_type.name);
 471
 472	/* create an override credential set with a special thread keyring in
 473	 * which requests are cached
 474	 *
 475	 * this is used to prevent malicious redirections from being installed
 476	 * with add_key().
 477	 */
 478	cred = prepare_kernel_cred(NULL);
 479	if (!cred)
 480		return -ENOMEM;
 481
 482	keyring = keyring_alloc(".cifs_idmap",
 483				GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
 484				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
 485				KEY_USR_VIEW | KEY_USR_READ,
 486				KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
 487	if (IS_ERR(keyring)) {
 488		ret = PTR_ERR(keyring);
 489		goto failed_put_cred;
 490	}
 491
 492	ret = register_key_type(&cifs_idmap_key_type);
 493	if (ret < 0)
 494		goto failed_put_key;
 495
 496	/* instruct request_key() to use this special keyring as a cache for
 497	 * the results it looks up */
 498	set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
 499	cred->thread_keyring = keyring;
 500	cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
 501	root_cred = cred;
 502
 503	cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
 504	return 0;
 505
 506failed_put_key:
 507	key_put(keyring);
 508failed_put_cred:
 509	put_cred(cred);
 510	return ret;
 511}
 512
 513void
 514exit_cifs_idmap(void)
 515{
 516	key_revoke(root_cred->thread_keyring);
 517	unregister_key_type(&cifs_idmap_key_type);
 518	put_cred(root_cred);
 519	cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
 520}
 521
 522/* copy ntsd, owner sid, and group sid from a security descriptor to another */
 523static void copy_sec_desc(const struct cifs_ntsd *pntsd,
 524				struct cifs_ntsd *pnntsd, __u32 sidsoffset)
 
 
 
 525{
 526	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
 527	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
 528
 529	/* copy security descriptor control portion */
 530	pnntsd->revision = pntsd->revision;
 531	pnntsd->type = pntsd->type;
 532	pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
 533	pnntsd->sacloffset = 0;
 534	pnntsd->osidoffset = cpu_to_le32(sidsoffset);
 535	pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
 536
 537	/* copy owner sid */
 538	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
 
 
 
 539				le32_to_cpu(pntsd->osidoffset));
 540	nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
 541	cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
 542
 543	/* copy group sid */
 544	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
 
 
 
 545				le32_to_cpu(pntsd->gsidoffset));
 546	ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
 547					sizeof(struct cifs_sid));
 548	cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
 549
 550	return;
 551}
 552
 553
 554/*
 555   change posix mode to reflect permissions
 556   pmode is the existing mode (we only want to overwrite part of this
 557   bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
 558*/
 559static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
 560				 umode_t *pbits_to_set)
 561{
 562	__u32 flags = le32_to_cpu(ace_flags);
 563	/* the order of ACEs is important.  The canonical order is to begin with
 564	   DENY entries followed by ALLOW, otherwise an allow entry could be
 565	   encountered first, making the subsequent deny entry like "dead code"
 566	   which would be superflous since Windows stops when a match is made
 567	   for the operation you are trying to perform for your user */
 
 568
 569	/* For deny ACEs we change the mask so that subsequent allow access
 570	   control entries do not turn on the bits we are denying */
 571	if (type == ACCESS_DENIED) {
 572		if (flags & GENERIC_ALL)
 573			*pbits_to_set &= ~S_IRWXUGO;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 574
 575		if ((flags & GENERIC_WRITE) ||
 576			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
 577			*pbits_to_set &= ~S_IWUGO;
 578		if ((flags & GENERIC_READ) ||
 579			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
 580			*pbits_to_set &= ~S_IRUGO;
 581		if ((flags & GENERIC_EXECUTE) ||
 582			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
 583			*pbits_to_set &= ~S_IXUGO;
 584		return;
 585	} else if (type != ACCESS_ALLOWED) {
 586		cifs_dbg(VFS, "unknown access control type %d\n", type);
 587		return;
 588	}
 589	/* else ACCESS_ALLOWED type */
 590
 591	if (flags & GENERIC_ALL) {
 592		*pmode |= (S_IRWXUGO & (*pbits_to_set));
 
 593		cifs_dbg(NOISY, "all perms\n");
 594		return;
 595	}
 596	if ((flags & GENERIC_WRITE) ||
 597			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
 598		*pmode |= (S_IWUGO & (*pbits_to_set));
 599	if ((flags & GENERIC_READ) ||
 600			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
 601		*pmode |= (S_IRUGO & (*pbits_to_set));
 602	if ((flags & GENERIC_EXECUTE) ||
 603			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
 604		*pmode |= (S_IXUGO & (*pbits_to_set));
 605
 606	cifs_dbg(NOISY, "access flags 0x%x mode now 0x%x\n", flags, *pmode);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 607	return;
 608}
 609
 610/*
 611   Generate access flags to reflect permissions mode is the existing mode.
 612   This function is called for every ACE in the DACL whose SID matches
 613   with either owner or group or everyone.
 614*/
 615
 616static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
 617				__u32 *pace_flags)
 618{
 619	/* reset access mask */
 620	*pace_flags = 0x0;
 621
 622	/* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
 623	mode &= bits_to_use;
 624
 625	/* check for R/W/X UGO since we do not know whose flags
 626	   is this but we have cleared all the bits sans RWX for
 627	   either user or group or other as per bits_to_use */
 628	if (mode & S_IRUGO)
 629		*pace_flags |= SET_FILE_READ_RIGHTS;
 630	if (mode & S_IWUGO)
 631		*pace_flags |= SET_FILE_WRITE_RIGHTS;
 632	if (mode & S_IXUGO)
 633		*pace_flags |= SET_FILE_EXEC_RIGHTS;
 634
 635	cifs_dbg(NOISY, "mode: 0x%x, access flags now 0x%x\n",
 636		 mode, *pace_flags);
 637	return;
 638}
 639
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 640static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
 641			const struct cifs_sid *psid, __u64 nmode, umode_t bits)
 
 
 642{
 643	int i;
 644	__u16 size = 0;
 645	__u32 access_req = 0;
 646
 647	pntace->type = ACCESS_ALLOWED;
 648	pntace->flags = 0x0;
 649	mode_to_access_flags(nmode, bits, &access_req);
 650	if (!access_req)
 
 
 
 
 651		access_req = SET_MINIMUM_RIGHTS;
 
 
 
 652	pntace->access_req = cpu_to_le32(access_req);
 653
 654	pntace->sid.revision = psid->revision;
 655	pntace->sid.num_subauth = psid->num_subauth;
 656	for (i = 0; i < NUM_AUTHS; i++)
 657		pntace->sid.authority[i] = psid->authority[i];
 658	for (i = 0; i < psid->num_subauth; i++)
 659		pntace->sid.sub_auth[i] = psid->sub_auth[i];
 660
 661	size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
 662	pntace->size = cpu_to_le16(size);
 663
 664	return size;
 665}
 666
 667
 668#ifdef CONFIG_CIFS_DEBUG2
 669static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
 670{
 671	int num_subauth;
 672
 673	/* validate that we do not go past end of acl */
 674
 675	if (le16_to_cpu(pace->size) < 16) {
 676		cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
 677		return;
 678	}
 679
 680	if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
 681		cifs_dbg(VFS, "ACL too small to parse ACE\n");
 682		return;
 683	}
 684
 685	num_subauth = pace->sid.num_subauth;
 686	if (num_subauth) {
 687		int i;
 688		cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
 689			 pace->sid.revision, pace->sid.num_subauth, pace->type,
 690			 pace->flags, le16_to_cpu(pace->size));
 691		for (i = 0; i < num_subauth; ++i) {
 692			cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
 693				 i, le32_to_cpu(pace->sid.sub_auth[i]));
 694		}
 695
 696		/* BB add length check to make sure that we do not have huge
 697			num auths and therefore go off the end */
 698	}
 699
 700	return;
 701}
 702#endif
 703
 704static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
 705		       struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
 706		       struct cifs_fattr *fattr, bool mode_from_special_sid)
 707{
 708	int i;
 709	int num_aces = 0;
 710	int acl_size;
 711	char *acl_base;
 712	struct cifs_ace **ppace;
 713
 714	/* BB need to add parm so we can store the SID BB */
 715
 716	if (!pdacl) {
 717		/* no DACL in the security descriptor, set
 718		   all the permissions for user/group/other */
 719		fattr->cf_mode |= S_IRWXUGO;
 720		return;
 721	}
 722
 723	/* validate that we do not go past end of acl */
 724	if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
 725		cifs_dbg(VFS, "ACL too small to parse DACL\n");
 726		return;
 727	}
 728
 729	cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
 730		 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
 731		 le32_to_cpu(pdacl->num_aces));
 732
 733	/* reset rwx permissions for user/group/other.
 734	   Also, if num_aces is 0 i.e. DACL has no ACEs,
 735	   user/group/other have no permissions */
 736	fattr->cf_mode &= ~(S_IRWXUGO);
 737
 738	acl_base = (char *)pdacl;
 739	acl_size = sizeof(struct cifs_acl);
 740
 741	num_aces = le32_to_cpu(pdacl->num_aces);
 742	if (num_aces > 0) {
 743		umode_t user_mask = S_IRWXU;
 744		umode_t group_mask = S_IRWXG;
 745		umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
 746
 747		if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
 748			return;
 749		ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
 750				      GFP_KERNEL);
 751		if (!ppace)
 752			return;
 753
 754		for (i = 0; i < num_aces; ++i) {
 755			ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
 756#ifdef CONFIG_CIFS_DEBUG2
 757			dump_ace(ppace[i], end_of_acl);
 758#endif
 759			if (mode_from_special_sid &&
 760			    (compare_sids(&(ppace[i]->sid),
 761					  &sid_unix_NFS_mode) == 0)) {
 762				/*
 763				 * Full permissions are:
 764				 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
 765				 *         S_IRWXU | S_IRWXG | S_IRWXO
 766				 */
 767				fattr->cf_mode &= ~07777;
 768				fattr->cf_mode |=
 769					le32_to_cpu(ppace[i]->sid.sub_auth[2]);
 770				break;
 771			} else if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
 772				access_flags_to_mode(ppace[i]->access_req,
 773						     ppace[i]->type,
 774						     &fattr->cf_mode,
 775						     &user_mask);
 776			else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
 777				access_flags_to_mode(ppace[i]->access_req,
 778						     ppace[i]->type,
 779						     &fattr->cf_mode,
 780						     &group_mask);
 781			else if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
 782				access_flags_to_mode(ppace[i]->access_req,
 783						     ppace[i]->type,
 784						     &fattr->cf_mode,
 785						     &other_mask);
 786			else if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
 787				access_flags_to_mode(ppace[i]->access_req,
 788						     ppace[i]->type,
 789						     &fattr->cf_mode,
 790						     &other_mask);
 
 
 791
 792
 793/*			memcpy((void *)(&(cifscred->aces[i])),
 794				(void *)ppace[i],
 795				sizeof(struct cifs_ace)); */
 796
 797			acl_base = (char *)ppace[i];
 798			acl_size = le16_to_cpu(ppace[i]->size);
 799		}
 800
 801		kfree(ppace);
 802	}
 803
 804	return;
 805}
 806
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 807
 808static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
 809			struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
 
 
 
 810{
 811	u16 size = 0;
 812	u32 num_aces = 0;
 813	struct cifs_acl *pnndacl;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 814
 815	pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
 
 
 816
 817	if (modefromsid) {
 818		struct cifs_ace *pntace =
 819			(struct cifs_ace *)((char *)pnndacl + size);
 820		int i;
 
 
 821
 822		pntace->type = ACCESS_ALLOWED;
 823		pntace->flags = 0x0;
 824		pntace->access_req = 0;
 825		pntace->sid.num_subauth = 3;
 826		pntace->sid.revision = 1;
 827		for (i = 0; i < NUM_AUTHS; i++)
 828			pntace->sid.authority[i] =
 829				sid_unix_NFS_mode.authority[i];
 830		pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
 831		pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
 832		pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
 833
 834		/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
 835		pntace->size = cpu_to_le16(28);
 836		size += 28;
 837		num_aces++;
 838	}
 839
 840	size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
 841					pownersid, nmode, S_IRWXU);
 
 842	num_aces++;
 843	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
 844					pgrpsid, nmode, S_IRWXG);
 
 
 
 
 
 
 
 
 
 
 845	num_aces++;
 846	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
 847					 &sid_everyone, nmode, S_IRWXO);
 
 
 848	num_aces++;
 849
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 850	pndacl->num_aces = cpu_to_le32(num_aces);
 851	pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
 852
 853	return 0;
 854}
 855
 856
 857static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
 858{
 859	/* BB need to add parm so we can store the SID BB */
 860
 861	/* validate that we do not go past end of ACL - sid must be at least 8
 862	   bytes long (assuming no sub-auths - e.g. the null SID */
 863	if (end_of_acl < (char *)psid + 8) {
 864		cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
 865		return -EINVAL;
 866	}
 867
 868#ifdef CONFIG_CIFS_DEBUG2
 869	if (psid->num_subauth) {
 870		int i;
 871		cifs_dbg(FYI, "SID revision %d num_auth %d\n",
 872			 psid->revision, psid->num_subauth);
 873
 874		for (i = 0; i < psid->num_subauth; i++) {
 875			cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
 876				 i, le32_to_cpu(psid->sub_auth[i]));
 877		}
 878
 879		/* BB add length check to make sure that we do not have huge
 880			num auths and therefore go off the end */
 881		cifs_dbg(FYI, "RID 0x%x\n",
 882			 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
 883	}
 884#endif
 885
 886	return 0;
 887}
 888
 889
 890/* Convert CIFS ACL to POSIX form */
 891static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
 892		struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
 893		bool get_mode_from_special_sid)
 894{
 895	int rc = 0;
 896	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
 897	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
 898	char *end_of_acl = ((char *)pntsd) + acl_len;
 899	__u32 dacloffset;
 900
 901	if (pntsd == NULL)
 902		return -EIO;
 903
 904	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
 905				le32_to_cpu(pntsd->osidoffset));
 906	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
 907				le32_to_cpu(pntsd->gsidoffset));
 908	dacloffset = le32_to_cpu(pntsd->dacloffset);
 909	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
 910	cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
 911		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
 912		 le32_to_cpu(pntsd->gsidoffset),
 913		 le32_to_cpu(pntsd->sacloffset), dacloffset);
 914/*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
 915	rc = parse_sid(owner_sid_ptr, end_of_acl);
 916	if (rc) {
 917		cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
 918		return rc;
 919	}
 920	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
 921	if (rc) {
 922		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
 923			 __func__, rc);
 924		return rc;
 925	}
 926
 927	rc = parse_sid(group_sid_ptr, end_of_acl);
 928	if (rc) {
 929		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
 930			 __func__, rc);
 931		return rc;
 932	}
 933	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
 934	if (rc) {
 935		cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
 936			 __func__, rc);
 937		return rc;
 938	}
 939
 940	if (dacloffset)
 941		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
 942			   group_sid_ptr, fattr, get_mode_from_special_sid);
 943	else
 944		cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
 945
 946	return rc;
 947}
 948
 949/* Convert permission bits from mode to equivalent CIFS ACL */
 950static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
 951	__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid,
 952	bool mode_from_sid, int *aclflag)
 953{
 954	int rc = 0;
 955	__u32 dacloffset;
 956	__u32 ndacloffset;
 957	__u32 sidsoffset;
 958	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
 959	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
 960	struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
 961	struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
 
 
 962
 963	if (nmode != NO_CHANGE_64) { /* chmod */
 964		owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
 965				le32_to_cpu(pntsd->osidoffset));
 966		group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
 967				le32_to_cpu(pntsd->gsidoffset));
 968		dacloffset = le32_to_cpu(pntsd->dacloffset);
 969		dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
 
 
 
 
 
 
 
 
 
 
 
 
 970		ndacloffset = sizeof(struct cifs_ntsd);
 971		ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
 972		ndacl_ptr->revision = dacl_ptr->revision;
 973		ndacl_ptr->size = 0;
 974		ndacl_ptr->num_aces = 0;
 
 
 
 
 
 975
 976		rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
 977				    nmode, mode_from_sid);
 978		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
 979		/* copy sec desc control portion & owner and group sids */
 980		copy_sec_desc(pntsd, pnntsd, sidsoffset);
 981		*aclflag = CIFS_ACL_DACL;
 
 
 982	} else {
 983		memcpy(pnntsd, pntsd, secdesclen);
 
 
 
 
 
 984		if (uid_valid(uid)) { /* chown */
 985			uid_t id;
 986			owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
 987					le32_to_cpu(pnntsd->osidoffset));
 988			nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
 989								GFP_KERNEL);
 990			if (!nowner_sid_ptr)
 991				return -ENOMEM;
 
 
 992			id = from_kuid(&init_user_ns, uid);
 993			rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
 994			if (rc) {
 995				cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
 996					 __func__, rc, id);
 997				kfree(nowner_sid_ptr);
 998				return rc;
 
 
 
 
 
 
 
 
 
 
 
 999			}
1000			cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
1001			kfree(nowner_sid_ptr);
1002			*aclflag = CIFS_ACL_OWNER;
1003		}
1004		if (gid_valid(gid)) { /* chgrp */
1005			gid_t id;
1006			group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1007					le32_to_cpu(pnntsd->gsidoffset));
1008			ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1009								GFP_KERNEL);
1010			if (!ngroup_sid_ptr)
1011				return -ENOMEM;
 
 
1012			id = from_kgid(&init_user_ns, gid);
1013			rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1014			if (rc) {
1015				cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1016					 __func__, rc, id);
1017				kfree(ngroup_sid_ptr);
1018				return rc;
 
 
 
 
 
 
 
 
 
 
 
1019			}
1020			cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
1021			kfree(ngroup_sid_ptr);
1022			*aclflag = CIFS_ACL_GROUP;
 
 
 
 
 
 
1023		}
 
 
 
 
 
 
 
 
 
 
1024	}
1025
1026	return rc;
1027}
1028
 
1029struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1030		const struct cifs_fid *cifsfid, u32 *pacllen)
 
1031{
1032	struct cifs_ntsd *pntsd = NULL;
1033	unsigned int xid;
1034	int rc;
1035	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1036
1037	if (IS_ERR(tlink))
1038		return ERR_CAST(tlink);
1039
1040	xid = get_xid();
1041	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1042				pacllen);
1043	free_xid(xid);
1044
1045	cifs_put_tlink(tlink);
1046
1047	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1048	if (rc)
1049		return ERR_PTR(rc);
1050	return pntsd;
1051}
1052
1053static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1054		const char *path, u32 *pacllen)
1055{
1056	struct cifs_ntsd *pntsd = NULL;
1057	int oplock = 0;
1058	unsigned int xid;
1059	int rc, create_options = 0;
1060	struct cifs_tcon *tcon;
1061	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1062	struct cifs_fid fid;
1063	struct cifs_open_parms oparms;
1064
1065	if (IS_ERR(tlink))
1066		return ERR_CAST(tlink);
1067
1068	tcon = tlink_tcon(tlink);
1069	xid = get_xid();
1070
1071	if (backup_cred(cifs_sb))
1072		create_options |= CREATE_OPEN_BACKUP_INTENT;
1073
1074	oparms.tcon = tcon;
1075	oparms.cifs_sb = cifs_sb;
1076	oparms.desired_access = READ_CONTROL;
1077	oparms.create_options = create_options;
1078	oparms.disposition = FILE_OPEN;
1079	oparms.path = path;
1080	oparms.fid = &fid;
1081	oparms.reconnect = false;
1082
1083	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1084	if (!rc) {
1085		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1086		CIFSSMBClose(xid, tcon, fid.netfid);
1087	}
1088
1089	cifs_put_tlink(tlink);
1090	free_xid(xid);
1091
1092	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1093	if (rc)
1094		return ERR_PTR(rc);
1095	return pntsd;
1096}
1097
1098/* Retrieve an ACL from the server */
1099struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1100				      struct inode *inode, const char *path,
1101				      u32 *pacllen)
1102{
1103	struct cifs_ntsd *pntsd = NULL;
1104	struct cifsFileInfo *open_file = NULL;
1105
1106	if (inode)
1107		open_file = find_readable_file(CIFS_I(inode), true);
1108	if (!open_file)
1109		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1110
1111	pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
1112	cifsFileInfo_put(open_file);
1113	return pntsd;
1114}
1115
1116 /* Set an ACL on the server */
1117int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1118			struct inode *inode, const char *path, int aclflag)
1119{
1120	int oplock = 0;
1121	unsigned int xid;
1122	int rc, access_flags, create_options = 0;
1123	struct cifs_tcon *tcon;
1124	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1125	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1126	struct cifs_fid fid;
1127	struct cifs_open_parms oparms;
1128
1129	if (IS_ERR(tlink))
1130		return PTR_ERR(tlink);
1131
1132	tcon = tlink_tcon(tlink);
1133	xid = get_xid();
1134
1135	if (backup_cred(cifs_sb))
1136		create_options |= CREATE_OPEN_BACKUP_INTENT;
1137
1138	if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1139		access_flags = WRITE_OWNER;
1140	else
1141		access_flags = WRITE_DAC;
1142
1143	oparms.tcon = tcon;
1144	oparms.cifs_sb = cifs_sb;
1145	oparms.desired_access = access_flags;
1146	oparms.create_options = create_options;
1147	oparms.disposition = FILE_OPEN;
1148	oparms.path = path;
1149	oparms.fid = &fid;
1150	oparms.reconnect = false;
1151
1152	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1153	if (rc) {
1154		cifs_dbg(VFS, "Unable to open file to set ACL\n");
1155		goto out;
1156	}
1157
1158	rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1159	cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1160
1161	CIFSSMBClose(xid, tcon, fid.netfid);
1162out:
1163	free_xid(xid);
1164	cifs_put_tlink(tlink);
1165	return rc;
1166}
 
1167
1168/* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1169int
1170cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1171		  struct inode *inode, bool mode_from_special_sid,
1172		  const char *path, const struct cifs_fid *pfid)
1173{
1174	struct cifs_ntsd *pntsd = NULL;
1175	u32 acllen = 0;
1176	int rc = 0;
1177	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1178	struct smb_version_operations *ops;
 
1179
1180	cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1181
1182	if (IS_ERR(tlink))
1183		return PTR_ERR(tlink);
1184
1185	ops = tlink_tcon(tlink)->ses->server->ops;
1186
1187	if (pfid && (ops->get_acl_by_fid))
1188		pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
1189	else if (ops->get_acl)
1190		pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
1191	else {
1192		cifs_put_tlink(tlink);
1193		return -EOPNOTSUPP;
1194	}
1195	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1196	if (IS_ERR(pntsd)) {
1197		rc = PTR_ERR(pntsd);
1198		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1199	} else if (mode_from_special_sid) {
1200		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
 
1201	} else {
1202		/* get approximated mode from ACL */
1203		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1204		kfree(pntsd);
1205		if (rc)
1206			cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1207	}
1208
1209	cifs_put_tlink(tlink);
1210
1211	return rc;
1212}
1213
1214/* Convert mode bits to an ACL so we can update the ACL on the server */
1215int
1216id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1217			kuid_t uid, kgid_t gid)
1218{
1219	int rc = 0;
1220	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1221	__u32 secdesclen = 0;
 
 
 
1222	struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1223	struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1224	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1225	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1226	struct smb_version_operations *ops;
1227	bool mode_from_sid;
 
1228
1229	if (IS_ERR(tlink))
1230		return PTR_ERR(tlink);
1231
1232	ops = tlink_tcon(tlink)->ses->server->ops;
1233
1234	cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1235
1236	/* Get the security descriptor */
1237
1238	if (ops->get_acl == NULL) {
1239		cifs_put_tlink(tlink);
1240		return -EOPNOTSUPP;
1241	}
1242
1243	pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
1244	if (IS_ERR(pntsd)) {
1245		rc = PTR_ERR(pntsd);
1246		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1247		cifs_put_tlink(tlink);
1248		return rc;
1249	}
1250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1251	/*
1252	 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1253	 * as chmod disables ACEs and set the security descriptor. Allocate
1254	 * memory for the smb header, set security descriptor request security
1255	 * descriptor parameters, and secuirty descriptor itself
1256	 */
1257	secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1258	pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1259	if (!pnntsd) {
1260		kfree(pntsd);
1261		cifs_put_tlink(tlink);
1262		return -ENOMEM;
1263	}
1264
1265	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1266		mode_from_sid = true;
1267	else
1268		mode_from_sid = false;
1269
1270	rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1271			    mode_from_sid, &aclflag);
1272
1273	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1274
1275	if (ops->set_acl == NULL)
1276		rc = -EOPNOTSUPP;
1277
1278	if (!rc) {
1279		/* Set the security descriptor */
1280		rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
1281		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1282	}
1283	cifs_put_tlink(tlink);
1284
1285	kfree(pnntsd);
1286	kfree(pntsd);
1287	return rc;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1288}