Print this page
1575 untangle libmlrpc from SMB server
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
NEX-15052 Need a way to add appliance local user/group ACE from Windows
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15052 Need a way to add appliance local user/group ACE from Windows
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-3106 ACL editor crash in Windows 2012 R2
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
re #12435 rb3958 r10 is added 2 times to panic info
re #12393 rb3935 Kerberos and smbd disagree about who is our AD server

@@ -19,11 +19,11 @@
  * CDDL HEADER END
  */
 
 /*
  * 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.
  */
 
 /*
  * Security Accounts Manager RPC (SAMR) server-side interface.
  *

@@ -37,12 +37,12 @@
 #include <strings.h>
 #include <unistd.h>
 #include <netdb.h>
 #include <assert.h>
 #include <grp.h>
+#include <libmlrpc/libmlrpc.h>
 #include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
 #include <smbsrv/libmlsvc.h>
 #include <smbsrv/smbinfo.h>
 #include <smbsrv/nmpipes.h>
 #include <smbsrv/ndl/samrpc.ndl>
 #include <samlib.h>

@@ -100,10 +100,11 @@
 
 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 *);
 
 static ndr_stub_table_t samr_stub_table[];

@@ -212,10 +213,28 @@
 
         return (hd);
 }
 
 /*
+ * 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
  * support any form of update request and our database doesn't
  * contain any private information, so there is little point in

@@ -259,10 +278,53 @@
         param->status = 0;
         return (NDR_DRC_OK);
 }
 
 /*
+ * 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
  * the primary domain name, our local domain name (hostname) and the
  * builtin domain names to the appropriate SID. Anything else will be

@@ -687,12 +749,10 @@
  */
 /*ARGSUSED*/
 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;
         ndr_handle_t                    *hd;
         samr_keydata_t                  *data;

@@ -730,25 +790,27 @@
         }
 
         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);
+        (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->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;
 
-        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;
-
         param->address = 1;
         param->switch_index = SAMR_QUERY_USER_ALL_INFO;
         param->status = NT_STATUS_SUCCESS;
         smb_account_free(&account);
         smb_sid_free(sid);

@@ -1849,10 +1911,11 @@
 }
 
 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 },
         { samr_s_QueryDomainInfo,       SAMR_OPNUM_QueryDomainInfo },
         { samr_s_QueryInfoDomain2,      SAMR_OPNUM_QueryInfoDomain2 },