Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Feb 10-13, 2025
Register
Loading...
Note: File does not exist in v4.17.
   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, KSMBD_DEFAULT_GFP);
 349	if (!state->users)
 350		return -ENOMEM;
 351	state->groups = kzalloc(alloc, KSMBD_DEFAULT_GFP);
 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 *), KSMBD_DEFAULT_GFP);
 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, KSMBD_DEFAULT_GFP);
 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, KSMBD_DEFAULT_GFP);
 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), KSMBD_DEFAULT_GFP);
 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), KSMBD_DEFAULT_GFP);
 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	if (!psid->num_subauth)
 811		return 0;
 812
 813	if (psid->num_subauth > SID_MAX_SUB_AUTHORITIES ||
 814	    end_of_acl < (char *)psid + 8 + sizeof(__le32) * psid->num_subauth)
 815		return -EINVAL;
 816
 817	return 0;
 818}
 819
 820/* Convert CIFS ACL to POSIX form */
 821int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
 822		   int acl_len, struct smb_fattr *fattr)
 823{
 824	int rc = 0;
 825	struct smb_sid *owner_sid_ptr, *group_sid_ptr;
 826	struct smb_acl *dacl_ptr; /* no need for SACL ptr */
 827	char *end_of_acl = ((char *)pntsd) + acl_len;
 828	__u32 dacloffset;
 829	int pntsd_type;
 830
 831	if (!pntsd)
 832		return -EIO;
 833
 834	if (acl_len < sizeof(struct smb_ntsd))
 835		return -EINVAL;
 836
 837	owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
 838			le32_to_cpu(pntsd->osidoffset));
 839	group_sid_ptr = (struct smb_sid *)((char *)pntsd +
 840			le32_to_cpu(pntsd->gsidoffset));
 841	dacloffset = le32_to_cpu(pntsd->dacloffset);
 842	dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
 843	ksmbd_debug(SMB,
 844		    "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
 845		    pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
 846		    le32_to_cpu(pntsd->gsidoffset),
 847		    le32_to_cpu(pntsd->sacloffset), dacloffset);
 848
 849	pntsd_type = le16_to_cpu(pntsd->type);
 850	if (!(pntsd_type & DACL_PRESENT)) {
 851		ksmbd_debug(SMB, "DACL_PRESENT in DACL type is not set\n");
 852		return rc;
 853	}
 854
 855	pntsd->type = cpu_to_le16(DACL_PRESENT);
 856
 857	if (pntsd->osidoffset) {
 858		if (le32_to_cpu(pntsd->osidoffset) < sizeof(struct smb_ntsd))
 859			return -EINVAL;
 860
 861		rc = parse_sid(owner_sid_ptr, end_of_acl);
 862		if (rc) {
 863			pr_err("%s: Error %d parsing Owner SID\n", __func__, rc);
 864			return rc;
 865		}
 866
 867		rc = sid_to_id(idmap, owner_sid_ptr, SIDOWNER, fattr);
 868		if (rc) {
 869			pr_err("%s: Error %d mapping Owner SID to uid\n",
 870			       __func__, rc);
 871			owner_sid_ptr = NULL;
 872		}
 873	}
 874
 875	if (pntsd->gsidoffset) {
 876		if (le32_to_cpu(pntsd->gsidoffset) < sizeof(struct smb_ntsd))
 877			return -EINVAL;
 878
 879		rc = parse_sid(group_sid_ptr, end_of_acl);
 880		if (rc) {
 881			pr_err("%s: Error %d mapping Owner SID to gid\n",
 882			       __func__, rc);
 883			return rc;
 884		}
 885		rc = sid_to_id(idmap, group_sid_ptr, SIDUNIX_GROUP, fattr);
 886		if (rc) {
 887			pr_err("%s: Error %d mapping Group SID to gid\n",
 888			       __func__, rc);
 889			group_sid_ptr = NULL;
 890		}
 891	}
 892
 893	if ((pntsd_type & (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ)) ==
 894	    (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ))
 895		pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
 896	if (pntsd_type & DACL_PROTECTED)
 897		pntsd->type |= cpu_to_le16(DACL_PROTECTED);
 898
 899	if (dacloffset) {
 900		if (dacloffset < sizeof(struct smb_ntsd))
 901			return -EINVAL;
 902
 903		parse_dacl(idmap, dacl_ptr, end_of_acl,
 904			   owner_sid_ptr, group_sid_ptr, fattr);
 905	}
 906
 907	return 0;
 908}
 909
 910/* Convert permission bits from mode to equivalent CIFS ACL */
 911int build_sec_desc(struct mnt_idmap *idmap,
 912		   struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
 913		   int ppntsd_size, int addition_info, __u32 *secdesclen,
 914		   struct smb_fattr *fattr)
 915{
 916	int rc = 0;
 917	__u32 offset;
 918	struct smb_sid *owner_sid_ptr, *group_sid_ptr;
 919	struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr;
 920	struct smb_acl *dacl_ptr = NULL; /* no need for SACL ptr */
 921	uid_t uid;
 922	gid_t gid;
 923	unsigned int sid_type = SIDOWNER;
 924
 925	nowner_sid_ptr = kmalloc(sizeof(struct smb_sid), KSMBD_DEFAULT_GFP);
 926	if (!nowner_sid_ptr)
 927		return -ENOMEM;
 928
 929	uid = from_kuid(&init_user_ns, fattr->cf_uid);
 930	if (!uid)
 931		sid_type = SIDUNIX_USER;
 932	id_to_sid(uid, sid_type, nowner_sid_ptr);
 933
 934	ngroup_sid_ptr = kmalloc(sizeof(struct smb_sid), KSMBD_DEFAULT_GFP);
 935	if (!ngroup_sid_ptr) {
 936		kfree(nowner_sid_ptr);
 937		return -ENOMEM;
 938	}
 939
 940	gid = from_kgid(&init_user_ns, fattr->cf_gid);
 941	id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr);
 942
 943	offset = sizeof(struct smb_ntsd);
 944	pntsd->sacloffset = 0;
 945	pntsd->revision = cpu_to_le16(1);
 946	pntsd->type = cpu_to_le16(SELF_RELATIVE);
 947	if (ppntsd)
 948		pntsd->type |= ppntsd->type;
 949
 950	if (addition_info & OWNER_SECINFO) {
 951		pntsd->osidoffset = cpu_to_le32(offset);
 952		owner_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
 953		smb_copy_sid(owner_sid_ptr, nowner_sid_ptr);
 954		offset += 1 + 1 + 6 + (nowner_sid_ptr->num_subauth * 4);
 955	}
 956
 957	if (addition_info & GROUP_SECINFO) {
 958		pntsd->gsidoffset = cpu_to_le32(offset);
 959		group_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
 960		smb_copy_sid(group_sid_ptr, ngroup_sid_ptr);
 961		offset += 1 + 1 + 6 + (ngroup_sid_ptr->num_subauth * 4);
 962	}
 963
 964	if (addition_info & DACL_SECINFO) {
 965		pntsd->type |= cpu_to_le16(DACL_PRESENT);
 966		dacl_ptr = (struct smb_acl *)((char *)pntsd + offset);
 967		dacl_ptr->revision = cpu_to_le16(2);
 968		dacl_ptr->size = cpu_to_le16(sizeof(struct smb_acl));
 969		dacl_ptr->num_aces = 0;
 970
 971		if (!ppntsd) {
 972			set_mode_dacl(idmap, dacl_ptr, fattr);
 973		} else {
 974			struct smb_acl *ppdacl_ptr;
 975			unsigned int dacl_offset = le32_to_cpu(ppntsd->dacloffset);
 976			int ppdacl_size, ntacl_size = ppntsd_size - dacl_offset;
 977
 978			if (!dacl_offset ||
 979			    (dacl_offset + sizeof(struct smb_acl) > ppntsd_size))
 980				goto out;
 981
 982			ppdacl_ptr = (struct smb_acl *)((char *)ppntsd + dacl_offset);
 983			ppdacl_size = le16_to_cpu(ppdacl_ptr->size);
 984			if (ppdacl_size > ntacl_size ||
 985			    ppdacl_size < sizeof(struct smb_acl))
 986				goto out;
 987
 988			set_ntacl_dacl(idmap, dacl_ptr, ppdacl_ptr,
 989				       ntacl_size - sizeof(struct smb_acl),
 990				       nowner_sid_ptr, ngroup_sid_ptr,
 991				       fattr);
 992		}
 993		pntsd->dacloffset = cpu_to_le32(offset);
 994		offset += le16_to_cpu(dacl_ptr->size);
 995	}
 996
 997out:
 998	kfree(nowner_sid_ptr);
 999	kfree(ngroup_sid_ptr);
1000	*secdesclen = offset;
1001	return rc;
1002}
1003
1004static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type,
1005			u8 flags, __le32 access_req)
1006{
1007	ace->type = type;
1008	ace->flags = flags;
1009	ace->access_req = access_req;
1010	smb_copy_sid(&ace->sid, sid);
1011	ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 + (sid->num_subauth * 4));
1012}
1013
1014int smb_inherit_dacl(struct ksmbd_conn *conn,
1015		     const struct path *path,
1016		     unsigned int uid, unsigned int gid)
1017{
1018	const struct smb_sid *psid, *creator = NULL;
1019	struct smb_ace *parent_aces, *aces;
1020	struct smb_acl *parent_pdacl;
1021	struct smb_ntsd *parent_pntsd = NULL;
1022	struct smb_sid owner_sid, group_sid;
1023	struct dentry *parent = path->dentry->d_parent;
1024	struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1025	int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0, pdacl_size;
1026	int rc = 0, num_aces, dacloffset, pntsd_type, pntsd_size, acl_len, aces_size;
1027	char *aces_base;
1028	bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
1029
1030	pntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
1031					    parent, &parent_pntsd);
1032	if (pntsd_size <= 0)
1033		return -ENOENT;
1034	dacloffset = le32_to_cpu(parent_pntsd->dacloffset);
1035	if (!dacloffset || (dacloffset + sizeof(struct smb_acl) > pntsd_size)) {
1036		rc = -EINVAL;
1037		goto free_parent_pntsd;
1038	}
1039
1040	parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset);
1041	acl_len = pntsd_size - dacloffset;
1042	num_aces = le32_to_cpu(parent_pdacl->num_aces);
1043	pntsd_type = le16_to_cpu(parent_pntsd->type);
1044	pdacl_size = le16_to_cpu(parent_pdacl->size);
1045
1046	if (pdacl_size > acl_len || pdacl_size < sizeof(struct smb_acl)) {
1047		rc = -EINVAL;
1048		goto free_parent_pntsd;
1049	}
1050
1051	aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2,
1052			    KSMBD_DEFAULT_GFP);
1053	if (!aces_base) {
1054		rc = -ENOMEM;
1055		goto free_parent_pntsd;
1056	}
1057
1058	aces = (struct smb_ace *)aces_base;
1059	parent_aces = (struct smb_ace *)((char *)parent_pdacl +
1060			sizeof(struct smb_acl));
1061	aces_size = acl_len - sizeof(struct smb_acl);
1062
1063	if (pntsd_type & DACL_AUTO_INHERITED)
1064		inherited_flags = INHERITED_ACE;
1065
1066	for (i = 0; i < num_aces; i++) {
1067		int pace_size;
1068
1069		if (offsetof(struct smb_ace, access_req) > aces_size)
1070			break;
1071
1072		pace_size = le16_to_cpu(parent_aces->size);
1073		if (pace_size > aces_size)
1074			break;
1075
1076		aces_size -= pace_size;
1077
1078		flags = parent_aces->flags;
1079		if (!smb_inherit_flags(flags, is_dir))
1080			goto pass;
1081		if (is_dir) {
1082			flags &= ~(INHERIT_ONLY_ACE | INHERITED_ACE);
1083			if (!(flags & CONTAINER_INHERIT_ACE))
1084				flags |= INHERIT_ONLY_ACE;
1085			if (flags & NO_PROPAGATE_INHERIT_ACE)
1086				flags = 0;
1087		} else {
1088			flags = 0;
1089		}
1090
1091		if (!compare_sids(&creator_owner, &parent_aces->sid)) {
1092			creator = &creator_owner;
1093			id_to_sid(uid, SIDOWNER, &owner_sid);
1094			psid = &owner_sid;
1095		} else if (!compare_sids(&creator_group, &parent_aces->sid)) {
1096			creator = &creator_group;
1097			id_to_sid(gid, SIDUNIX_GROUP, &group_sid);
1098			psid = &group_sid;
1099		} else {
1100			creator = NULL;
1101			psid = &parent_aces->sid;
1102		}
1103
1104		if (is_dir && creator && flags & CONTAINER_INHERIT_ACE) {
1105			smb_set_ace(aces, psid, parent_aces->type, inherited_flags,
1106				    parent_aces->access_req);
1107			nt_size += le16_to_cpu(aces->size);
1108			ace_cnt++;
1109			aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
1110			flags |= INHERIT_ONLY_ACE;
1111			psid = creator;
1112		} else if (is_dir && !(parent_aces->flags & NO_PROPAGATE_INHERIT_ACE)) {
1113			psid = &parent_aces->sid;
1114		}
1115
1116		smb_set_ace(aces, psid, parent_aces->type, flags | inherited_flags,
1117			    parent_aces->access_req);
1118		nt_size += le16_to_cpu(aces->size);
1119		aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
1120		ace_cnt++;
1121pass:
1122		parent_aces = (struct smb_ace *)((char *)parent_aces + pace_size);
1123	}
1124
1125	if (nt_size > 0) {
1126		struct smb_ntsd *pntsd;
1127		struct smb_acl *pdacl;
1128		struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL;
1129		int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
1130		int pntsd_alloc_size;
1131
1132		if (parent_pntsd->osidoffset) {
1133			powner_sid = (struct smb_sid *)((char *)parent_pntsd +
1134					le32_to_cpu(parent_pntsd->osidoffset));
1135			powner_sid_size = 1 + 1 + 6 + (powner_sid->num_subauth * 4);
1136		}
1137		if (parent_pntsd->gsidoffset) {
1138			pgroup_sid = (struct smb_sid *)((char *)parent_pntsd +
1139					le32_to_cpu(parent_pntsd->gsidoffset));
1140			pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4);
1141		}
1142
1143		pntsd_alloc_size = sizeof(struct smb_ntsd) + powner_sid_size +
1144			pgroup_sid_size + sizeof(struct smb_acl) + nt_size;
1145
1146		pntsd = kzalloc(pntsd_alloc_size, KSMBD_DEFAULT_GFP);
1147		if (!pntsd) {
1148			rc = -ENOMEM;
1149			goto free_aces_base;
1150		}
1151
1152		pntsd->revision = cpu_to_le16(1);
1153		pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PRESENT);
1154		if (le16_to_cpu(parent_pntsd->type) & DACL_AUTO_INHERITED)
1155			pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
1156		pntsd_size = sizeof(struct smb_ntsd);
1157		pntsd->osidoffset = parent_pntsd->osidoffset;
1158		pntsd->gsidoffset = parent_pntsd->gsidoffset;
1159		pntsd->dacloffset = parent_pntsd->dacloffset;
1160
1161		if ((u64)le32_to_cpu(pntsd->osidoffset) + powner_sid_size >
1162		    pntsd_alloc_size) {
1163			rc = -EINVAL;
1164			kfree(pntsd);
1165			goto free_aces_base;
1166		}
1167
1168		if ((u64)le32_to_cpu(pntsd->gsidoffset) + pgroup_sid_size >
1169		    pntsd_alloc_size) {
1170			rc = -EINVAL;
1171			kfree(pntsd);
1172			goto free_aces_base;
1173		}
1174
1175		if ((u64)le32_to_cpu(pntsd->dacloffset) + sizeof(struct smb_acl) + nt_size >
1176		    pntsd_alloc_size) {
1177			rc = -EINVAL;
1178			kfree(pntsd);
1179			goto free_aces_base;
1180		}
1181
1182		if (pntsd->osidoffset) {
1183			struct smb_sid *owner_sid = (struct smb_sid *)((char *)pntsd +
1184					le32_to_cpu(pntsd->osidoffset));
1185			memcpy(owner_sid, powner_sid, powner_sid_size);
1186			pntsd_size += powner_sid_size;
1187		}
1188
1189		if (pntsd->gsidoffset) {
1190			struct smb_sid *group_sid = (struct smb_sid *)((char *)pntsd +
1191					le32_to_cpu(pntsd->gsidoffset));
1192			memcpy(group_sid, pgroup_sid, pgroup_sid_size);
1193			pntsd_size += pgroup_sid_size;
1194		}
1195
1196		if (pntsd->dacloffset) {
1197			struct smb_ace *pace;
1198
1199			pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1200			pdacl->revision = cpu_to_le16(2);
1201			pdacl->size = cpu_to_le16(sizeof(struct smb_acl) + nt_size);
1202			pdacl->num_aces = cpu_to_le32(ace_cnt);
1203			pace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1204			memcpy(pace, aces_base, nt_size);
1205			pntsd_size += sizeof(struct smb_acl) + nt_size;
1206		}
1207
1208		ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, pntsd_size, false);
1209		kfree(pntsd);
1210	}
1211
1212free_aces_base:
1213	kfree(aces_base);
1214free_parent_pntsd:
1215	kfree(parent_pntsd);
1216	return rc;
1217}
1218
1219bool smb_inherit_flags(int flags, bool is_dir)
1220{
1221	if (!is_dir)
1222		return (flags & OBJECT_INHERIT_ACE) != 0;
1223
1224	if (flags & OBJECT_INHERIT_ACE && !(flags & NO_PROPAGATE_INHERIT_ACE))
1225		return true;
1226
1227	if (flags & CONTAINER_INHERIT_ACE)
1228		return true;
1229	return false;
1230}
1231
1232int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
1233			__le32 *pdaccess, int uid)
1234{
1235	struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1236	struct smb_ntsd *pntsd = NULL;
1237	struct smb_acl *pdacl;
1238	struct posix_acl *posix_acls;
1239	int rc = 0, pntsd_size, acl_size, aces_size, pdacl_size, dacl_offset;
1240	struct smb_sid sid;
1241	int granted = le32_to_cpu(*pdaccess & ~FILE_MAXIMAL_ACCESS_LE);
1242	struct smb_ace *ace;
1243	int i, found = 0;
1244	unsigned int access_bits = 0;
1245	struct smb_ace *others_ace = NULL;
1246	struct posix_acl_entry *pa_entry;
1247	unsigned int sid_type = SIDOWNER;
1248	unsigned short ace_size;
1249
1250	ksmbd_debug(SMB, "check permission using windows acl\n");
1251	pntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
1252					    path->dentry, &pntsd);
1253	if (pntsd_size <= 0 || !pntsd)
1254		goto err_out;
1255
1256	dacl_offset = le32_to_cpu(pntsd->dacloffset);
1257	if (!dacl_offset ||
1258	    (dacl_offset + sizeof(struct smb_acl) > pntsd_size))
1259		goto err_out;
1260
1261	pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1262	acl_size = pntsd_size - dacl_offset;
1263	pdacl_size = le16_to_cpu(pdacl->size);
1264
1265	if (pdacl_size > acl_size || pdacl_size < sizeof(struct smb_acl))
1266		goto err_out;
1267
1268	if (!pdacl->num_aces) {
1269		if (!(pdacl_size - sizeof(struct smb_acl)) &&
1270		    *pdaccess & ~(FILE_READ_CONTROL_LE | FILE_WRITE_DAC_LE)) {
1271			rc = -EACCES;
1272			goto err_out;
1273		}
1274		goto err_out;
1275	}
1276
1277	if (*pdaccess & FILE_MAXIMAL_ACCESS_LE) {
1278		granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1279			DELETE;
1280
1281		ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1282		aces_size = acl_size - sizeof(struct smb_acl);
1283		for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1284			if (offsetof(struct smb_ace, access_req) > aces_size)
1285				break;
1286			ace_size = le16_to_cpu(ace->size);
1287			if (ace_size > aces_size)
1288				break;
1289			aces_size -= ace_size;
1290			granted |= le32_to_cpu(ace->access_req);
1291			ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1292		}
1293
1294		if (!pdacl->num_aces)
1295			granted = GENERIC_ALL_FLAGS;
1296	}
1297
1298	if (!uid)
1299		sid_type = SIDUNIX_USER;
1300	id_to_sid(uid, sid_type, &sid);
1301
1302	ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1303	aces_size = acl_size - sizeof(struct smb_acl);
1304	for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1305		if (offsetof(struct smb_ace, access_req) > aces_size)
1306			break;
1307		ace_size = le16_to_cpu(ace->size);
1308		if (ace_size > aces_size)
1309			break;
1310		aces_size -= ace_size;
1311
1312		if (!compare_sids(&sid, &ace->sid) ||
1313		    !compare_sids(&sid_unix_NFS_mode, &ace->sid)) {
1314			found = 1;
1315			break;
1316		}
1317		if (!compare_sids(&sid_everyone, &ace->sid))
1318			others_ace = ace;
1319
1320		ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1321	}
1322
1323	if (*pdaccess & FILE_MAXIMAL_ACCESS_LE && found) {
1324		granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1325			DELETE;
1326
1327		granted |= le32_to_cpu(ace->access_req);
1328
1329		if (!pdacl->num_aces)
1330			granted = GENERIC_ALL_FLAGS;
1331	}
1332
1333	if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
1334		posix_acls = get_inode_acl(d_inode(path->dentry), ACL_TYPE_ACCESS);
1335		if (!IS_ERR_OR_NULL(posix_acls) && !found) {
1336			unsigned int id = -1;
1337
1338			pa_entry = posix_acls->a_entries;
1339			for (i = 0; i < posix_acls->a_count; i++, pa_entry++) {
1340				if (pa_entry->e_tag == ACL_USER)
1341					id = posix_acl_uid_translate(idmap, pa_entry);
1342				else if (pa_entry->e_tag == ACL_GROUP)
1343					id = posix_acl_gid_translate(idmap, pa_entry);
1344				else
1345					continue;
1346
1347				if (id == uid) {
1348					mode_to_access_flags(pa_entry->e_perm,
1349							     0777,
1350							     &access_bits);
1351					if (!access_bits)
1352						access_bits =
1353							SET_MINIMUM_RIGHTS;
1354					posix_acl_release(posix_acls);
1355					goto check_access_bits;
1356				}
1357			}
1358		}
1359		if (!IS_ERR_OR_NULL(posix_acls))
1360			posix_acl_release(posix_acls);
1361	}
1362
1363	if (!found) {
1364		if (others_ace) {
1365			ace = others_ace;
1366		} else {
1367			ksmbd_debug(SMB, "Can't find corresponding sid\n");
1368			rc = -EACCES;
1369			goto err_out;
1370		}
1371	}
1372
1373	switch (ace->type) {
1374	case ACCESS_ALLOWED_ACE_TYPE:
1375		access_bits = le32_to_cpu(ace->access_req);
1376		break;
1377	case ACCESS_DENIED_ACE_TYPE:
1378	case ACCESS_DENIED_CALLBACK_ACE_TYPE:
1379		access_bits = le32_to_cpu(~ace->access_req);
1380		break;
1381	}
1382
1383check_access_bits:
1384	if (granted &
1385	    ~(access_bits | FILE_READ_ATTRIBUTES | READ_CONTROL | WRITE_DAC | DELETE)) {
1386		ksmbd_debug(SMB, "Access denied with winACL, granted : %x, access_req : %x\n",
1387			    granted, le32_to_cpu(ace->access_req));
1388		rc = -EACCES;
1389		goto err_out;
1390	}
1391
1392	*pdaccess = cpu_to_le32(granted);
1393err_out:
1394	kfree(pntsd);
1395	return rc;
1396}
1397
1398int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
1399		 const struct path *path, struct smb_ntsd *pntsd, int ntsd_len,
1400		 bool type_check, bool get_write)
1401{
1402	int rc;
1403	struct smb_fattr fattr = {{0}};
1404	struct inode *inode = d_inode(path->dentry);
1405	struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1406	struct iattr newattrs;
1407
1408	fattr.cf_uid = INVALID_UID;
1409	fattr.cf_gid = INVALID_GID;
1410	fattr.cf_mode = inode->i_mode;
1411
1412	rc = parse_sec_desc(idmap, pntsd, ntsd_len, &fattr);
1413	if (rc)
1414		goto out;
1415
1416	newattrs.ia_valid = ATTR_CTIME;
1417	if (!uid_eq(fattr.cf_uid, INVALID_UID)) {
1418		newattrs.ia_valid |= ATTR_UID;
1419		newattrs.ia_uid = fattr.cf_uid;
1420	}
1421	if (!gid_eq(fattr.cf_gid, INVALID_GID)) {
1422		newattrs.ia_valid |= ATTR_GID;
1423		newattrs.ia_gid = fattr.cf_gid;
1424	}
1425	newattrs.ia_valid |= ATTR_MODE;
1426	newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
1427
1428	ksmbd_vfs_remove_acl_xattrs(idmap, path);
1429	/* Update posix acls */
1430	if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) {
1431		rc = set_posix_acl(idmap, path->dentry,
1432				   ACL_TYPE_ACCESS, fattr.cf_acls);
1433		if (rc < 0)
1434			ksmbd_debug(SMB,
1435				    "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
1436				    rc);
1437		if (S_ISDIR(inode->i_mode) && fattr.cf_dacls) {
1438			rc = set_posix_acl(idmap, path->dentry,
1439					   ACL_TYPE_DEFAULT, fattr.cf_dacls);
1440			if (rc)
1441				ksmbd_debug(SMB,
1442					    "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
1443					    rc);
1444		}
1445	}
1446
1447	inode_lock(inode);
1448	rc = notify_change(idmap, path->dentry, &newattrs, NULL);
1449	inode_unlock(inode);
1450	if (rc)
1451		goto out;
1452
1453	/* Check it only calling from SD BUFFER context */
1454	if (type_check && !(le16_to_cpu(pntsd->type) & DACL_PRESENT))
1455		goto out;
1456
1457	if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
1458		/* Update WinACL in xattr */
1459		ksmbd_vfs_remove_sd_xattrs(idmap, path);
1460		ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, ntsd_len,
1461				get_write);
1462	}
1463
1464out:
1465	posix_acl_release(fattr.cf_acls);
1466	posix_acl_release(fattr.cf_dacls);
1467	return rc;
1468}
1469
1470void ksmbd_init_domain(u32 *sub_auth)
1471{
1472	int i;
1473
1474	memcpy(&server_conf.domain_sid, &domain, sizeof(struct smb_sid));
1475	for (i = 0; i < 3; ++i)
1476		server_conf.domain_sid.sub_auth[i + 1] = cpu_to_le32(sub_auth[i]);
1477}