summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorMatt Barden <matt.barden@nexenta.com>2017-10-31 10:19:42 -0400
committerGordon Ross <gwr@nexenta.com>2019-08-10 10:06:13 -0400
commit9242c9192f9f0f5745fbfc92d13edb32c9bcb8c3 (patch)
tree49ba4c276894e589812426775f9a8bcfaca84e10 /usr
parentef4cfbfda6599ba454267385722705117460a9c8 (diff)
downloadillumos-gate-9242c9192f9f0f5745fbfc92d13edb32c9bcb8c3.tar.gz
11028 Need a way to add local user/group ACE from Windows
Reviewed by: Gordon Ross <gordon.ross@nexenta.com> Reviewed by: Evan Layton <evan.layton@nexenta.com> Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr')
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c101
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/libsmb.h1
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_sam.c3
-rw-r--r--usr/src/uts/common/smbsrv/ndl/samrpc.ndl35
4 files changed, 117 insertions, 23 deletions
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c
index 43ae0568e9..3ac6f2e926 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -70,16 +70,16 @@ typedef struct samr_keydata {
/*
* DomainDisplayUser All user objects (or those derived from user) with
- * userAccountControl containing the UF_NORMAL_ACCOUNT bit.
+ * userAccountControl containing the UF_NORMAL_ACCOUNT bit.
*
* DomainDisplayMachine All user objects (or those derived from user) with
- * userAccountControl containing the
- * UF_WORKSTATION_TRUST_ACCOUNT or UF_SERVER_TRUST_ACCOUNT
- * bit.
+ * userAccountControl containing the
+ * UF_WORKSTATION_TRUST_ACCOUNT or UF_SERVER_TRUST_ACCOUNT
+ * bit.
*
* DomainDisplayGroup All group objects (or those derived from group) with
- * groupType equal to GROUP_TYPE_SECURITY_UNIVERSAL or
- * GROUP_TYPE_SECURITY_ACCOUNT.
+ * groupType equal to GROUP_TYPE_SECURITY_UNIVERSAL or
+ * GROUP_TYPE_SECURITY_ACCOUNT.
*
* DomainDisplayOemUser Same as DomainDisplayUser with OEM strings
*
@@ -102,6 +102,7 @@ static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t,
DWORD);
static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *);
static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t);
+static ndr_handle_t *samr_hdlookup_any(ndr_xa_t *, ndr_hdid_t *);
static int samr_call_stub(ndr_xa_t *mxa);
static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *,
ndr_xa_t *);
@@ -214,6 +215,24 @@ samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key)
}
/*
+ * Handle lookup wrapper to validate the local context,
+ * but don't limit to one type.
+ */
+static ndr_handle_t *
+samr_hdlookup_any(ndr_xa_t *mxa, ndr_hdid_t *id)
+{
+ ndr_handle_t *hd;
+
+ if ((hd = ndr_hdlookup(mxa, id)) == NULL)
+ return (NULL);
+
+ if (hd->nh_data == NULL)
+ return (NULL);
+
+ return (hd);
+}
+
+/*
* samr_s_Connect
*
* This is a request to connect to the local SAM database. We don't
@@ -261,6 +280,49 @@ samr_s_CloseHandle(void *arg, ndr_xa_t *mxa)
}
/*
+ * samr_s_QuerySecObject
+ */
+static int
+samr_s_QuerySecObject(void *arg, ndr_xa_t *mxa)
+{
+ struct samr_QuerySecObject *param = arg;
+ ndr_hdid_t *id;
+ uint32_t status;
+ struct samr_sec_desc *sd;
+
+ id = (ndr_hdid_t *)&param->obj_handle;
+ if (samr_hdlookup_any(mxa, id) == NULL) {
+ status = NT_STATUS_INVALID_HANDLE;
+ goto QuerySecObjectError;
+ }
+
+ param->sd = NDR_MALLOC(mxa, sizeof (samr_sd_t));
+ if (param->sd == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto QuerySecObjectError;
+ }
+ param->sd->length = sizeof (struct samr_sec_desc);
+
+ sd = NDR_MALLOC(mxa, param->sd->length);
+ if (sd == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto QuerySecObjectError;
+ }
+ bzero(sd, param->sd->length);
+ sd->Revision = 1;
+ sd->Control = SE_SELF_RELATIVE;
+
+ param->sd->data = (void *)sd;
+ param->status = NT_STATUS_SUCCESS;
+ return (NDR_DRC_OK);
+
+QuerySecObjectError:
+ bzero(param, sizeof (struct samr_QuerySecObject));
+ param->status = NT_SC_ERROR(status);
+ return (NDR_DRC_OK);
+}
+
+/*
* samr_s_LookupDomain
*
* This is a request to map a domain name to a domain SID. We can map
@@ -689,8 +751,6 @@ samr_s_DeleteUser(void *arg, ndr_xa_t *mxa)
static int
samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa)
{
- static uint16_t owf_buf[8];
- static uint8_t hour_buf[SAMR_SET_USER_HOURS_SZ];
struct samr_QueryUserInfo *param = arg;
struct samr_QueryUserInfo21 *all_info;
ndr_hdid_t *id;
@@ -732,20 +792,22 @@ samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa)
all_info = &param->ru.info21;
bzero(all_info, sizeof (struct samr_QueryUserInfo21));
- all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID;
+ all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID |
+ SAMR_USER_ALL_FULLNAME | SAMR_USER_ALL_USERACCOUNTCONTROL |
+ SAMR_USER_ALL_ADMINCOMMENT;
(void) NDR_MSTRING(mxa, account.a_name,
(ndr_mstring_t *)&all_info->UserName);
- all_info->UserId = data->kd_rid;
+ (void) NDR_MSTRING(mxa, account.a_name,
+ (ndr_mstring_t *)&all_info->FullName);
+ (void) NDR_MSTRING(mxa, "",
+ (ndr_mstring_t *)&all_info->AdminComment);
- all_info->LmOwfPassword.length = 16;
- all_info->LmOwfPassword.maxlen = 16;
- all_info->LmOwfPassword.buf = owf_buf;
- all_info->NtOwfPassword.length = 16;
- all_info->NtOwfPassword.maxlen = 16;
- all_info->NtOwfPassword.buf = owf_buf;
- all_info->LogonHours.units_per_week = SAMR_HOURS_PER_WEEK;
- all_info->LogonHours.hours = hour_buf;
+ all_info->UserId = data->kd_rid;
+ all_info->UserAccountControl = SAMR_AF_NORMAL_ACCOUNT |
+ SAMR_AF_DONT_EXPIRE_PASSWD;
+ if ((account.a_flags & SMB_PWF_DISABLE) != 0)
+ all_info->UserAccountControl |= SAMR_AF_ACCOUNTDISABLE;
param->address = 1;
param->switch_index = SAMR_QUERY_USER_ALL_INFO;
@@ -1851,6 +1913,7 @@ samr_s_Connect5(void *arg, ndr_xa_t *mxa)
static ndr_stub_table_t samr_stub_table[] = {
{ samr_s_Connect, SAMR_OPNUM_Connect },
{ samr_s_CloseHandle, SAMR_OPNUM_CloseHandle },
+ { samr_s_QuerySecObject, SAMR_OPNUM_QuerySecObject },
{ samr_s_LookupDomain, SAMR_OPNUM_LookupDomain },
{ samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains },
{ samr_s_OpenDomain, SAMR_OPNUM_OpenDomain },
diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
index b9357d1e49..25bd45f6bb 100644
--- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h
+++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
@@ -868,6 +868,7 @@ typedef struct smb_account {
smb_sid_t *a_sid;
smb_sid_t *a_domsid;
uint32_t a_rid;
+ uint32_t a_flags;
} smb_account_t;
uint32_t smb_sam_lookup_name(char *, char *, uint16_t, smb_account_t *);
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_sam.c b/usr/src/lib/smbsrv/libsmb/common/smb_sam.c
index 68a7aa2131..77e82f2366 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_sam.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_sam.c
@@ -22,7 +22,7 @@
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
- * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
* Copyright 2018 RackTop Systems.
*/
@@ -260,6 +260,7 @@ smb_sam_lookup_sid(smb_sid_t *sid, smb_account_t *account)
return (NT_STATUS_NO_SUCH_USER);
account->a_name = strdup(smbpw.pw_name);
+ account->a_flags = smbpw.pw_flags;
break;
case SMB_IDMAP_GROUP:
diff --git a/usr/src/uts/common/smbsrv/ndl/samrpc.ndl b/usr/src/uts/common/smbsrv/ndl/samrpc.ndl
index ef47fff452..a0055ca101 100644
--- a/usr/src/uts/common/smbsrv/ndl/samrpc.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/samrpc.ndl
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _MLSVC_SAM_NDL_
@@ -488,6 +488,33 @@ struct samr_CloseHandle {
/*
***********************************************************************
+ * QuerySecObject
+ *
+ * Returns the SecurityDescriptor of the object. Support not complete.
+ *
+ * QuerySecObject (
+ * IN samr_handle_t obj_handle,
+ * IN SECURITY_INFO secinfo,
+ * OUT samr_sd_t *sd,
+ * OUT DWORD status
+ * )
+ *
+ ***********************************************************************
+ */
+
+typedef DWORD SECURITY_INFO;
+
+OPERATION(SAMR_OPNUM_QuerySecObject)
+struct samr_QuerySecObject {
+ IN samr_handle_t obj_handle;
+ IN SECURITY_INFO secinfo;
+ OUT samr_sd_t *sd;
+ OUT DWORD status;
+};
+
+
+/*
+ ***********************************************************************
* LookupDomain: lookup up the domain SID.
***********************************************************************
*/
@@ -540,7 +567,7 @@ struct samr_EnumLocalDomain {
/*
***********************************************************************
* OpenDomain
- *
+ *
* Open a specific domain within the SAM. From this I assume that each
* SAM can handle multiple domains so you need to identify the one with
* which you want to work. Working with a domain handle does appear to
@@ -883,7 +910,7 @@ struct samr_DeleteUser {
* offsets used by the unmarshalling code at runtime. In order to
* simplify things it is useful to use a naming convention that
* indicates the switch value for each structure.
- *
+ *
***********************************************************************
*/
@@ -1392,6 +1419,8 @@ union samr_interface {
struct samr_Connect Connect;
CASE(SAMR_OPNUM_CloseHandle)
struct samr_CloseHandle CloseHandle;
+ CASE(SAMR_OPNUM_QuerySecObject)
+ struct samr_QuerySecObject QuerySecObject;
CASE(SAMR_OPNUM_LookupDomain)
struct samr_LookupDomain LookupDomain;
CASE(SAMR_OPNUM_EnumLocalDomains)