29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * CDDL HEADER START
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * The contents of this file are subject to the terms of the
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Common Development and Distribution License (the "License").
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * You may not use this file except in compliance with the License.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * or http://www.opensolaris.org/os/licensing.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * See the License for the specific language governing permissions
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * and limitations under the License.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * When distributing Covered Code, include this CDDL HEADER in each
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * If applicable, add the following below this CDDL HEADER, with the
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * fields enclosed by brackets "[]" replaced with your own identifying
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * information: Portions Copyright [yyyy] [name of copyright owner]
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * CDDL HEADER END
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Use is subject to license terms.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#include <stddef.h>
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#include <strings.h>
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#include <assert.h>
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <smbsrv/smb.h>
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#include <smbsrv/smb_sid.h>
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#include <smbsrv/smb_idmap.h>
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#define ACE_ALL_TYPES 0x001F
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * ACE groups within a DACL
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * This is from lower to higher ACE order priority
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#define SMB_AG_START 0
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#define SMB_AG_ALW_INHRT 0
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#define SMB_AG_DNY_INHRT 1
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#define SMB_AG_ALW_DRCT 2
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#define SMB_AG_DNY_DRCT 3
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#define SMB_AG_NUM 4
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright#define DEFAULT_DACL_ACENUM 2
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightacl_t *acl_alloc(enum acl_type);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wrightstatic idmap_stat smb_fsacl_getsids(smb_idmap_batch_t *, acl_t *);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic acl_t *smb_fsacl_null_empty(boolean_t);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic uint16_t smb_ace_len(smb_ace_t *);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic uint32_t smb_ace_mask_g2s(uint32_t);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic uint16_t smb_ace_flags_tozfs(uint8_t);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic uint8_t smb_ace_flags_fromzfs(uint16_t);
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wrightstatic boolean_t smb_ace_wellknown_update(const char *, ace_t *);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_acl_t *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_acl_alloc(uint8_t revision, uint16_t bsize, uint16_t acecnt)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_acl_t *acl;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright int size;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright size = sizeof (smb_acl_t) + (acecnt * sizeof (smb_ace_t));
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if ((acl = malloc(size)) == NULL)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (NULL);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl->sl_revision = revision;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl->sl_bsize = bsize;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl->sl_acecnt = acecnt;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl->sl_aces = (smb_ace_t *)(acl + 1);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright list_create(&acl->sl_sorted, sizeof (smb_ace_t),
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright offsetof(smb_ace_t, se_sln));
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (acl);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightvoid
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_acl_free(smb_acl_t *acl)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright int i;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright void *ace;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (acl == NULL)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright for (i = 0; i < acl->sl_acecnt; i++)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_sid_free(acl->sl_aces[i].se_sid);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright while ((ace = list_head(&acl->sl_sorted)) != NULL)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright list_remove(&acl->sl_sorted, ace);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright list_destroy(&acl->sl_sorted);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright free(acl);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * smb_acl_len
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Returns the size of given ACL in bytes. Note that this
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * is not an in-memory size, it's the ACL's size as it would
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * appear on the wire
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightuint16_t
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_acl_len(smb_acl_t *acl)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return ((acl) ? acl->sl_bsize : 0);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*ARGSUSED*/
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightboolean_t
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_acl_isvalid(smb_acl_t *acl, int which_acl)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (acl->sl_bsize < SMB_ACL_HDRSIZE)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (B_FALSE);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (acl->sl_revision != ACL_REVISION) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright /*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * we are rejecting ACLs with object-specific ACEs for now
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (B_FALSE);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (B_TRUE);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * smb_acl_sort
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Sorts the given ACL in place if it needs to be sorted.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * The following is an excerpt from MSDN website.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Order of ACEs in a DACL
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * For Windows NT versions 4.0 and earlier, the preferred order of ACEs
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * is simple: In a DACL, all access-denied ACEs should precede any
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * access-allowed ACEs.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * For Windows 2000 or later, the proper order of ACEs is more complicated
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * because of the introduction of object-specific ACEs and automatic
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * inheritance.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * The following describes the preferred order:
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * To ensure that noninherited ACEs have precedence over inherited ACEs,
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * place all noninherited ACEs in a group before any inherited ACEs. This
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * ordering ensures, for example, that a noninherited access-denied ACE
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * is enforced regardless of any inherited ACE that allows access.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Within the groups of noninherited ACEs and inherited ACEs, order ACEs
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * according to ACE type, as the following shows:
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * . Access-denied ACEs that apply to the object itself
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * . Access-denied ACEs that apply to a subobject of the
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * object, such as a property set or property
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * . Access-allowed ACEs that apply to the object itself
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * . Access-allowed ACEs that apply to a subobject of the object
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * So, here is the desired ACE order
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * deny-direct, allow-direct, deny-inherited, allow-inherited
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Of course, not all ACE types are required in an ACL.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightvoid
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_acl_sort(smb_acl_t *acl)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright list_t ace_grps[SMB_AG_NUM];
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright list_t *alist;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_ace_t *ace;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright uint8_t ace_flags;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright int ag, i;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright assert(acl);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (acl->sl_acecnt == 0) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright /*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * ACL with no entry is a valid ACL and it means
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * no access for anybody.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright for (i = SMB_AG_START; i < SMB_AG_NUM; i++) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright list_create(&ace_grps[i], sizeof (smb_ace_t),
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright offsetof(smb_ace_t, se_sln));
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright for (i = 0, ace = acl->sl_aces; i < acl->sl_acecnt; ++i, ace++) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace_flags = ace->se_hdr.se_flags;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright switch (ace->se_hdr.se_type) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright case ACCESS_DENIED_ACE_TYPE:
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ag = (ace_flags & INHERITED_ACE) ?
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright SMB_AG_DNY_INHRT : SMB_AG_DNY_DRCT;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright break;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright case ACCESS_ALLOWED_ACE_TYPE:
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ag = (ace_flags & INHERITED_ACE) ?
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright SMB_AG_ALW_INHRT : SMB_AG_ALW_DRCT;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright break;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright default:
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright /*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * This is the lowest priority group so we put
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * evertything unknown here.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ag = SMB_AG_ALW_INHRT;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright break;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright /* Add the ACE to the selected group */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright list_insert_tail(&ace_grps[ag], ace);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright /*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * start with highest priority ACE group and append
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * the ACEs to the ACL.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright for (i = SMB_AG_NUM - 1; i >= SMB_AG_START; i--) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright alist = &ace_grps[i];
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright while ((ace = list_head(alist)) != NULL) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright list_remove(alist, ace);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright list_insert_tail(&acl->sl_sorted, ace);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright list_destroy(alist);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * smb_acl_from_zfs
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Converts given ZFS ACL to a Windows ACL.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * A pointer to allocated memory for the Windows ACL will be
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * returned upon successful conversion.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_acl_t *
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wrightsmb_acl_from_zfs(acl_t *zacl)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace_t *zace;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright int numaces;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_acl_t *acl;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_ace_t *ace;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_idmap_batch_t sib;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_idmap_t *sim;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright idmap_stat idm_stat;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright idm_stat = smb_idmap_batch_create(&sib, zacl->acl_cnt,
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright SMB_IDMAP_ID2SID);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (idm_stat != IDMAP_SUCCESS)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (NULL);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright if (smb_fsacl_getsids(&sib, zacl) != IDMAP_SUCCESS) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_idmap_batch_destroy(&sib);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (NULL);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl = smb_acl_alloc(ACL_REVISION, SMB_ACL_HDRSIZE, zacl->acl_cnt);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright sim = sib.sib_maps;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright for (numaces = 0, zace = zacl->acl_aclp;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright numaces < zacl->acl_cnt;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace++, numaces++, sim++) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright assert(sim->sim_sid);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (sim->sim_sid == NULL) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_acl_free(acl);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl = NULL;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright break;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace = &acl->sl_aces[numaces];
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace->se_hdr.se_type = zace->a_type;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace->se_hdr.se_flags = smb_ace_flags_fromzfs(zace->a_flags);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace->se_mask = zace->a_access_mask;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace->se_sid = smb_sid_dup(sim->sim_sid);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace->se_hdr.se_bsize = smb_ace_len(ace);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl->sl_bsize += ace->se_hdr.se_bsize;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_idmap_batch_destroy(&sib);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (acl);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * smb_acl_to_zfs
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Converts given Windows ACL to a ZFS ACL.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * fs_acl will contain a pointer to the created ZFS ACL.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * The allocated memory should be freed by calling
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * smb_fsacl_free().
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Since the output parameter, fs_acl, is allocated in this
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * function, the caller has to make sure *fs_acl is NULL which
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * means it's not pointing to any memory.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightuint32_t
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright char sidstr[SMB_SID_STRSZ];
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_ace_t *ace;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl_t *zacl;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace_t *zace;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_idmap_batch_t sib;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_idmap_t *sim;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright idmap_stat idm_stat;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright int i;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright assert(fs_acl);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright assert(*fs_acl == NULL);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (acl && !smb_acl_isvalid(acl, which_acl))
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (NT_STATUS_INVALID_ACL);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if ((acl == NULL) || (acl->sl_acecnt == 0)) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (which_acl == SMB_DACL_SECINFO) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *fs_acl = smb_fsacl_null_empty(acl == NULL);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (NT_STATUS_SUCCESS);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright idm_stat = smb_idmap_batch_create(&sib, acl->sl_acecnt,
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright SMB_IDMAP_SID2ID);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (idm_stat != IDMAP_SUCCESS)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (NT_STATUS_INTERNAL_ERROR);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zacl = smb_fsacl_alloc(acl->sl_acecnt, flags);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace = zacl->acl_aclp;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace = acl->sl_aces;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright sim = sib.sib_maps;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright for (i = 0; i < acl->sl_acecnt; i++, zace++, ace++, sim++) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace->a_type = ace->se_hdr.se_type & ACE_ALL_TYPES;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace->a_access_mask = smb_ace_mask_g2s(ace->se_mask);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace->a_flags = smb_ace_flags_tozfs(ace->se_hdr.se_flags);
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright zace->a_who = (uid_t)-1;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright smb_sid_tostr(ace->se_sid, sidstr);
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright if (!smb_ace_wellknown_update(sidstr, zace)) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright sim->sim_id = &zace->a_who;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright idm_stat = smb_idmap_batch_getid(sib.sib_idmaph, sim,
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright ace->se_sid, SMB_IDMAP_UNKNOWN);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (idm_stat != IDMAP_SUCCESS) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_fsacl_free(zacl);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_idmap_batch_destroy(&sib);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (NT_STATUS_INTERNAL_ERROR);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright idm_stat = smb_idmap_batch_getmappings(&sib);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (idm_stat != IDMAP_SUCCESS) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_fsacl_free(zacl);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_idmap_batch_destroy(&sib);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (NT_STATUS_NONE_MAPPED);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright /*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Set the ACEs group flag based on the type of ID returned.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace = zacl->acl_aclp;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace = acl->sl_aces;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright sim = sib.sib_maps;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright for (i = 0; i < acl->sl_acecnt; i++, zace++, ace++, sim++) {
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright if (zace->a_who == (uid_t)-1)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright continue;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (sim->sim_idtype == SMB_IDMAP_GROUP)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace->a_flags |= ACE_IDENTIFIER_GROUP;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_idmap_batch_destroy(&sib);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *fs_acl = zacl;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (NT_STATUS_SUCCESS);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wrightstatic boolean_t
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wrightsmb_ace_wellknown_update(const char *sid, ace_t *zace)
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright{
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright struct {
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright char *sid;
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright uint16_t flags;
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright } map[] = {
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright { NT_WORLD_SIDSTR, ACE_EVERYONE },
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright { NT_BUILTIN_CURRENT_OWNER_SIDSTR, ACE_OWNER },
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright { NT_BUILTIN_CURRENT_GROUP_SIDSTR,
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright (ACE_GROUP | ACE_IDENTIFIER_GROUP) },
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright };
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright int i;
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright for (i = 0; i < (sizeof (map) / sizeof (map[0])); ++i) {
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright if (strcmp(sid, map[i].sid) == 0) {
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright zace->a_flags |= map[i].flags;
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright return (B_TRUE);
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright }
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright }
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright return (B_FALSE);
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright}
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * smb_fsacl_getsids
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Batch all the uid/gid in given ZFS ACL to get their corresponding SIDs.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic idmap_stat
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wrightsmb_fsacl_getsids(smb_idmap_batch_t *sib, acl_t *zacl)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace_t *zace;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright idmap_stat idm_stat;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_idmap_t *sim;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright uid_t id;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright int i, idtype;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright sim = sib->sib_maps;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright for (i = 0, zace = zacl->acl_aclp; i < zacl->acl_cnt;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace++, i++, sim++) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright switch (zace->a_flags & ACE_TYPE_FLAGS) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright case ACE_OWNER:
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright idtype = SMB_IDMAP_OWNERAT;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright break;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright case (ACE_GROUP | ACE_IDENTIFIER_GROUP):
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright /* owning group */
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright idtype = SMB_IDMAP_GROUPAT;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright break;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright case ACE_IDENTIFIER_GROUP:
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright /* regular group */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright id = zace->a_who;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright idtype = SMB_IDMAP_GROUP;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright break;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright case ACE_EVERYONE:
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright idtype = SMB_IDMAP_EVERYONE;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright break;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright default:
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright /* user entry */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright id = zace->a_who;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright idtype = SMB_IDMAP_USER;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright idm_stat = smb_idmap_batch_getsid(sib->sib_idmaph, sim,
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright id, idtype);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (idm_stat != IDMAP_SUCCESS) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (idm_stat);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright idm_stat = smb_idmap_batch_getmappings(sib);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (idm_stat);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * smb_fsacl_null_empty
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * NULL DACL means everyone full-access
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Empty DACL means everyone full-deny
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * ZFS ACL must have at least one entry so smb server has
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * to simulate the aforementioned expected behavior by adding
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * an entry in case the requested DACL is null or empty. Adding
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * a everyone full-deny entry has proved to be problematic in
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * tests since a deny entry takes precedence over allow entries.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * So, instead of adding a everyone full-deny, an owner ACE with
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * owner implicit permissions will be set.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic acl_t *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_fsacl_null_empty(boolean_t null)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl_t *zacl;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ace_t *zace;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zacl = smb_fsacl_alloc(1, ACL_AUTO_INHERIT);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace = zacl->acl_aclp;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (null) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace->a_access_mask = ACE_ALL_PERMS;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace->a_flags = ACE_EVERYONE;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright } else {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace->a_access_mask = ACE_READ_ACL | ACE_WRITE_ACL |
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright ACE_READ_ATTRIBUTES;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright zace->a_flags = ACE_OWNER;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (zacl);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * FS ACL (acl_t) Functions
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightacl_t *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_fsacl_alloc(int acenum, int flags)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl_t *acl;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl = acl_alloc(ACE_T);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl->acl_cnt = acenum;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if ((acl->acl_aclp = malloc(acl->acl_entry_size * acenum)) == NULL)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (NULL);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl->acl_flags = flags;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (acl);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightvoid
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_fsacl_free(acl_t *acl)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (acl)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright acl_free(acl);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * ACE Functions
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * smb_ace_len
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Returns the length of the given ACE as it appears in an
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * ACL on the wire (i.e. a flat buffer which contains the SID)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic uint16_t
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_ace_len(smb_ace_t *ace)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright assert(ace);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright assert(ace->se_sid);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (ace == NULL)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (0);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (SMB_ACE_HDRSIZE + sizeof (ace->se_mask) +
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_sid_len(ace->se_sid));
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * smb_ace_mask_g2s
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * Converts generic access bits in the given mask (if any)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * to file specific bits. Generic access masks shouldn't be
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * stored in filesystem ACEs.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic uint32_t
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_ace_mask_g2s(uint32_t mask)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (mask & GENERIC_ALL) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright mask &= ~(GENERIC_ALL | GENERIC_READ | GENERIC_WRITE
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright | GENERIC_EXECUTE);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright mask |= FILE_ALL_ACCESS;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (mask);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (mask & GENERIC_READ) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright mask &= ~GENERIC_READ;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright mask |= FILE_GENERIC_READ;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (mask & GENERIC_WRITE) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright mask &= ~GENERIC_WRITE;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright mask |= FILE_GENERIC_WRITE;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (mask & GENERIC_EXECUTE) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright mask &= ~GENERIC_EXECUTE;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright mask |= FILE_GENERIC_EXECUTE;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (mask);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/*
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * smb_ace_flags_tozfs
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright *
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * This function maps the flags which have different values
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * in Windows and Solaris. The ones with the same value are
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * transferred untouched.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic uint16_t
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_ace_flags_tozfs(uint8_t c_flags)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright uint16_t z_flags = 0;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (c_flags & SUCCESSFUL_ACCESS_ACE_FLAG)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright z_flags |= ACE_SUCCESSFUL_ACCESS_ACE_FLAG;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (c_flags & FAILED_ACCESS_ACE_FLAG)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright z_flags |= ACE_FAILED_ACCESS_ACE_FLAG;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (c_flags & INHERITED_ACE)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright z_flags |= ACE_INHERITED_ACE;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright z_flags |= (c_flags & ACE_INHERIT_FLAGS);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (z_flags);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic uint8_t
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_ace_flags_fromzfs(uint16_t z_flags)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright{
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright uint8_t c_flags;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright c_flags = z_flags & ACE_INHERIT_FLAGS;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (z_flags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright c_flags |= SUCCESSFUL_ACCESS_ACE_FLAG;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (z_flags & ACE_FAILED_ACCESS_ACE_FLAG)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright c_flags |= FAILED_ACCESS_ACE_FLAG;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (z_flags & ACE_INHERITED_ACE)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright c_flags |= INHERITED_ACE;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright return (c_flags);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright}