Linux Audio

Check our new training course

Loading...
   1// SPDX-License-Identifier: LGPL-2.1+
   2/*
   3 *   Copyright (C) International Business Machines  Corp., 2007,2008
   4 *   Author(s): Steve French (sfrench@us.ibm.com)
   5 *   Copyright (C) 2020 Samsung Electronics Co., Ltd.
   6 *   Author(s): Namjae Jeon <linkinjeon@kernel.org>
   7 */
   8
   9#include <linux/fs.h>
  10#include <linux/slab.h>
  11#include <linux/string.h>
  12#include <linux/mnt_idmapping.h>
  13
  14#include "smbacl.h"
  15#include "smb_common.h"
  16#include "server.h"
  17#include "misc.h"
  18#include "mgmt/share_config.h"
  19
  20static const struct smb_sid domain = {1, 4, {0, 0, 0, 0, 0, 5},
  21	{cpu_to_le32(21), cpu_to_le32(1), cpu_to_le32(2), cpu_to_le32(3),
  22	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  23
  24/* security id for everyone/world system group */
  25static const struct smb_sid creator_owner = {
  26	1, 1, {0, 0, 0, 0, 0, 3}, {0} };
  27/* security id for everyone/world system group */
  28static const struct smb_sid creator_group = {
  29	1, 1, {0, 0, 0, 0, 0, 3}, {cpu_to_le32(1)} };
  30
  31/* security id for everyone/world system group */
  32static const struct smb_sid sid_everyone = {
  33	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
  34/* security id for Authenticated Users system group */
  35static const struct smb_sid sid_authusers = {
  36	1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
  37
  38/* S-1-22-1 Unmapped Unix users */
  39static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
  40		{cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  41
  42/* S-1-22-2 Unmapped Unix groups */
  43static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
  44		{cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  45
  46/*
  47 * See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
  48 */
  49
  50/* S-1-5-88 MS NFS and Apple style UID/GID/mode */
  51
  52/* S-1-5-88-1 Unix uid */
  53static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
  54	{cpu_to_le32(88),
  55	 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  56
  57/* S-1-5-88-2 Unix gid */
  58static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
  59	{cpu_to_le32(88),
  60	 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  61
  62/* S-1-5-88-3 Unix mode */
  63static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
  64	{cpu_to_le32(88),
  65	 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  66
  67/*
  68 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
  69 * the same returns zero, if they do not match returns non-zero.
  70 */
  71int compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
  72{
  73	int i;
  74	int num_subauth, num_sat, num_saw;
  75
  76	if (!ctsid || !cwsid)
  77		return 1;
  78
  79	/* compare the revision */
  80	if (ctsid->revision != cwsid->revision) {
  81		if (ctsid->revision > cwsid->revision)
  82			return 1;
  83		else
  84			return -1;
  85	}
  86
  87	/* compare all of the six auth values */
  88	for (i = 0; i < NUM_AUTHS; ++i) {
  89		if (ctsid->authority[i] != cwsid->authority[i]) {
  90			if (ctsid->authority[i] > cwsid->authority[i])
  91				return 1;
  92			else
  93				return -1;
  94		}
  95	}
  96
  97	/* compare all of the subauth values if any */
  98	num_sat = ctsid->num_subauth;
  99	num_saw = cwsid->num_subauth;
 100	num_subauth = min(num_sat, num_saw);
 101	if (num_subauth) {
 102		for (i = 0; i < num_subauth; ++i) {
 103			if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
 104				if (le32_to_cpu(ctsid->sub_auth[i]) >
 105				    le32_to_cpu(cwsid->sub_auth[i]))
 106					return 1;
 107				else
 108					return -1;
 109			}
 110		}
 111	}
 112
 113	return 0; /* sids compare/match */
 114}
 115
 116static void smb_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
 117{
 118	int i;
 119
 120	dst->revision = src->revision;
 121	dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
 122	for (i = 0; i < NUM_AUTHS; ++i)
 123		dst->authority[i] = src->authority[i];
 124	for (i = 0; i < dst->num_subauth; ++i)
 125		dst->sub_auth[i] = src->sub_auth[i];
 126}
 127
 128/*
 129 * change posix mode to reflect permissions
 130 * pmode is the existing mode (we only want to overwrite part of this
 131 * bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
 132 */
 133static umode_t access_flags_to_mode(struct smb_fattr *fattr, __le32 ace_flags,
 134				    int type)
 135{
 136	__u32 flags = le32_to_cpu(ace_flags);
 137	umode_t mode = 0;
 138
 139	if (flags & GENERIC_ALL) {
 140		mode = 0777;
 141		ksmbd_debug(SMB, "all perms\n");
 142		return mode;
 143	}
 144
 145	if ((flags & GENERIC_READ) || (flags & FILE_READ_RIGHTS))
 146		mode = 0444;
 147	if ((flags & GENERIC_WRITE) || (flags & FILE_WRITE_RIGHTS)) {
 148		mode |= 0222;
 149		if (S_ISDIR(fattr->cf_mode))
 150			mode |= 0111;
 151	}
 152	if ((flags & GENERIC_EXECUTE) || (flags & FILE_EXEC_RIGHTS))
 153		mode |= 0111;
 154
 155	if (type == ACCESS_DENIED_ACE_TYPE || type == ACCESS_DENIED_OBJECT_ACE_TYPE)
 156		mode = ~mode;
 157
 158	ksmbd_debug(SMB, "access flags 0x%x mode now %04o\n", flags, mode);
 159
 160	return mode;
 161}
 162
 163/*
 164 * Generate access flags to reflect permissions mode is the existing mode.
 165 * This function is called for every ACE in the DACL whose SID matches
 166 * with either owner or group or everyone.
 167 */
 168static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
 169				 __u32 *pace_flags)
 170{
 171	/* reset access mask */
 172	*pace_flags = 0x0;
 173
 174	/* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
 175	mode &= bits_to_use;
 176
 177	/*
 178	 * check for R/W/X UGO since we do not know whose flags
 179	 * is this but we have cleared all the bits sans RWX for
 180	 * either user or group or other as per bits_to_use
 181	 */
 182	if (mode & 0444)
 183		*pace_flags |= SET_FILE_READ_RIGHTS;
 184	if (mode & 0222)
 185		*pace_flags |= FILE_WRITE_RIGHTS;
 186	if (mode & 0111)
 187		*pace_flags |= SET_FILE_EXEC_RIGHTS;
 188
 189	ksmbd_debug(SMB, "mode: %o, access flags now 0x%x\n",
 190		    mode, *pace_flags);
 191}
 192
 193static __u16 fill_ace_for_sid(struct smb_ace *pntace,
 194			      const struct smb_sid *psid, int type, int flags,
 195			      umode_t mode, umode_t bits)
 196{
 197	int i;
 198	__u16 size = 0;
 199	__u32 access_req = 0;
 200
 201	pntace->type = type;
 202	pntace->flags = flags;
 203	mode_to_access_flags(mode, bits, &access_req);
 204	if (!access_req)
 205		access_req = SET_MINIMUM_RIGHTS;
 206	pntace->access_req = cpu_to_le32(access_req);
 207
 208	pntace->sid.revision = psid->revision;
 209	pntace->sid.num_subauth = psid->num_subauth;
 210	for (i = 0; i < NUM_AUTHS; i++)
 211		pntace->sid.authority[i] = psid->authority[i];
 212	for (i = 0; i < psid->num_subauth; i++)
 213		pntace->sid.sub_auth[i] = psid->sub_auth[i];
 214
 215	size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
 216	pntace->size = cpu_to_le16(size);
 217
 218	return size;
 219}
 220
 221void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
 222{
 223	switch (sidtype) {
 224	case SIDOWNER:
 225		smb_copy_sid(ssid, &server_conf.domain_sid);
 226		break;
 227	case SIDUNIX_USER:
 228		smb_copy_sid(ssid, &sid_unix_users);
 229		break;
 230	case SIDUNIX_GROUP:
 231		smb_copy_sid(ssid, &sid_unix_groups);
 232		break;
 233	case SIDCREATOR_OWNER:
 234		smb_copy_sid(ssid, &creator_owner);
 235		return;
 236	case SIDCREATOR_GROUP:
 237		smb_copy_sid(ssid, &creator_group);
 238		return;
 239	case SIDNFS_USER:
 240		smb_copy_sid(ssid, &sid_unix_NFS_users);
 241		break;
 242	case SIDNFS_GROUP:
 243		smb_copy_sid(ssid, &sid_unix_NFS_groups);
 244		break;
 245	case SIDNFS_MODE:
 246		smb_copy_sid(ssid, &sid_unix_NFS_mode);
 247		break;
 248	default:
 249		return;
 250	}
 251
 252	/* RID */
 253	ssid->sub_auth[ssid->num_subauth] = cpu_to_le32(cid);
 254	ssid->num_subauth++;
 255}
 256
 257static int sid_to_id(struct mnt_idmap *idmap,
 258		     struct smb_sid *psid, uint sidtype,
 259		     struct smb_fattr *fattr)
 260{
 261	int rc = -EINVAL;
 262
 263	/*
 264	 * If we have too many subauthorities, then something is really wrong.
 265	 * Just return an error.
 266	 */
 267	if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
 268		pr_err("%s: %u subauthorities is too many!\n",
 269		       __func__, psid->num_subauth);
 270		return -EIO;
 271	}
 272
 273	if (sidtype == SIDOWNER) {
 274		kuid_t uid;
 275		uid_t id;
 276
 277		id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
 278		uid = KUIDT_INIT(id);
 279		uid = from_vfsuid(idmap, &init_user_ns, VFSUIDT_INIT(uid));
 280		if (uid_valid(uid)) {
 281			fattr->cf_uid = uid;
 282			rc = 0;
 283		}
 284	} else {
 285		kgid_t gid;
 286		gid_t id;
 287
 288		id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
 289		gid = KGIDT_INIT(id);
 290		gid = from_vfsgid(idmap, &init_user_ns, VFSGIDT_INIT(gid));
 291		if (gid_valid(gid)) {
 292			fattr->cf_gid = gid;
 293			rc = 0;
 294		}
 295	}
 296
 297	return rc;
 298}
 299
 300void posix_state_to_acl(struct posix_acl_state *state,
 301			struct posix_acl_entry *pace)
 302{
 303	int i;
 304
 305	pace->e_tag = ACL_USER_OBJ;
 306	pace->e_perm = state->owner.allow;
 307	for (i = 0; i < state->users->n; i++) {
 308		pace++;
 309		pace->e_tag = ACL_USER;
 310		pace->e_uid = state->users->aces[i].uid;
 311		pace->e_perm = state->users->aces[i].perms.allow;
 312	}
 313
 314	pace++;
 315	pace->e_tag = ACL_GROUP_OBJ;
 316	pace->e_perm = state->group.allow;
 317
 318	for (i = 0; i < state->groups->n; i++) {
 319		pace++;
 320		pace->e_tag = ACL_GROUP;
 321		pace->e_gid = state->groups->aces[i].gid;
 322		pace->e_perm = state->groups->aces[i].perms.allow;
 323	}
 324
 325	if (state->users->n || state->groups->n) {
 326		pace++;
 327		pace->e_tag = ACL_MASK;
 328		pace->e_perm = state->mask.allow;
 329	}
 330
 331	pace++;
 332	pace->e_tag = ACL_OTHER;
 333	pace->e_perm = state->other.allow;
 334}
 335
 336int init_acl_state(struct posix_acl_state *state, int cnt)
 337{
 338	int alloc;
 339
 340	memset(state, 0, sizeof(struct posix_acl_state));
 341	/*
 342	 * In the worst case, each individual acl could be for a distinct
 343	 * named user or group, but we don't know which, so we allocate
 344	 * enough space for either:
 345	 */
 346	alloc = sizeof(struct posix_ace_state_array)
 347		+ cnt * sizeof(struct posix_user_ace_state);
 348	state->users = kzalloc(alloc, GFP_KERNEL);
 349	if (!state->users)
 350		return -ENOMEM;
 351	state->groups = kzalloc(alloc, GFP_KERNEL);
 352	if (!state->groups) {
 353		kfree(state->users);
 354		return -ENOMEM;
 355	}
 356	return 0;
 357}
 358
 359void free_acl_state(struct posix_acl_state *state)
 360{
 361	kfree(state->users);
 362	kfree(state->groups);
 363}
 364
 365static void parse_dacl(struct mnt_idmap *idmap,
 366		       struct smb_acl *pdacl, char *end_of_acl,
 367		       struct smb_sid *pownersid, struct smb_sid *pgrpsid,
 368		       struct smb_fattr *fattr)
 369{
 370	int i, ret;
 371	int num_aces = 0;
 372	unsigned int acl_size;
 373	char *acl_base;
 374	struct smb_ace **ppace;
 375	struct posix_acl_entry *cf_pace, *cf_pdace;
 376	struct posix_acl_state acl_state, default_acl_state;
 377	umode_t mode = 0, acl_mode;
 378	bool owner_found = false, group_found = false, others_found = false;
 379
 380	if (!pdacl)
 381		return;
 382
 383	/* validate that we do not go past end of acl */
 384	if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl) ||
 385	    end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
 386		pr_err("ACL too small to parse DACL\n");
 387		return;
 388	}
 389
 390	ksmbd_debug(SMB, "DACL revision %d size %d num aces %d\n",
 391		    le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
 392		    le32_to_cpu(pdacl->num_aces));
 393
 394	acl_base = (char *)pdacl;
 395	acl_size = sizeof(struct smb_acl);
 396
 397	num_aces = le32_to_cpu(pdacl->num_aces);
 398	if (num_aces <= 0)
 399		return;
 400
 401	if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
 402		return;
 403
 404	ret = init_acl_state(&acl_state, num_aces);
 405	if (ret)
 406		return;
 407	ret = init_acl_state(&default_acl_state, num_aces);
 408	if (ret) {
 409		free_acl_state(&acl_state);
 410		return;
 411	}
 412
 413	ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), GFP_KERNEL);
 414	if (!ppace) {
 415		free_acl_state(&default_acl_state);
 416		free_acl_state(&acl_state);
 417		return;
 418	}
 419
 420	/*
 421	 * reset rwx permissions for user/group/other.
 422	 * Also, if num_aces is 0 i.e. DACL has no ACEs,
 423	 * user/group/other have no permissions
 424	 */
 425	for (i = 0; i < num_aces; ++i) {
 426		if (end_of_acl - acl_base < acl_size)
 427			break;
 428
 429		ppace[i] = (struct smb_ace *)(acl_base + acl_size);
 430		acl_base = (char *)ppace[i];
 431		acl_size = offsetof(struct smb_ace, sid) +
 432			offsetof(struct smb_sid, sub_auth);
 433
 434		if (end_of_acl - acl_base < acl_size ||
 435		    ppace[i]->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
 436		    (end_of_acl - acl_base <
 437		     acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) ||
 438		    (le16_to_cpu(ppace[i]->size) <
 439		     acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth))
 440			break;
 441
 442		acl_size = le16_to_cpu(ppace[i]->size);
 443		ppace[i]->access_req =
 444			smb_map_generic_desired_access(ppace[i]->access_req);
 445
 446		if (!(compare_sids(&ppace[i]->sid, &sid_unix_NFS_mode))) {
 447			fattr->cf_mode =
 448				le32_to_cpu(ppace[i]->sid.sub_auth[2]);
 449			break;
 450		} else if (!compare_sids(&ppace[i]->sid, pownersid)) {
 451			acl_mode = access_flags_to_mode(fattr,
 452							ppace[i]->access_req,
 453							ppace[i]->type);
 454			acl_mode &= 0700;
 455
 456			if (!owner_found) {
 457				mode &= ~(0700);
 458				mode |= acl_mode;
 459			}
 460			owner_found = true;
 461		} else if (!compare_sids(&ppace[i]->sid, pgrpsid) ||
 462			   ppace[i]->sid.sub_auth[ppace[i]->sid.num_subauth - 1] ==
 463			    DOMAIN_USER_RID_LE) {
 464			acl_mode = access_flags_to_mode(fattr,
 465							ppace[i]->access_req,
 466							ppace[i]->type);
 467			acl_mode &= 0070;
 468			if (!group_found) {
 469				mode &= ~(0070);
 470				mode |= acl_mode;
 471			}
 472			group_found = true;
 473		} else if (!compare_sids(&ppace[i]->sid, &sid_everyone)) {
 474			acl_mode = access_flags_to_mode(fattr,
 475							ppace[i]->access_req,
 476							ppace[i]->type);
 477			acl_mode &= 0007;
 478			if (!others_found) {
 479				mode &= ~(0007);
 480				mode |= acl_mode;
 481			}
 482			others_found = true;
 483		} else if (!compare_sids(&ppace[i]->sid, &creator_owner)) {
 484			continue;
 485		} else if (!compare_sids(&ppace[i]->sid, &creator_group)) {
 486			continue;
 487		} else if (!compare_sids(&ppace[i]->sid, &sid_authusers)) {
 488			continue;
 489		} else {
 490			struct smb_fattr temp_fattr;
 491
 492			acl_mode = access_flags_to_mode(fattr, ppace[i]->access_req,
 493							ppace[i]->type);
 494			temp_fattr.cf_uid = INVALID_UID;
 495			ret = sid_to_id(idmap, &ppace[i]->sid, SIDOWNER, &temp_fattr);
 496			if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) {
 497				pr_err("%s: Error %d mapping Owner SID to uid\n",
 498				       __func__, ret);
 499				continue;
 500			}
 501
 502			acl_state.owner.allow = ((acl_mode & 0700) >> 6) | 0004;
 503			acl_state.users->aces[acl_state.users->n].uid =
 504				temp_fattr.cf_uid;
 505			acl_state.users->aces[acl_state.users->n++].perms.allow =
 506				((acl_mode & 0700) >> 6) | 0004;
 507			default_acl_state.owner.allow = ((acl_mode & 0700) >> 6) | 0004;
 508			default_acl_state.users->aces[default_acl_state.users->n].uid =
 509				temp_fattr.cf_uid;
 510			default_acl_state.users->aces[default_acl_state.users->n++].perms.allow =
 511				((acl_mode & 0700) >> 6) | 0004;
 512		}
 513	}
 514	kfree(ppace);
 515
 516	if (owner_found) {
 517		/* The owner must be set to at least read-only. */
 518		acl_state.owner.allow = ((mode & 0700) >> 6) | 0004;
 519		acl_state.users->aces[acl_state.users->n].uid = fattr->cf_uid;
 520		acl_state.users->aces[acl_state.users->n++].perms.allow =
 521			((mode & 0700) >> 6) | 0004;
 522		default_acl_state.owner.allow = ((mode & 0700) >> 6) | 0004;
 523		default_acl_state.users->aces[default_acl_state.users->n].uid =
 524			fattr->cf_uid;
 525		default_acl_state.users->aces[default_acl_state.users->n++].perms.allow =
 526			((mode & 0700) >> 6) | 0004;
 527	}
 528
 529	if (group_found) {
 530		acl_state.group.allow = (mode & 0070) >> 3;
 531		acl_state.groups->aces[acl_state.groups->n].gid =
 532			fattr->cf_gid;
 533		acl_state.groups->aces[acl_state.groups->n++].perms.allow =
 534			(mode & 0070) >> 3;
 535		default_acl_state.group.allow = (mode & 0070) >> 3;
 536		default_acl_state.groups->aces[default_acl_state.groups->n].gid =
 537			fattr->cf_gid;
 538		default_acl_state.groups->aces[default_acl_state.groups->n++].perms.allow =
 539			(mode & 0070) >> 3;
 540	}
 541
 542	if (others_found) {
 543		fattr->cf_mode &= ~(0007);
 544		fattr->cf_mode |= mode & 0007;
 545
 546		acl_state.other.allow = mode & 0007;
 547		default_acl_state.other.allow = mode & 0007;
 548	}
 549
 550	if (acl_state.users->n || acl_state.groups->n) {
 551		acl_state.mask.allow = 0x07;
 552
 553		if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
 554			fattr->cf_acls =
 555				posix_acl_alloc(acl_state.users->n +
 556					acl_state.groups->n + 4, GFP_KERNEL);
 557			if (fattr->cf_acls) {
 558				cf_pace = fattr->cf_acls->a_entries;
 559				posix_state_to_acl(&acl_state, cf_pace);
 560			}
 561		}
 562	}
 563
 564	if (default_acl_state.users->n || default_acl_state.groups->n) {
 565		default_acl_state.mask.allow = 0x07;
 566
 567		if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
 568			fattr->cf_dacls =
 569				posix_acl_alloc(default_acl_state.users->n +
 570				default_acl_state.groups->n + 4, GFP_KERNEL);
 571			if (fattr->cf_dacls) {
 572				cf_pdace = fattr->cf_dacls->a_entries;
 573				posix_state_to_acl(&default_acl_state, cf_pdace);
 574			}
 575		}
 576	}
 577	free_acl_state(&acl_state);
 578	free_acl_state(&default_acl_state);
 579}
 580
 581static void set_posix_acl_entries_dacl(struct mnt_idmap *idmap,
 582				       struct smb_ace *pndace,
 583				       struct smb_fattr *fattr, u32 *num_aces,
 584				       u16 *size, u32 nt_aces_num)
 585{
 586	struct posix_acl_entry *pace;
 587	struct smb_sid *sid;
 588	struct smb_ace *ntace;
 589	int i, j;
 590
 591	if (!fattr->cf_acls)
 592		goto posix_default_acl;
 593
 594	pace = fattr->cf_acls->a_entries;
 595	for (i = 0; i < fattr->cf_acls->a_count; i++, pace++) {
 596		int flags = 0;
 597
 598		sid = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
 599		if (!sid)
 600			break;
 601
 602		if (pace->e_tag == ACL_USER) {
 603			uid_t uid;
 604			unsigned int sid_type = SIDOWNER;
 605
 606			uid = posix_acl_uid_translate(idmap, pace);
 607			if (!uid)
 608				sid_type = SIDUNIX_USER;
 609			id_to_sid(uid, sid_type, sid);
 610		} else if (pace->e_tag == ACL_GROUP) {
 611			gid_t gid;
 612
 613			gid = posix_acl_gid_translate(idmap, pace);
 614			id_to_sid(gid, SIDUNIX_GROUP, sid);
 615		} else if (pace->e_tag == ACL_OTHER && !nt_aces_num) {
 616			smb_copy_sid(sid, &sid_everyone);
 617		} else {
 618			kfree(sid);
 619			continue;
 620		}
 621		ntace = pndace;
 622		for (j = 0; j < nt_aces_num; j++) {
 623			if (ntace->sid.sub_auth[ntace->sid.num_subauth - 1] ==
 624					sid->sub_auth[sid->num_subauth - 1])
 625				goto pass_same_sid;
 626			ntace = (struct smb_ace *)((char *)ntace +
 627					le16_to_cpu(ntace->size));
 628		}
 629
 630		if (S_ISDIR(fattr->cf_mode) && pace->e_tag == ACL_OTHER)
 631			flags = 0x03;
 632
 633		ntace = (struct smb_ace *)((char *)pndace + *size);
 634		*size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, flags,
 635				pace->e_perm, 0777);
 636		(*num_aces)++;
 637		if (pace->e_tag == ACL_USER)
 638			ntace->access_req |=
 639				FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
 640
 641		if (S_ISDIR(fattr->cf_mode) &&
 642		    (pace->e_tag == ACL_USER || pace->e_tag == ACL_GROUP)) {
 643			ntace = (struct smb_ace *)((char *)pndace + *size);
 644			*size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED,
 645					0x03, pace->e_perm, 0777);
 646			(*num_aces)++;
 647			if (pace->e_tag == ACL_USER)
 648				ntace->access_req |=
 649					FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
 650		}
 651
 652pass_same_sid:
 653		kfree(sid);
 654	}
 655
 656	if (nt_aces_num)
 657		return;
 658
 659posix_default_acl:
 660	if (!fattr->cf_dacls)
 661		return;
 662
 663	pace = fattr->cf_dacls->a_entries;
 664	for (i = 0; i < fattr->cf_dacls->a_count; i++, pace++) {
 665		sid = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
 666		if (!sid)
 667			break;
 668
 669		if (pace->e_tag == ACL_USER) {
 670			uid_t uid;
 671
 672			uid = posix_acl_uid_translate(idmap, pace);
 673			id_to_sid(uid, SIDCREATOR_OWNER, sid);
 674		} else if (pace->e_tag == ACL_GROUP) {
 675			gid_t gid;
 676
 677			gid = posix_acl_gid_translate(idmap, pace);
 678			id_to_sid(gid, SIDCREATOR_GROUP, sid);
 679		} else {
 680			kfree(sid);
 681			continue;
 682		}
 683
 684		ntace = (struct smb_ace *)((char *)pndace + *size);
 685		*size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, 0x0b,
 686				pace->e_perm, 0777);
 687		(*num_aces)++;
 688		if (pace->e_tag == ACL_USER)
 689			ntace->access_req |=
 690				FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
 691		kfree(sid);
 692	}
 693}
 694
 695static void set_ntacl_dacl(struct mnt_idmap *idmap,
 696			   struct smb_acl *pndacl,
 697			   struct smb_acl *nt_dacl,
 698			   unsigned int aces_size,
 699			   const struct smb_sid *pownersid,
 700			   const struct smb_sid *pgrpsid,
 701			   struct smb_fattr *fattr)
 702{
 703	struct smb_ace *ntace, *pndace;
 704	int nt_num_aces = le32_to_cpu(nt_dacl->num_aces), num_aces = 0;
 705	unsigned short size = 0;
 706	int i;
 707
 708	pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
 709	if (nt_num_aces) {
 710		ntace = (struct smb_ace *)((char *)nt_dacl + sizeof(struct smb_acl));
 711		for (i = 0; i < nt_num_aces; i++) {
 712			unsigned short nt_ace_size;
 713
 714			if (offsetof(struct smb_ace, access_req) > aces_size)
 715				break;
 716
 717			nt_ace_size = le16_to_cpu(ntace->size);
 718			if (nt_ace_size > aces_size)
 719				break;
 720
 721			memcpy((char *)pndace + size, ntace, nt_ace_size);
 722			size += nt_ace_size;
 723			aces_size -= nt_ace_size;
 724			ntace = (struct smb_ace *)((char *)ntace + nt_ace_size);
 725			num_aces++;
 726		}
 727	}
 728
 729	set_posix_acl_entries_dacl(idmap, pndace, fattr,
 730				   &num_aces, &size, nt_num_aces);
 731	pndacl->num_aces = cpu_to_le32(num_aces);
 732	pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
 733}
 734
 735static void set_mode_dacl(struct mnt_idmap *idmap,
 736			  struct smb_acl *pndacl, struct smb_fattr *fattr)
 737{
 738	struct smb_ace *pace, *pndace;
 739	u32 num_aces = 0;
 740	u16 size = 0, ace_size = 0;
 741	uid_t uid;
 742	const struct smb_sid *sid;
 743
 744	pace = pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
 745
 746	if (fattr->cf_acls) {
 747		set_posix_acl_entries_dacl(idmap, pndace, fattr,
 748					   &num_aces, &size, num_aces);
 749		goto out;
 750	}
 751
 752	/* owner RID */
 753	uid = from_kuid(&init_user_ns, fattr->cf_uid);
 754	if (uid)
 755		sid = &server_conf.domain_sid;
 756	else
 757		sid = &sid_unix_users;
 758	ace_size = fill_ace_for_sid(pace, sid, ACCESS_ALLOWED, 0,
 759				    fattr->cf_mode, 0700);
 760	pace->sid.sub_auth[pace->sid.num_subauth++] = cpu_to_le32(uid);
 761	pace->size = cpu_to_le16(ace_size + 4);
 762	size += le16_to_cpu(pace->size);
 763	pace = (struct smb_ace *)((char *)pndace + size);
 764
 765	/* Group RID */
 766	ace_size = fill_ace_for_sid(pace, &sid_unix_groups,
 767				    ACCESS_ALLOWED, 0, fattr->cf_mode, 0070);
 768	pace->sid.sub_auth[pace->sid.num_subauth++] =
 769		cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid));
 770	pace->size = cpu_to_le16(ace_size + 4);
 771	size += le16_to_cpu(pace->size);
 772	pace = (struct smb_ace *)((char *)pndace + size);
 773	num_aces = 3;
 774
 775	if (S_ISDIR(fattr->cf_mode)) {
 776		pace = (struct smb_ace *)((char *)pndace + size);
 777
 778		/* creator owner */
 779		size += fill_ace_for_sid(pace, &creator_owner, ACCESS_ALLOWED,
 780					 0x0b, fattr->cf_mode, 0700);
 781		pace = (struct smb_ace *)((char *)pndace + size);
 782
 783		/* creator group */
 784		size += fill_ace_for_sid(pace, &creator_group, ACCESS_ALLOWED,
 785					 0x0b, fattr->cf_mode, 0070);
 786		pace = (struct smb_ace *)((char *)pndace + size);
 787		num_aces = 5;
 788	}
 789
 790	/* other */
 791	size += fill_ace_for_sid(pace, &sid_everyone, ACCESS_ALLOWED, 0,
 792				 fattr->cf_mode, 0007);
 793
 794out:
 795	pndacl->num_aces = cpu_to_le32(num_aces);
 796	pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
 797}
 798
 799static int parse_sid(struct smb_sid *psid, char *end_of_acl)
 800{
 801	/*
 802	 * validate that we do not go past end of ACL - sid must be at least 8
 803	 * bytes long (assuming no sub-auths - e.g. the null SID
 804	 */
 805	if (end_of_acl < (char *)psid + 8) {
 806		pr_err("ACL too small to parse SID %p\n", psid);
 807		return -EINVAL;
 808	}
 809
 810	return 0;
 811}
 812
 813/* Convert CIFS ACL to POSIX form */
 814int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
 815		   int acl_len, struct smb_fattr *fattr)
 816{
 817	int rc = 0;
 818	struct smb_sid *owner_sid_ptr, *group_sid_ptr;
 819	struct smb_acl *dacl_ptr; /* no need for SACL ptr */
 820	char *end_of_acl = ((char *)pntsd) + acl_len;
 821	__u32 dacloffset;
 822	int pntsd_type;
 823
 824	if (!pntsd)
 825		return -EIO;
 826
 827	if (acl_len < sizeof(struct smb_ntsd))
 828		return -EINVAL;
 829
 830	owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
 831			le32_to_cpu(pntsd->osidoffset));
 832	group_sid_ptr = (struct smb_sid *)((char *)pntsd +
 833			le32_to_cpu(pntsd->gsidoffset));
 834	dacloffset = le32_to_cpu(pntsd->dacloffset);
 835	dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
 836	ksmbd_debug(SMB,
 837		    "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
 838		    pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
 839		    le32_to_cpu(pntsd->gsidoffset),
 840		    le32_to_cpu(pntsd->sacloffset), dacloffset);
 841
 842	pntsd_type = le16_to_cpu(pntsd->type);
 843	if (!(pntsd_type & DACL_PRESENT)) {
 844		ksmbd_debug(SMB, "DACL_PRESENT in DACL type is not set\n");
 845		return rc;
 846	}
 847
 848	pntsd->type = cpu_to_le16(DACL_PRESENT);
 849
 850	if (pntsd->osidoffset) {
 851		rc = parse_sid(owner_sid_ptr, end_of_acl);
 852		if (rc) {
 853			pr_err("%s: Error %d parsing Owner SID\n", __func__, rc);
 854			return rc;
 855		}
 856
 857		rc = sid_to_id(idmap, owner_sid_ptr, SIDOWNER, fattr);
 858		if (rc) {
 859			pr_err("%s: Error %d mapping Owner SID to uid\n",
 860			       __func__, rc);
 861			owner_sid_ptr = NULL;
 862		}
 863	}
 864
 865	if (pntsd->gsidoffset) {
 866		rc = parse_sid(group_sid_ptr, end_of_acl);
 867		if (rc) {
 868			pr_err("%s: Error %d mapping Owner SID to gid\n",
 869			       __func__, rc);
 870			return rc;
 871		}
 872		rc = sid_to_id(idmap, group_sid_ptr, SIDUNIX_GROUP, fattr);
 873		if (rc) {
 874			pr_err("%s: Error %d mapping Group SID to gid\n",
 875			       __func__, rc);
 876			group_sid_ptr = NULL;
 877		}
 878	}
 879
 880	if ((pntsd_type & (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ)) ==
 881	    (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ))
 882		pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
 883	if (pntsd_type & DACL_PROTECTED)
 884		pntsd->type |= cpu_to_le16(DACL_PROTECTED);
 885
 886	if (dacloffset) {
 887		parse_dacl(idmap, dacl_ptr, end_of_acl,
 888			   owner_sid_ptr, group_sid_ptr, fattr);
 889	}
 890
 891	return 0;
 892}
 893
 894/* Convert permission bits from mode to equivalent CIFS ACL */
 895int build_sec_desc(struct mnt_idmap *idmap,
 896		   struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
 897		   int ppntsd_size, int addition_info, __u32 *secdesclen,
 898		   struct smb_fattr *fattr)
 899{
 900	int rc = 0;
 901	__u32 offset;
 902	struct smb_sid *owner_sid_ptr, *group_sid_ptr;
 903	struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr;
 904	struct smb_acl *dacl_ptr = NULL; /* no need for SACL ptr */
 905	uid_t uid;
 906	gid_t gid;
 907	unsigned int sid_type = SIDOWNER;
 908
 909	nowner_sid_ptr = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
 910	if (!nowner_sid_ptr)
 911		return -ENOMEM;
 912
 913	uid = from_kuid(&init_user_ns, fattr->cf_uid);
 914	if (!uid)
 915		sid_type = SIDUNIX_USER;
 916	id_to_sid(uid, sid_type, nowner_sid_ptr);
 917
 918	ngroup_sid_ptr = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
 919	if (!ngroup_sid_ptr) {
 920		kfree(nowner_sid_ptr);
 921		return -ENOMEM;
 922	}
 923
 924	gid = from_kgid(&init_user_ns, fattr->cf_gid);
 925	id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr);
 926
 927	offset = sizeof(struct smb_ntsd);
 928	pntsd->sacloffset = 0;
 929	pntsd->revision = cpu_to_le16(1);
 930	pntsd->type = cpu_to_le16(SELF_RELATIVE);
 931	if (ppntsd)
 932		pntsd->type |= ppntsd->type;
 933
 934	if (addition_info & OWNER_SECINFO) {
 935		pntsd->osidoffset = cpu_to_le32(offset);
 936		owner_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
 937		smb_copy_sid(owner_sid_ptr, nowner_sid_ptr);
 938		offset += 1 + 1 + 6 + (nowner_sid_ptr->num_subauth * 4);
 939	}
 940
 941	if (addition_info & GROUP_SECINFO) {
 942		pntsd->gsidoffset = cpu_to_le32(offset);
 943		group_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
 944		smb_copy_sid(group_sid_ptr, ngroup_sid_ptr);
 945		offset += 1 + 1 + 6 + (ngroup_sid_ptr->num_subauth * 4);
 946	}
 947
 948	if (addition_info & DACL_SECINFO) {
 949		pntsd->type |= cpu_to_le16(DACL_PRESENT);
 950		dacl_ptr = (struct smb_acl *)((char *)pntsd + offset);
 951		dacl_ptr->revision = cpu_to_le16(2);
 952		dacl_ptr->size = cpu_to_le16(sizeof(struct smb_acl));
 953		dacl_ptr->num_aces = 0;
 954
 955		if (!ppntsd) {
 956			set_mode_dacl(idmap, dacl_ptr, fattr);
 957		} else {
 958			struct smb_acl *ppdacl_ptr;
 959			unsigned int dacl_offset = le32_to_cpu(ppntsd->dacloffset);
 960			int ppdacl_size, ntacl_size = ppntsd_size - dacl_offset;
 961
 962			if (!dacl_offset ||
 963			    (dacl_offset + sizeof(struct smb_acl) > ppntsd_size))
 964				goto out;
 965
 966			ppdacl_ptr = (struct smb_acl *)((char *)ppntsd + dacl_offset);
 967			ppdacl_size = le16_to_cpu(ppdacl_ptr->size);
 968			if (ppdacl_size > ntacl_size ||
 969			    ppdacl_size < sizeof(struct smb_acl))
 970				goto out;
 971
 972			set_ntacl_dacl(idmap, dacl_ptr, ppdacl_ptr,
 973				       ntacl_size - sizeof(struct smb_acl),
 974				       nowner_sid_ptr, ngroup_sid_ptr,
 975				       fattr);
 976		}
 977		pntsd->dacloffset = cpu_to_le32(offset);
 978		offset += le16_to_cpu(dacl_ptr->size);
 979	}
 980
 981out:
 982	kfree(nowner_sid_ptr);
 983	kfree(ngroup_sid_ptr);
 984	*secdesclen = offset;
 985	return rc;
 986}
 987
 988static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type,
 989			u8 flags, __le32 access_req)
 990{
 991	ace->type = type;
 992	ace->flags = flags;
 993	ace->access_req = access_req;
 994	smb_copy_sid(&ace->sid, sid);
 995	ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 + (sid->num_subauth * 4));
 996}
 997
 998int smb_inherit_dacl(struct ksmbd_conn *conn,
 999		     const struct path *path,
1000		     unsigned int uid, unsigned int gid)
1001{
1002	const struct smb_sid *psid, *creator = NULL;
1003	struct smb_ace *parent_aces, *aces;
1004	struct smb_acl *parent_pdacl;
1005	struct smb_ntsd *parent_pntsd = NULL;
1006	struct smb_sid owner_sid, group_sid;
1007	struct dentry *parent = path->dentry->d_parent;
1008	struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1009	int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0, pdacl_size;
1010	int rc = 0, num_aces, dacloffset, pntsd_type, pntsd_size, acl_len, aces_size;
1011	char *aces_base;
1012	bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
1013
1014	pntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
1015					    parent, &parent_pntsd);
1016	if (pntsd_size <= 0)
1017		return -ENOENT;
1018	dacloffset = le32_to_cpu(parent_pntsd->dacloffset);
1019	if (!dacloffset || (dacloffset + sizeof(struct smb_acl) > pntsd_size)) {
1020		rc = -EINVAL;
1021		goto free_parent_pntsd;
1022	}
1023
1024	parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset);
1025	acl_len = pntsd_size - dacloffset;
1026	num_aces = le32_to_cpu(parent_pdacl->num_aces);
1027	pntsd_type = le16_to_cpu(parent_pntsd->type);
1028	pdacl_size = le16_to_cpu(parent_pdacl->size);
1029
1030	if (pdacl_size > acl_len || pdacl_size < sizeof(struct smb_acl)) {
1031		rc = -EINVAL;
1032		goto free_parent_pntsd;
1033	}
1034
1035	aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2, GFP_KERNEL);
1036	if (!aces_base) {
1037		rc = -ENOMEM;
1038		goto free_parent_pntsd;
1039	}
1040
1041	aces = (struct smb_ace *)aces_base;
1042	parent_aces = (struct smb_ace *)((char *)parent_pdacl +
1043			sizeof(struct smb_acl));
1044	aces_size = acl_len - sizeof(struct smb_acl);
1045
1046	if (pntsd_type & DACL_AUTO_INHERITED)
1047		inherited_flags = INHERITED_ACE;
1048
1049	for (i = 0; i < num_aces; i++) {
1050		int pace_size;
1051
1052		if (offsetof(struct smb_ace, access_req) > aces_size)
1053			break;
1054
1055		pace_size = le16_to_cpu(parent_aces->size);
1056		if (pace_size > aces_size)
1057			break;
1058
1059		aces_size -= pace_size;
1060
1061		flags = parent_aces->flags;
1062		if (!smb_inherit_flags(flags, is_dir))
1063			goto pass;
1064		if (is_dir) {
1065			flags &= ~(INHERIT_ONLY_ACE | INHERITED_ACE);
1066			if (!(flags & CONTAINER_INHERIT_ACE))
1067				flags |= INHERIT_ONLY_ACE;
1068			if (flags & NO_PROPAGATE_INHERIT_ACE)
1069				flags = 0;
1070		} else {
1071			flags = 0;
1072		}
1073
1074		if (!compare_sids(&creator_owner, &parent_aces->sid)) {
1075			creator = &creator_owner;
1076			id_to_sid(uid, SIDOWNER, &owner_sid);
1077			psid = &owner_sid;
1078		} else if (!compare_sids(&creator_group, &parent_aces->sid)) {
1079			creator = &creator_group;
1080			id_to_sid(gid, SIDUNIX_GROUP, &group_sid);
1081			psid = &group_sid;
1082		} else {
1083			creator = NULL;
1084			psid = &parent_aces->sid;
1085		}
1086
1087		if (is_dir && creator && flags & CONTAINER_INHERIT_ACE) {
1088			smb_set_ace(aces, psid, parent_aces->type, inherited_flags,
1089				    parent_aces->access_req);
1090			nt_size += le16_to_cpu(aces->size);
1091			ace_cnt++;
1092			aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
1093			flags |= INHERIT_ONLY_ACE;
1094			psid = creator;
1095		} else if (is_dir && !(parent_aces->flags & NO_PROPAGATE_INHERIT_ACE)) {
1096			psid = &parent_aces->sid;
1097		}
1098
1099		smb_set_ace(aces, psid, parent_aces->type, flags | inherited_flags,
1100			    parent_aces->access_req);
1101		nt_size += le16_to_cpu(aces->size);
1102		aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
1103		ace_cnt++;
1104pass:
1105		parent_aces = (struct smb_ace *)((char *)parent_aces + pace_size);
1106	}
1107
1108	if (nt_size > 0) {
1109		struct smb_ntsd *pntsd;
1110		struct smb_acl *pdacl;
1111		struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL;
1112		int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
1113		int pntsd_alloc_size;
1114
1115		if (parent_pntsd->osidoffset) {
1116			powner_sid = (struct smb_sid *)((char *)parent_pntsd +
1117					le32_to_cpu(parent_pntsd->osidoffset));
1118			powner_sid_size = 1 + 1 + 6 + (powner_sid->num_subauth * 4);
1119		}
1120		if (parent_pntsd->gsidoffset) {
1121			pgroup_sid = (struct smb_sid *)((char *)parent_pntsd +
1122					le32_to_cpu(parent_pntsd->gsidoffset));
1123			pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4);
1124		}
1125
1126		pntsd_alloc_size = sizeof(struct smb_ntsd) + powner_sid_size +
1127			pgroup_sid_size + sizeof(struct smb_acl) + nt_size;
1128
1129		pntsd = kzalloc(pntsd_alloc_size, GFP_KERNEL);
1130		if (!pntsd) {
1131			rc = -ENOMEM;
1132			goto free_aces_base;
1133		}
1134
1135		pntsd->revision = cpu_to_le16(1);
1136		pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PRESENT);
1137		if (le16_to_cpu(parent_pntsd->type) & DACL_AUTO_INHERITED)
1138			pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
1139		pntsd_size = sizeof(struct smb_ntsd);
1140		pntsd->osidoffset = parent_pntsd->osidoffset;
1141		pntsd->gsidoffset = parent_pntsd->gsidoffset;
1142		pntsd->dacloffset = parent_pntsd->dacloffset;
1143
1144		if ((u64)le32_to_cpu(pntsd->osidoffset) + powner_sid_size >
1145		    pntsd_alloc_size) {
1146			rc = -EINVAL;
1147			kfree(pntsd);
1148			goto free_aces_base;
1149		}
1150
1151		if ((u64)le32_to_cpu(pntsd->gsidoffset) + pgroup_sid_size >
1152		    pntsd_alloc_size) {
1153			rc = -EINVAL;
1154			kfree(pntsd);
1155			goto free_aces_base;
1156		}
1157
1158		if ((u64)le32_to_cpu(pntsd->dacloffset) + sizeof(struct smb_acl) + nt_size >
1159		    pntsd_alloc_size) {
1160			rc = -EINVAL;
1161			kfree(pntsd);
1162			goto free_aces_base;
1163		}
1164
1165		if (pntsd->osidoffset) {
1166			struct smb_sid *owner_sid = (struct smb_sid *)((char *)pntsd +
1167					le32_to_cpu(pntsd->osidoffset));
1168			memcpy(owner_sid, powner_sid, powner_sid_size);
1169			pntsd_size += powner_sid_size;
1170		}
1171
1172		if (pntsd->gsidoffset) {
1173			struct smb_sid *group_sid = (struct smb_sid *)((char *)pntsd +
1174					le32_to_cpu(pntsd->gsidoffset));
1175			memcpy(group_sid, pgroup_sid, pgroup_sid_size);
1176			pntsd_size += pgroup_sid_size;
1177		}
1178
1179		if (pntsd->dacloffset) {
1180			struct smb_ace *pace;
1181
1182			pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1183			pdacl->revision = cpu_to_le16(2);
1184			pdacl->size = cpu_to_le16(sizeof(struct smb_acl) + nt_size);
1185			pdacl->num_aces = cpu_to_le32(ace_cnt);
1186			pace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1187			memcpy(pace, aces_base, nt_size);
1188			pntsd_size += sizeof(struct smb_acl) + nt_size;
1189		}
1190
1191		ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, pntsd_size, false);
1192		kfree(pntsd);
1193	}
1194
1195free_aces_base:
1196	kfree(aces_base);
1197free_parent_pntsd:
1198	kfree(parent_pntsd);
1199	return rc;
1200}
1201
1202bool smb_inherit_flags(int flags, bool is_dir)
1203{
1204	if (!is_dir)
1205		return (flags & OBJECT_INHERIT_ACE) != 0;
1206
1207	if (flags & OBJECT_INHERIT_ACE && !(flags & NO_PROPAGATE_INHERIT_ACE))
1208		return true;
1209
1210	if (flags & CONTAINER_INHERIT_ACE)
1211		return true;
1212	return false;
1213}
1214
1215int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
1216			__le32 *pdaccess, int uid)
1217{
1218	struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1219	struct smb_ntsd *pntsd = NULL;
1220	struct smb_acl *pdacl;
1221	struct posix_acl *posix_acls;
1222	int rc = 0, pntsd_size, acl_size, aces_size, pdacl_size, dacl_offset;
1223	struct smb_sid sid;
1224	int granted = le32_to_cpu(*pdaccess & ~FILE_MAXIMAL_ACCESS_LE);
1225	struct smb_ace *ace;
1226	int i, found = 0;
1227	unsigned int access_bits = 0;
1228	struct smb_ace *others_ace = NULL;
1229	struct posix_acl_entry *pa_entry;
1230	unsigned int sid_type = SIDOWNER;
1231	unsigned short ace_size;
1232
1233	ksmbd_debug(SMB, "check permission using windows acl\n");
1234	pntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
1235					    path->dentry, &pntsd);
1236	if (pntsd_size <= 0 || !pntsd)
1237		goto err_out;
1238
1239	dacl_offset = le32_to_cpu(pntsd->dacloffset);
1240	if (!dacl_offset ||
1241	    (dacl_offset + sizeof(struct smb_acl) > pntsd_size))
1242		goto err_out;
1243
1244	pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1245	acl_size = pntsd_size - dacl_offset;
1246	pdacl_size = le16_to_cpu(pdacl->size);
1247
1248	if (pdacl_size > acl_size || pdacl_size < sizeof(struct smb_acl))
1249		goto err_out;
1250
1251	if (!pdacl->num_aces) {
1252		if (!(pdacl_size - sizeof(struct smb_acl)) &&
1253		    *pdaccess & ~(FILE_READ_CONTROL_LE | FILE_WRITE_DAC_LE)) {
1254			rc = -EACCES;
1255			goto err_out;
1256		}
1257		goto err_out;
1258	}
1259
1260	if (*pdaccess & FILE_MAXIMAL_ACCESS_LE) {
1261		granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1262			DELETE;
1263
1264		ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1265		aces_size = acl_size - sizeof(struct smb_acl);
1266		for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1267			if (offsetof(struct smb_ace, access_req) > aces_size)
1268				break;
1269			ace_size = le16_to_cpu(ace->size);
1270			if (ace_size > aces_size)
1271				break;
1272			aces_size -= ace_size;
1273			granted |= le32_to_cpu(ace->access_req);
1274			ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1275		}
1276
1277		if (!pdacl->num_aces)
1278			granted = GENERIC_ALL_FLAGS;
1279	}
1280
1281	if (!uid)
1282		sid_type = SIDUNIX_USER;
1283	id_to_sid(uid, sid_type, &sid);
1284
1285	ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1286	aces_size = acl_size - sizeof(struct smb_acl);
1287	for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1288		if (offsetof(struct smb_ace, access_req) > aces_size)
1289			break;
1290		ace_size = le16_to_cpu(ace->size);
1291		if (ace_size > aces_size)
1292			break;
1293		aces_size -= ace_size;
1294
1295		if (!compare_sids(&sid, &ace->sid) ||
1296		    !compare_sids(&sid_unix_NFS_mode, &ace->sid)) {
1297			found = 1;
1298			break;
1299		}
1300		if (!compare_sids(&sid_everyone, &ace->sid))
1301			others_ace = ace;
1302
1303		ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1304	}
1305
1306	if (*pdaccess & FILE_MAXIMAL_ACCESS_LE && found) {
1307		granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1308			DELETE;
1309
1310		granted |= le32_to_cpu(ace->access_req);
1311
1312		if (!pdacl->num_aces)
1313			granted = GENERIC_ALL_FLAGS;
1314	}
1315
1316	if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
1317		posix_acls = get_inode_acl(d_inode(path->dentry), ACL_TYPE_ACCESS);
1318		if (!IS_ERR_OR_NULL(posix_acls) && !found) {
1319			unsigned int id = -1;
1320
1321			pa_entry = posix_acls->a_entries;
1322			for (i = 0; i < posix_acls->a_count; i++, pa_entry++) {
1323				if (pa_entry->e_tag == ACL_USER)
1324					id = posix_acl_uid_translate(idmap, pa_entry);
1325				else if (pa_entry->e_tag == ACL_GROUP)
1326					id = posix_acl_gid_translate(idmap, pa_entry);
1327				else
1328					continue;
1329
1330				if (id == uid) {
1331					mode_to_access_flags(pa_entry->e_perm,
1332							     0777,
1333							     &access_bits);
1334					if (!access_bits)
1335						access_bits =
1336							SET_MINIMUM_RIGHTS;
1337					posix_acl_release(posix_acls);
1338					goto check_access_bits;
1339				}
1340			}
1341		}
1342		if (!IS_ERR_OR_NULL(posix_acls))
1343			posix_acl_release(posix_acls);
1344	}
1345
1346	if (!found) {
1347		if (others_ace) {
1348			ace = others_ace;
1349		} else {
1350			ksmbd_debug(SMB, "Can't find corresponding sid\n");
1351			rc = -EACCES;
1352			goto err_out;
1353		}
1354	}
1355
1356	switch (ace->type) {
1357	case ACCESS_ALLOWED_ACE_TYPE:
1358		access_bits = le32_to_cpu(ace->access_req);
1359		break;
1360	case ACCESS_DENIED_ACE_TYPE:
1361	case ACCESS_DENIED_CALLBACK_ACE_TYPE:
1362		access_bits = le32_to_cpu(~ace->access_req);
1363		break;
1364	}
1365
1366check_access_bits:
1367	if (granted &
1368	    ~(access_bits | FILE_READ_ATTRIBUTES | READ_CONTROL | WRITE_DAC | DELETE)) {
1369		ksmbd_debug(SMB, "Access denied with winACL, granted : %x, access_req : %x\n",
1370			    granted, le32_to_cpu(ace->access_req));
1371		rc = -EACCES;
1372		goto err_out;
1373	}
1374
1375	*pdaccess = cpu_to_le32(granted);
1376err_out:
1377	kfree(pntsd);
1378	return rc;
1379}
1380
1381int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
1382		 const struct path *path, struct smb_ntsd *pntsd, int ntsd_len,
1383		 bool type_check, bool get_write)
1384{
1385	int rc;
1386	struct smb_fattr fattr = {{0}};
1387	struct inode *inode = d_inode(path->dentry);
1388	struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1389	struct iattr newattrs;
1390
1391	fattr.cf_uid = INVALID_UID;
1392	fattr.cf_gid = INVALID_GID;
1393	fattr.cf_mode = inode->i_mode;
1394
1395	rc = parse_sec_desc(idmap, pntsd, ntsd_len, &fattr);
1396	if (rc)
1397		goto out;
1398
1399	newattrs.ia_valid = ATTR_CTIME;
1400	if (!uid_eq(fattr.cf_uid, INVALID_UID)) {
1401		newattrs.ia_valid |= ATTR_UID;
1402		newattrs.ia_uid = fattr.cf_uid;
1403	}
1404	if (!gid_eq(fattr.cf_gid, INVALID_GID)) {
1405		newattrs.ia_valid |= ATTR_GID;
1406		newattrs.ia_gid = fattr.cf_gid;
1407	}
1408	newattrs.ia_valid |= ATTR_MODE;
1409	newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
1410
1411	ksmbd_vfs_remove_acl_xattrs(idmap, path);
1412	/* Update posix acls */
1413	if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) {
1414		rc = set_posix_acl(idmap, path->dentry,
1415				   ACL_TYPE_ACCESS, fattr.cf_acls);
1416		if (rc < 0)
1417			ksmbd_debug(SMB,
1418				    "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
1419				    rc);
1420		if (S_ISDIR(inode->i_mode) && fattr.cf_dacls) {
1421			rc = set_posix_acl(idmap, path->dentry,
1422					   ACL_TYPE_DEFAULT, fattr.cf_dacls);
1423			if (rc)
1424				ksmbd_debug(SMB,
1425					    "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
1426					    rc);
1427		}
1428	}
1429
1430	inode_lock(inode);
1431	rc = notify_change(idmap, path->dentry, &newattrs, NULL);
1432	inode_unlock(inode);
1433	if (rc)
1434		goto out;
1435
1436	/* Check it only calling from SD BUFFER context */
1437	if (type_check && !(le16_to_cpu(pntsd->type) & DACL_PRESENT))
1438		goto out;
1439
1440	if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
1441		/* Update WinACL in xattr */
1442		ksmbd_vfs_remove_sd_xattrs(idmap, path);
1443		ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, ntsd_len,
1444				get_write);
1445	}
1446
1447out:
1448	posix_acl_release(fattr.cf_acls);
1449	posix_acl_release(fattr.cf_dacls);
1450	return rc;
1451}
1452
1453void ksmbd_init_domain(u32 *sub_auth)
1454{
1455	int i;
1456
1457	memcpy(&server_conf.domain_sid, &domain, sizeof(struct smb_sid));
1458	for (i = 0; i < 3; ++i)
1459		server_conf.domain_sid.sub_auth[i + 1] = cpu_to_le32(sub_auth[i]);
1460}
1