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


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 /*
  28  * Security Accounts Manager RPC (SAMR) server-side interface.
  29  *
  30  * The SAM is a hierarchical database:
  31  * - If you want to talk to the SAM you need a SAM handle.
  32  * - If you want to work with a domain, use the SAM handle.
  33  *   to obtain a domain handle.
  34  * - Use domain handles to obtain user handles etc.
  35  */
  36 
  37 #include <strings.h>
  38 #include <unistd.h>
  39 #include <netdb.h>
  40 #include <assert.h>
  41 #include <grp.h>

  42 #include <smbsrv/libsmb.h>
  43 #include <smbsrv/libmlrpc.h>
  44 #include <smbsrv/libmlsvc.h>
  45 #include <smbsrv/smbinfo.h>
  46 #include <smbsrv/nmpipes.h>
  47 #include <smbsrv/ndl/samrpc.ndl>
  48 #include <samlib.h>
  49 
  50 /*
  51  * The keys associated with the various handles dispensed by the SAMR
  52  * server.  These keys can be used to validate client activity.
  53  * These values are never passed over the wire so security shouldn't
  54  * be an issue.
  55  */
  56 typedef enum {
  57         SAMR_KEY_NULL = 0,
  58         SAMR_KEY_CONNECT,
  59         SAMR_KEY_DOMAIN,
  60         SAMR_KEY_USER,
  61         SAMR_KEY_GROUP,
  62         SAMR_KEY_ALIAS
  63 } samr_key_t;


  85  *
  86  * DomainDisplayOemGroup Same as DomainDisplayGroup with OEM strings
  87  */
  88 typedef enum {
  89         DomainDisplayUser = 1,
  90         DomainDisplayMachine,
  91         DomainDispalyGroup,
  92         DomainDisplayOemUser,
  93         DomainDisplayOemGroup
  94 } samr_displvl_t;
  95 
  96 #define SAMR_VALID_DISPLEVEL(lvl) \
  97         (((lvl) >= DomainDisplayUser) && ((lvl) <= DomainDisplayOemGroup))
  98 
  99 #define SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser)
 100 
 101 static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t,
 102     DWORD);
 103 static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *);
 104 static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t);

 105 static int samr_call_stub(ndr_xa_t *mxa);
 106 static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *,
 107     ndr_xa_t *);
 108 
 109 static ndr_stub_table_t samr_stub_table[];
 110 
 111 static ndr_service_t samr_service = {
 112         "SAMR",                         /* name */
 113         "Security Accounts Manager",    /* desc */
 114         "\\samr",                       /* endpoint */
 115         PIPE_LSASS,                     /* sec_addr_port */
 116         "12345778-1234-abcd-ef00-0123456789ac", 1,      /* abstract */
 117         NDR_TRANSFER_SYNTAX_UUID,               2,      /* transfer */
 118         0,                              /* no bind_instance_size */
 119         NULL,                           /* no bind_req() */
 120         NULL,                           /* no unbind_and_close() */
 121         samr_call_stub,                 /* call_stub() */
 122         &TYPEINFO(samr_interface),  /* interface ti */
 123         samr_stub_table                 /* stub_table */
 124 };


 197  */
 198 static ndr_handle_t *
 199 samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key)
 200 {
 201         ndr_handle_t *hd;
 202         samr_keydata_t *data;
 203 
 204         if ((hd = ndr_hdlookup(mxa, id)) == NULL)
 205                 return (NULL);
 206 
 207         if ((data = (samr_keydata_t *)hd->nh_data) == NULL)
 208                 return (NULL);
 209 
 210         if (data->kd_key != key)
 211                 return (NULL);
 212 
 213         return (hd);
 214 }
 215 
 216 /*


















 217  * samr_s_Connect
 218  *
 219  * This is a request to connect to the local SAM database. We don't
 220  * support any form of update request and our database doesn't
 221  * contain any private information, so there is little point in
 222  * doing any access access checking here.
 223  *
 224  * Return a handle for use with subsequent SAM requests.
 225  */
 226 static int
 227 samr_s_Connect(void *arg, ndr_xa_t *mxa)
 228 {
 229         struct samr_Connect *param = arg;
 230         ndr_hdid_t *id;
 231 
 232         id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
 233         if (id) {
 234                 bcopy(id, &param->handle, sizeof (samr_handle_t));
 235                 param->status = 0;
 236         } else {


 244 /*
 245  * samr_s_CloseHandle
 246  *
 247  * Close the SAM interface specified by the handle.
 248  * Free the handle and zero out the result handle for the client.
 249  */
 250 static int
 251 samr_s_CloseHandle(void *arg, ndr_xa_t *mxa)
 252 {
 253         struct samr_CloseHandle *param = arg;
 254         ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
 255 
 256         samr_hdfree(mxa, id);
 257 
 258         bzero(&param->result_handle, sizeof (samr_handle_t));
 259         param->status = 0;
 260         return (NDR_DRC_OK);
 261 }
 262 
 263 /*











































 264  * samr_s_LookupDomain
 265  *
 266  * This is a request to map a domain name to a domain SID. We can map
 267  * the primary domain name, our local domain name (hostname) and the
 268  * builtin domain names to the appropriate SID. Anything else will be
 269  * rejected.
 270  */
 271 static int
 272 samr_s_LookupDomain(void *arg, ndr_xa_t *mxa)
 273 {
 274         struct samr_LookupDomain *param = arg;
 275         char *domain_name;
 276         smb_domain_t di;
 277 
 278         if ((domain_name = (char *)param->domain_name.str) == NULL) {
 279                 bzero(param, sizeof (struct samr_LookupDomain));
 280                 param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
 281                 return (NDR_DRC_OK);
 282         }
 283 


 672 {
 673         struct samr_DeleteUser *param = arg;
 674 
 675         bzero(param, sizeof (struct samr_DeleteUser));
 676         param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
 677         return (NDR_DRC_OK);
 678 }
 679 
 680 /*
 681  * samr_s_QueryUserInfo
 682  *
 683  * Returns:
 684  * NT_STATUS_SUCCESS
 685  * NT_STATUS_ACCESS_DENIED
 686  * NT_STATUS_INVALID_INFO_CLASS
 687  */
 688 /*ARGSUSED*/
 689 static int
 690 samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa)
 691 {
 692         static uint16_t                 owf_buf[8];
 693         static uint8_t                  hour_buf[SAMR_SET_USER_HOURS_SZ];
 694         struct samr_QueryUserInfo       *param = arg;
 695         struct samr_QueryUserInfo21     *all_info;
 696         ndr_hdid_t                      *id;
 697         ndr_handle_t                    *hd;
 698         samr_keydata_t                  *data;
 699         smb_domain_t                    di;
 700         smb_account_t                   account;
 701         smb_sid_t                       *sid;
 702         uint32_t                        status;
 703 
 704         id = (ndr_hdid_t *)&param->user_handle;
 705         if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) {
 706                 status = NT_STATUS_INVALID_HANDLE;
 707                 goto QueryUserInfoError;
 708         }
 709 
 710         data = (samr_keydata_t *)hd->nh_data;
 711 
 712         if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) {
 713                 status = NT_STATUS_ACCESS_DENIED;


 715         }
 716 
 717         if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) {
 718                 status = NT_STATUS_ACCESS_DENIED;
 719                 goto QueryUserInfoError;
 720         }
 721 
 722         if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) {
 723                 status = NT_STATUS_ACCESS_DENIED;
 724                 goto QueryUserInfoError;
 725         }
 726 
 727         if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) {
 728                 status = NT_STATUS_ACCESS_DENIED;
 729                 goto QueryUserInfoError;
 730         }
 731 
 732         all_info = &param->ru.info21;
 733         bzero(all_info, sizeof (struct samr_QueryUserInfo21));
 734 
 735         all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID;


 736 
 737         (void) NDR_MSTRING(mxa, account.a_name,
 738             (ndr_mstring_t *)&all_info->UserName);





 739         all_info->UserId = data->kd_rid;




 740 
 741         all_info->LmOwfPassword.length = 16;
 742         all_info->LmOwfPassword.maxlen = 16;
 743         all_info->LmOwfPassword.buf = owf_buf;
 744         all_info->NtOwfPassword.length = 16;
 745         all_info->NtOwfPassword.maxlen = 16;
 746         all_info->NtOwfPassword.buf = owf_buf;
 747         all_info->LogonHours.units_per_week = SAMR_HOURS_PER_WEEK;
 748         all_info->LogonHours.hours = hour_buf;
 749 
 750         param->address = 1;
 751         param->switch_index = SAMR_QUERY_USER_ALL_INFO;
 752         param->status = NT_STATUS_SUCCESS;
 753         smb_account_free(&account);
 754         smb_sid_free(sid);
 755         return (NDR_DRC_OK);
 756 
 757 QueryUserInfoError:
 758         smb_sid_free(sid);
 759         bzero(param, sizeof (struct samr_QueryUserInfo));
 760         param->status = NT_SC_ERROR(status);
 761         return (NDR_DRC_OK);
 762 }
 763 
 764 /*
 765  * samr_s_QueryUserGroups
 766  *
 767  * Request the list of groups of which a user is a member.
 768  * The user is identified from the handle, which contains an
 769  * rid in the discriminator field. Note that this is a local user.


1834 
1835 /*
1836  * samr_s_Connect5
1837  *
1838  * This is the connect5 form of the connect request used by Windows XP.
1839  * Returns an RPC fault for now.
1840  */
1841 /*ARGSUSED*/
1842 static int
1843 samr_s_Connect5(void *arg, ndr_xa_t *mxa)
1844 {
1845         struct samr_Connect5 *param = arg;
1846 
1847         bzero(param, sizeof (struct samr_Connect5));
1848         return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
1849 }
1850 
1851 static ndr_stub_table_t samr_stub_table[] = {
1852         { samr_s_Connect,               SAMR_OPNUM_Connect },
1853         { samr_s_CloseHandle,           SAMR_OPNUM_CloseHandle },

1854         { samr_s_LookupDomain,          SAMR_OPNUM_LookupDomain },
1855         { samr_s_EnumLocalDomains,      SAMR_OPNUM_EnumLocalDomains },
1856         { samr_s_OpenDomain,            SAMR_OPNUM_OpenDomain },
1857         { samr_s_QueryDomainInfo,       SAMR_OPNUM_QueryDomainInfo },
1858         { samr_s_QueryInfoDomain2,      SAMR_OPNUM_QueryInfoDomain2 },
1859         { samr_s_LookupNames,           SAMR_OPNUM_LookupNames },
1860         { samr_s_OpenUser,              SAMR_OPNUM_OpenUser },
1861         { samr_s_DeleteUser,            SAMR_OPNUM_DeleteUser },
1862         { samr_s_QueryUserInfo,         SAMR_OPNUM_QueryUserInfo },
1863         { samr_s_QueryUserGroups,       SAMR_OPNUM_QueryUserGroups },
1864         { samr_s_OpenGroup,             SAMR_OPNUM_OpenGroup },
1865         { samr_s_Connect2,              SAMR_OPNUM_Connect2 },
1866         { samr_s_GetUserPwInfo,         SAMR_OPNUM_GetUserPwInfo },
1867         { samr_s_CreateUser,            SAMR_OPNUM_CreateUser },
1868         { samr_s_ChangePasswordUser2,   SAMR_OPNUM_ChangePasswordUser2 },
1869         { samr_s_GetDomainPwInfo,       SAMR_OPNUM_GetDomainPwInfo },
1870         { samr_s_SetUserInfo,           SAMR_OPNUM_SetUserInfo },
1871         { samr_s_Connect4,              SAMR_OPNUM_Connect4 },
1872         { samr_s_Connect5,              SAMR_OPNUM_Connect5 },
1873         { samr_s_QueryDispInfo,         SAMR_OPNUM_QueryDispInfo },




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 /*
  28  * Security Accounts Manager RPC (SAMR) server-side interface.
  29  *
  30  * The SAM is a hierarchical database:
  31  * - If you want to talk to the SAM you need a SAM handle.
  32  * - If you want to work with a domain, use the SAM handle.
  33  *   to obtain a domain handle.
  34  * - Use domain handles to obtain user handles etc.
  35  */
  36 
  37 #include <strings.h>
  38 #include <unistd.h>
  39 #include <netdb.h>
  40 #include <assert.h>
  41 #include <grp.h>
  42 #include <libmlrpc/libmlrpc.h>
  43 #include <smbsrv/libsmb.h>

  44 #include <smbsrv/libmlsvc.h>
  45 #include <smbsrv/smbinfo.h>
  46 #include <smbsrv/nmpipes.h>
  47 #include <smbsrv/ndl/samrpc.ndl>
  48 #include <samlib.h>
  49 
  50 /*
  51  * The keys associated with the various handles dispensed by the SAMR
  52  * server.  These keys can be used to validate client activity.
  53  * These values are never passed over the wire so security shouldn't
  54  * be an issue.
  55  */
  56 typedef enum {
  57         SAMR_KEY_NULL = 0,
  58         SAMR_KEY_CONNECT,
  59         SAMR_KEY_DOMAIN,
  60         SAMR_KEY_USER,
  61         SAMR_KEY_GROUP,
  62         SAMR_KEY_ALIAS
  63 } samr_key_t;


  85  *
  86  * DomainDisplayOemGroup Same as DomainDisplayGroup with OEM strings
  87  */
  88 typedef enum {
  89         DomainDisplayUser = 1,
  90         DomainDisplayMachine,
  91         DomainDispalyGroup,
  92         DomainDisplayOemUser,
  93         DomainDisplayOemGroup
  94 } samr_displvl_t;
  95 
  96 #define SAMR_VALID_DISPLEVEL(lvl) \
  97         (((lvl) >= DomainDisplayUser) && ((lvl) <= DomainDisplayOemGroup))
  98 
  99 #define SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser)
 100 
 101 static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t,
 102     DWORD);
 103 static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *);
 104 static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t);
 105 static ndr_handle_t *samr_hdlookup_any(ndr_xa_t *, ndr_hdid_t *);
 106 static int samr_call_stub(ndr_xa_t *mxa);
 107 static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *,
 108     ndr_xa_t *);
 109 
 110 static ndr_stub_table_t samr_stub_table[];
 111 
 112 static ndr_service_t samr_service = {
 113         "SAMR",                         /* name */
 114         "Security Accounts Manager",    /* desc */
 115         "\\samr",                       /* endpoint */
 116         PIPE_LSASS,                     /* sec_addr_port */
 117         "12345778-1234-abcd-ef00-0123456789ac", 1,      /* abstract */
 118         NDR_TRANSFER_SYNTAX_UUID,               2,      /* transfer */
 119         0,                              /* no bind_instance_size */
 120         NULL,                           /* no bind_req() */
 121         NULL,                           /* no unbind_and_close() */
 122         samr_call_stub,                 /* call_stub() */
 123         &TYPEINFO(samr_interface),  /* interface ti */
 124         samr_stub_table                 /* stub_table */
 125 };


 198  */
 199 static ndr_handle_t *
 200 samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key)
 201 {
 202         ndr_handle_t *hd;
 203         samr_keydata_t *data;
 204 
 205         if ((hd = ndr_hdlookup(mxa, id)) == NULL)
 206                 return (NULL);
 207 
 208         if ((data = (samr_keydata_t *)hd->nh_data) == NULL)
 209                 return (NULL);
 210 
 211         if (data->kd_key != key)
 212                 return (NULL);
 213 
 214         return (hd);
 215 }
 216 
 217 /*
 218  * Handle lookup wrapper to validate the local context,
 219  * but don't limit to one type.
 220  */
 221 static ndr_handle_t *
 222 samr_hdlookup_any(ndr_xa_t *mxa, ndr_hdid_t *id)
 223 {
 224         ndr_handle_t *hd;
 225 
 226         if ((hd = ndr_hdlookup(mxa, id)) == NULL)
 227                 return (NULL);
 228 
 229         if (hd->nh_data == NULL)
 230                 return (NULL);
 231 
 232         return (hd);
 233 }
 234 
 235 /*
 236  * samr_s_Connect
 237  *
 238  * This is a request to connect to the local SAM database. We don't
 239  * support any form of update request and our database doesn't
 240  * contain any private information, so there is little point in
 241  * doing any access access checking here.
 242  *
 243  * Return a handle for use with subsequent SAM requests.
 244  */
 245 static int
 246 samr_s_Connect(void *arg, ndr_xa_t *mxa)
 247 {
 248         struct samr_Connect *param = arg;
 249         ndr_hdid_t *id;
 250 
 251         id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
 252         if (id) {
 253                 bcopy(id, &param->handle, sizeof (samr_handle_t));
 254                 param->status = 0;
 255         } else {


 263 /*
 264  * samr_s_CloseHandle
 265  *
 266  * Close the SAM interface specified by the handle.
 267  * Free the handle and zero out the result handle for the client.
 268  */
 269 static int
 270 samr_s_CloseHandle(void *arg, ndr_xa_t *mxa)
 271 {
 272         struct samr_CloseHandle *param = arg;
 273         ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
 274 
 275         samr_hdfree(mxa, id);
 276 
 277         bzero(&param->result_handle, sizeof (samr_handle_t));
 278         param->status = 0;
 279         return (NDR_DRC_OK);
 280 }
 281 
 282 /*
 283  * samr_s_QuerySecObject
 284  */
 285 static int
 286 samr_s_QuerySecObject(void *arg, ndr_xa_t *mxa)
 287 {
 288         struct samr_QuerySecObject      *param = arg;
 289         ndr_hdid_t                      *id;
 290         uint32_t                        status;
 291         struct samr_sec_desc            *sd;
 292 
 293         id = (ndr_hdid_t *)&param->obj_handle;
 294         if (samr_hdlookup_any(mxa, id) == NULL) {
 295                 status = NT_STATUS_INVALID_HANDLE;
 296                 goto QuerySecObjectError;
 297         }
 298 
 299         param->sd = NDR_MALLOC(mxa, sizeof (samr_sd_t));
 300         if (param->sd == NULL) {
 301                 status = NT_STATUS_NO_MEMORY;
 302                 goto QuerySecObjectError;
 303         }
 304         param->sd->length = sizeof (struct samr_sec_desc);
 305 
 306         sd = NDR_MALLOC(mxa, param->sd->length);
 307         if (sd == NULL) {
 308                 status = NT_STATUS_NO_MEMORY;
 309                 goto QuerySecObjectError;
 310         }
 311         bzero(sd, param->sd->length);
 312         sd->Revision = 1;
 313         sd->Control = SE_SELF_RELATIVE;
 314 
 315         param->sd->data = (void *)sd;
 316         param->status = NT_STATUS_SUCCESS;
 317         return (NDR_DRC_OK);
 318 
 319 QuerySecObjectError:
 320         bzero(param, sizeof (struct samr_QuerySecObject));
 321         param->status = NT_SC_ERROR(status);
 322         return (NDR_DRC_OK);
 323 }
 324 
 325 /*
 326  * samr_s_LookupDomain
 327  *
 328  * This is a request to map a domain name to a domain SID. We can map
 329  * the primary domain name, our local domain name (hostname) and the
 330  * builtin domain names to the appropriate SID. Anything else will be
 331  * rejected.
 332  */
 333 static int
 334 samr_s_LookupDomain(void *arg, ndr_xa_t *mxa)
 335 {
 336         struct samr_LookupDomain *param = arg;
 337         char *domain_name;
 338         smb_domain_t di;
 339 
 340         if ((domain_name = (char *)param->domain_name.str) == NULL) {
 341                 bzero(param, sizeof (struct samr_LookupDomain));
 342                 param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
 343                 return (NDR_DRC_OK);
 344         }
 345 


 734 {
 735         struct samr_DeleteUser *param = arg;
 736 
 737         bzero(param, sizeof (struct samr_DeleteUser));
 738         param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
 739         return (NDR_DRC_OK);
 740 }
 741 
 742 /*
 743  * samr_s_QueryUserInfo
 744  *
 745  * Returns:
 746  * NT_STATUS_SUCCESS
 747  * NT_STATUS_ACCESS_DENIED
 748  * NT_STATUS_INVALID_INFO_CLASS
 749  */
 750 /*ARGSUSED*/
 751 static int
 752 samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa)
 753 {


 754         struct samr_QueryUserInfo       *param = arg;
 755         struct samr_QueryUserInfo21     *all_info;
 756         ndr_hdid_t                      *id;
 757         ndr_handle_t                    *hd;
 758         samr_keydata_t                  *data;
 759         smb_domain_t                    di;
 760         smb_account_t                   account;
 761         smb_sid_t                       *sid;
 762         uint32_t                        status;
 763 
 764         id = (ndr_hdid_t *)&param->user_handle;
 765         if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) {
 766                 status = NT_STATUS_INVALID_HANDLE;
 767                 goto QueryUserInfoError;
 768         }
 769 
 770         data = (samr_keydata_t *)hd->nh_data;
 771 
 772         if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) {
 773                 status = NT_STATUS_ACCESS_DENIED;


 775         }
 776 
 777         if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) {
 778                 status = NT_STATUS_ACCESS_DENIED;
 779                 goto QueryUserInfoError;
 780         }
 781 
 782         if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) {
 783                 status = NT_STATUS_ACCESS_DENIED;
 784                 goto QueryUserInfoError;
 785         }
 786 
 787         if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) {
 788                 status = NT_STATUS_ACCESS_DENIED;
 789                 goto QueryUserInfoError;
 790         }
 791 
 792         all_info = &param->ru.info21;
 793         bzero(all_info, sizeof (struct samr_QueryUserInfo21));
 794 
 795         all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID |
 796             SAMR_USER_ALL_FULLNAME | SAMR_USER_ALL_USERACCOUNTCONTROL |
 797             SAMR_USER_ALL_ADMINCOMMENT;
 798 
 799         (void) NDR_MSTRING(mxa, account.a_name,
 800             (ndr_mstring_t *)&all_info->UserName);
 801         (void) NDR_MSTRING(mxa, account.a_name,
 802             (ndr_mstring_t *)&all_info->FullName);
 803         (void) NDR_MSTRING(mxa, "",
 804             (ndr_mstring_t *)&all_info->AdminComment);
 805 
 806         all_info->UserId = data->kd_rid;
 807         all_info->UserAccountControl = SAMR_AF_NORMAL_ACCOUNT |
 808             SAMR_AF_DONT_EXPIRE_PASSWD;
 809         if ((account.a_flags & SMB_PWF_DISABLE) != 0)
 810                 all_info->UserAccountControl |= SAMR_AF_ACCOUNTDISABLE;
 811 









 812         param->address = 1;
 813         param->switch_index = SAMR_QUERY_USER_ALL_INFO;
 814         param->status = NT_STATUS_SUCCESS;
 815         smb_account_free(&account);
 816         smb_sid_free(sid);
 817         return (NDR_DRC_OK);
 818 
 819 QueryUserInfoError:
 820         smb_sid_free(sid);
 821         bzero(param, sizeof (struct samr_QueryUserInfo));
 822         param->status = NT_SC_ERROR(status);
 823         return (NDR_DRC_OK);
 824 }
 825 
 826 /*
 827  * samr_s_QueryUserGroups
 828  *
 829  * Request the list of groups of which a user is a member.
 830  * The user is identified from the handle, which contains an
 831  * rid in the discriminator field. Note that this is a local user.


1896 
1897 /*
1898  * samr_s_Connect5
1899  *
1900  * This is the connect5 form of the connect request used by Windows XP.
1901  * Returns an RPC fault for now.
1902  */
1903 /*ARGSUSED*/
1904 static int
1905 samr_s_Connect5(void *arg, ndr_xa_t *mxa)
1906 {
1907         struct samr_Connect5 *param = arg;
1908 
1909         bzero(param, sizeof (struct samr_Connect5));
1910         return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
1911 }
1912 
1913 static ndr_stub_table_t samr_stub_table[] = {
1914         { samr_s_Connect,               SAMR_OPNUM_Connect },
1915         { samr_s_CloseHandle,           SAMR_OPNUM_CloseHandle },
1916         { samr_s_QuerySecObject,        SAMR_OPNUM_QuerySecObject },
1917         { samr_s_LookupDomain,          SAMR_OPNUM_LookupDomain },
1918         { samr_s_EnumLocalDomains,      SAMR_OPNUM_EnumLocalDomains },
1919         { samr_s_OpenDomain,            SAMR_OPNUM_OpenDomain },
1920         { samr_s_QueryDomainInfo,       SAMR_OPNUM_QueryDomainInfo },
1921         { samr_s_QueryInfoDomain2,      SAMR_OPNUM_QueryInfoDomain2 },
1922         { samr_s_LookupNames,           SAMR_OPNUM_LookupNames },
1923         { samr_s_OpenUser,              SAMR_OPNUM_OpenUser },
1924         { samr_s_DeleteUser,            SAMR_OPNUM_DeleteUser },
1925         { samr_s_QueryUserInfo,         SAMR_OPNUM_QueryUserInfo },
1926         { samr_s_QueryUserGroups,       SAMR_OPNUM_QueryUserGroups },
1927         { samr_s_OpenGroup,             SAMR_OPNUM_OpenGroup },
1928         { samr_s_Connect2,              SAMR_OPNUM_Connect2 },
1929         { samr_s_GetUserPwInfo,         SAMR_OPNUM_GetUserPwInfo },
1930         { samr_s_CreateUser,            SAMR_OPNUM_CreateUser },
1931         { samr_s_ChangePasswordUser2,   SAMR_OPNUM_ChangePasswordUser2 },
1932         { samr_s_GetDomainPwInfo,       SAMR_OPNUM_GetDomainPwInfo },
1933         { samr_s_SetUserInfo,           SAMR_OPNUM_SetUserInfo },
1934         { samr_s_Connect4,              SAMR_OPNUM_Connect4 },
1935         { samr_s_Connect5,              SAMR_OPNUM_Connect5 },
1936         { samr_s_QueryDispInfo,         SAMR_OPNUM_QueryDispInfo },