111337SWilliam.Krier@Sun.COM /* 211337SWilliam.Krier@Sun.COM * CDDL HEADER START 311337SWilliam.Krier@Sun.COM * 411337SWilliam.Krier@Sun.COM * The contents of this file are subject to the terms of the 511337SWilliam.Krier@Sun.COM * Common Development and Distribution License (the "License"). 611337SWilliam.Krier@Sun.COM * You may not use this file except in compliance with the License. 711337SWilliam.Krier@Sun.COM * 811337SWilliam.Krier@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 911337SWilliam.Krier@Sun.COM * or http://www.opensolaris.org/os/licensing. 1011337SWilliam.Krier@Sun.COM * See the License for the specific language governing permissions 1111337SWilliam.Krier@Sun.COM * and limitations under the License. 1211337SWilliam.Krier@Sun.COM * 1311337SWilliam.Krier@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 1411337SWilliam.Krier@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1511337SWilliam.Krier@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 1611337SWilliam.Krier@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 1711337SWilliam.Krier@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 1811337SWilliam.Krier@Sun.COM * 1911337SWilliam.Krier@Sun.COM * CDDL HEADER END 2011337SWilliam.Krier@Sun.COM */ 2111337SWilliam.Krier@Sun.COM /* 2211447Samw@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 2311337SWilliam.Krier@Sun.COM * Use is subject to license terms. 2411337SWilliam.Krier@Sun.COM */ 2511337SWilliam.Krier@Sun.COM 2611337SWilliam.Krier@Sun.COM /* 2711337SWilliam.Krier@Sun.COM * Security Accounts Manager RPC (SAMR) server-side interface. 2811337SWilliam.Krier@Sun.COM * 2911337SWilliam.Krier@Sun.COM * The SAM is a hierarchical database: 3011337SWilliam.Krier@Sun.COM * - If you want to talk to the SAM you need a SAM handle. 3111337SWilliam.Krier@Sun.COM * - If you want to work with a domain, use the SAM handle. 3211337SWilliam.Krier@Sun.COM * to obtain a domain handle. 3311337SWilliam.Krier@Sun.COM * - Use domain handles to obtain user handles etc. 3411337SWilliam.Krier@Sun.COM */ 3511337SWilliam.Krier@Sun.COM 3611337SWilliam.Krier@Sun.COM #include <strings.h> 3711337SWilliam.Krier@Sun.COM #include <unistd.h> 3811337SWilliam.Krier@Sun.COM #include <netdb.h> 3911337SWilliam.Krier@Sun.COM #include <assert.h> 4011337SWilliam.Krier@Sun.COM 4111337SWilliam.Krier@Sun.COM #include <smbsrv/libsmb.h> 4211337SWilliam.Krier@Sun.COM #include <smbsrv/libmlrpc.h> 4311337SWilliam.Krier@Sun.COM #include <smbsrv/libmlsvc.h> 4411337SWilliam.Krier@Sun.COM #include <smbsrv/ntstatus.h> 4511337SWilliam.Krier@Sun.COM #include <smbsrv/nterror.h> 4611337SWilliam.Krier@Sun.COM #include <smbsrv/smbinfo.h> 4711337SWilliam.Krier@Sun.COM #include <smbsrv/nmpipes.h> 4811337SWilliam.Krier@Sun.COM #include <smbsrv/ndl/samrpc.ndl> 4911337SWilliam.Krier@Sun.COM #include <samlib.h> 5011337SWilliam.Krier@Sun.COM 5111337SWilliam.Krier@Sun.COM /* 5211337SWilliam.Krier@Sun.COM * The keys associated with the various handles dispensed by the SAMR 5311337SWilliam.Krier@Sun.COM * server. These keys can be used to validate client activity. 5411337SWilliam.Krier@Sun.COM * These values are never passed over the wire so security shouldn't 5511337SWilliam.Krier@Sun.COM * be an issue. 5611337SWilliam.Krier@Sun.COM */ 5711337SWilliam.Krier@Sun.COM typedef enum { 5811337SWilliam.Krier@Sun.COM SAMR_KEY_NULL = 0, 5911337SWilliam.Krier@Sun.COM SAMR_KEY_CONNECT, 6011337SWilliam.Krier@Sun.COM SAMR_KEY_DOMAIN, 6111337SWilliam.Krier@Sun.COM SAMR_KEY_USER, 6211337SWilliam.Krier@Sun.COM SAMR_KEY_GROUP, 6311337SWilliam.Krier@Sun.COM SAMR_KEY_ALIAS 6411337SWilliam.Krier@Sun.COM } samr_key_t; 6511337SWilliam.Krier@Sun.COM 6611337SWilliam.Krier@Sun.COM typedef struct samr_keydata { 6711337SWilliam.Krier@Sun.COM samr_key_t kd_key; 6811337SWilliam.Krier@Sun.COM smb_domain_type_t kd_type; 6911337SWilliam.Krier@Sun.COM DWORD kd_rid; 7011337SWilliam.Krier@Sun.COM } samr_keydata_t; 7111337SWilliam.Krier@Sun.COM 7211337SWilliam.Krier@Sun.COM /* 7311337SWilliam.Krier@Sun.COM * DomainDisplayUser All user objects (or those derived from user) with 7411337SWilliam.Krier@Sun.COM * userAccountControl containing the UF_NORMAL_ACCOUNT bit. 7511337SWilliam.Krier@Sun.COM * 7611337SWilliam.Krier@Sun.COM * DomainDisplayMachine All user objects (or those derived from user) with 7711337SWilliam.Krier@Sun.COM * userAccountControl containing the 7811337SWilliam.Krier@Sun.COM * UF_WORKSTATION_TRUST_ACCOUNT or UF_SERVER_TRUST_ACCOUNT 7911337SWilliam.Krier@Sun.COM * bit. 8011337SWilliam.Krier@Sun.COM * 8111337SWilliam.Krier@Sun.COM * DomainDisplayGroup All group objects (or those derived from group) with 8211337SWilliam.Krier@Sun.COM * groupType equal to GROUP_TYPE_SECURITY_UNIVERSAL or 8311337SWilliam.Krier@Sun.COM * GROUP_TYPE_SECURITY_ACCOUNT. 8411337SWilliam.Krier@Sun.COM * 8511337SWilliam.Krier@Sun.COM * DomainDisplayOemUser Same as DomainDisplayUser with OEM strings 8611337SWilliam.Krier@Sun.COM * 8711337SWilliam.Krier@Sun.COM * DomainDisplayOemGroup Same as DomainDisplayGroup with OEM strings 8811337SWilliam.Krier@Sun.COM */ 8911337SWilliam.Krier@Sun.COM typedef enum { 9011337SWilliam.Krier@Sun.COM DomainDisplayUser = 1, 9111337SWilliam.Krier@Sun.COM DomainDisplayMachine, 9211337SWilliam.Krier@Sun.COM DomainDispalyGroup, 9311337SWilliam.Krier@Sun.COM DomainDisplayOemUser, 9411337SWilliam.Krier@Sun.COM DomainDisplayOemGroup 9511337SWilliam.Krier@Sun.COM } samr_displvl_t; 9611337SWilliam.Krier@Sun.COM 9711337SWilliam.Krier@Sun.COM #define SAMR_VALID_DISPLEVEL(lvl) \ 9811337SWilliam.Krier@Sun.COM (((lvl) >= DomainDisplayUser) && ((lvl) <= DomainDisplayOemGroup)) 9911337SWilliam.Krier@Sun.COM 10011337SWilliam.Krier@Sun.COM #define SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser) 10111337SWilliam.Krier@Sun.COM 10211337SWilliam.Krier@Sun.COM static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t, 10311337SWilliam.Krier@Sun.COM DWORD); 10411337SWilliam.Krier@Sun.COM static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *); 10511337SWilliam.Krier@Sun.COM static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t); 10611337SWilliam.Krier@Sun.COM static int samr_call_stub(ndr_xa_t *mxa); 10711337SWilliam.Krier@Sun.COM static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *, 10811337SWilliam.Krier@Sun.COM ndr_xa_t *); 10911337SWilliam.Krier@Sun.COM 11011337SWilliam.Krier@Sun.COM static ndr_stub_table_t samr_stub_table[]; 11111337SWilliam.Krier@Sun.COM 11211337SWilliam.Krier@Sun.COM static ndr_service_t samr_service = { 11311337SWilliam.Krier@Sun.COM "SAMR", /* name */ 11411337SWilliam.Krier@Sun.COM "Security Accounts Manager", /* desc */ 11511337SWilliam.Krier@Sun.COM "\\samr", /* endpoint */ 11611337SWilliam.Krier@Sun.COM PIPE_LSASS, /* sec_addr_port */ 11711337SWilliam.Krier@Sun.COM "12345778-1234-abcd-ef00-0123456789ac", 1, /* abstract */ 11811337SWilliam.Krier@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 11911337SWilliam.Krier@Sun.COM 0, /* no bind_instance_size */ 12011337SWilliam.Krier@Sun.COM NULL, /* no bind_req() */ 12111337SWilliam.Krier@Sun.COM NULL, /* no unbind_and_close() */ 12211337SWilliam.Krier@Sun.COM samr_call_stub, /* call_stub() */ 12311337SWilliam.Krier@Sun.COM &TYPEINFO(samr_interface), /* interface ti */ 12411337SWilliam.Krier@Sun.COM samr_stub_table /* stub_table */ 12511337SWilliam.Krier@Sun.COM }; 12611337SWilliam.Krier@Sun.COM 12711337SWilliam.Krier@Sun.COM /* 12811337SWilliam.Krier@Sun.COM * samr_initialize 12911337SWilliam.Krier@Sun.COM * 13011337SWilliam.Krier@Sun.COM * This function registers the SAM RPC interface with the RPC runtime 13111337SWilliam.Krier@Sun.COM * library. It must be called in order to use either the client side 13211337SWilliam.Krier@Sun.COM * or the server side functions. 13311337SWilliam.Krier@Sun.COM */ 13411337SWilliam.Krier@Sun.COM void 13511337SWilliam.Krier@Sun.COM samr_initialize(void) 13611337SWilliam.Krier@Sun.COM { 13711337SWilliam.Krier@Sun.COM (void) ndr_svc_register(&samr_service); 13811337SWilliam.Krier@Sun.COM } 13911337SWilliam.Krier@Sun.COM 14011337SWilliam.Krier@Sun.COM /* 14111337SWilliam.Krier@Sun.COM * Custom call_stub to set the stream string policy. 14211337SWilliam.Krier@Sun.COM */ 14311337SWilliam.Krier@Sun.COM static int 14411337SWilliam.Krier@Sun.COM samr_call_stub(ndr_xa_t *mxa) 14511337SWilliam.Krier@Sun.COM { 14611337SWilliam.Krier@Sun.COM NDS_SETF(&mxa->send_nds, NDS_F_NOTERM); 14711337SWilliam.Krier@Sun.COM NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM); 14811337SWilliam.Krier@Sun.COM 14911337SWilliam.Krier@Sun.COM return (ndr_generic_call_stub(mxa)); 15011337SWilliam.Krier@Sun.COM } 15111337SWilliam.Krier@Sun.COM 15211337SWilliam.Krier@Sun.COM /* 15311337SWilliam.Krier@Sun.COM * Handle allocation wrapper to setup the local context. 15411337SWilliam.Krier@Sun.COM */ 15511337SWilliam.Krier@Sun.COM static ndr_hdid_t * 15611337SWilliam.Krier@Sun.COM samr_hdalloc(ndr_xa_t *mxa, samr_key_t key, smb_domain_type_t domain_type, 15711337SWilliam.Krier@Sun.COM DWORD rid) 15811337SWilliam.Krier@Sun.COM { 159*11963SAfshin.Ardakani@Sun.COM ndr_handle_t *hd; 160*11963SAfshin.Ardakani@Sun.COM ndr_hdid_t *id; 161*11963SAfshin.Ardakani@Sun.COM samr_keydata_t *data; 16211337SWilliam.Krier@Sun.COM 16311337SWilliam.Krier@Sun.COM if ((data = malloc(sizeof (samr_keydata_t))) == NULL) 16411337SWilliam.Krier@Sun.COM return (NULL); 16511337SWilliam.Krier@Sun.COM 16611337SWilliam.Krier@Sun.COM data->kd_key = key; 16711337SWilliam.Krier@Sun.COM data->kd_type = domain_type; 16811337SWilliam.Krier@Sun.COM data->kd_rid = rid; 16911337SWilliam.Krier@Sun.COM 170*11963SAfshin.Ardakani@Sun.COM if ((id = ndr_hdalloc(mxa, data)) == NULL) { 171*11963SAfshin.Ardakani@Sun.COM free(data); 172*11963SAfshin.Ardakani@Sun.COM return (NULL); 173*11963SAfshin.Ardakani@Sun.COM } 174*11963SAfshin.Ardakani@Sun.COM 175*11963SAfshin.Ardakani@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL) 176*11963SAfshin.Ardakani@Sun.COM hd->nh_data_free = free; 177*11963SAfshin.Ardakani@Sun.COM 178*11963SAfshin.Ardakani@Sun.COM return (id); 17911337SWilliam.Krier@Sun.COM } 18011337SWilliam.Krier@Sun.COM 18111337SWilliam.Krier@Sun.COM /* 18211337SWilliam.Krier@Sun.COM * Handle deallocation wrapper to free the local context. 18311337SWilliam.Krier@Sun.COM */ 18411337SWilliam.Krier@Sun.COM static void 18511337SWilliam.Krier@Sun.COM samr_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id) 18611337SWilliam.Krier@Sun.COM { 18711337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 18811337SWilliam.Krier@Sun.COM 18911337SWilliam.Krier@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL) { 19011337SWilliam.Krier@Sun.COM free(hd->nh_data); 191*11963SAfshin.Ardakani@Sun.COM hd->nh_data = NULL; 19211337SWilliam.Krier@Sun.COM ndr_hdfree(mxa, id); 19311337SWilliam.Krier@Sun.COM } 19411337SWilliam.Krier@Sun.COM } 19511337SWilliam.Krier@Sun.COM 19611337SWilliam.Krier@Sun.COM /* 19711337SWilliam.Krier@Sun.COM * Handle lookup wrapper to validate the local context. 19811337SWilliam.Krier@Sun.COM */ 19911337SWilliam.Krier@Sun.COM static ndr_handle_t * 20011337SWilliam.Krier@Sun.COM samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key) 20111337SWilliam.Krier@Sun.COM { 20211337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 20311337SWilliam.Krier@Sun.COM samr_keydata_t *data; 20411337SWilliam.Krier@Sun.COM 20511337SWilliam.Krier@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) == NULL) 20611337SWilliam.Krier@Sun.COM return (NULL); 20711337SWilliam.Krier@Sun.COM 20811337SWilliam.Krier@Sun.COM if ((data = (samr_keydata_t *)hd->nh_data) == NULL) 20911337SWilliam.Krier@Sun.COM return (NULL); 21011337SWilliam.Krier@Sun.COM 21111337SWilliam.Krier@Sun.COM if (data->kd_key != key) 21211337SWilliam.Krier@Sun.COM return (NULL); 21311337SWilliam.Krier@Sun.COM 21411337SWilliam.Krier@Sun.COM return (hd); 21511337SWilliam.Krier@Sun.COM } 21611337SWilliam.Krier@Sun.COM 21711337SWilliam.Krier@Sun.COM /* 21811337SWilliam.Krier@Sun.COM * samr_s_ConnectAnon 21911337SWilliam.Krier@Sun.COM * 22011337SWilliam.Krier@Sun.COM * This is a request to connect to the local SAM database. We don't 22111337SWilliam.Krier@Sun.COM * support any form of update request and our database doesn't 22211337SWilliam.Krier@Sun.COM * contain any private information, so there is little point in 22311337SWilliam.Krier@Sun.COM * doing any access access checking here. 22411337SWilliam.Krier@Sun.COM * 22511337SWilliam.Krier@Sun.COM * Return a handle for use with subsequent SAM requests. 22611337SWilliam.Krier@Sun.COM */ 22711337SWilliam.Krier@Sun.COM static int 22811337SWilliam.Krier@Sun.COM samr_s_ConnectAnon(void *arg, ndr_xa_t *mxa) 22911337SWilliam.Krier@Sun.COM { 23011337SWilliam.Krier@Sun.COM struct samr_ConnectAnon *param = arg; 23111337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 23211337SWilliam.Krier@Sun.COM 23311337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 23411337SWilliam.Krier@Sun.COM if (id) { 23511337SWilliam.Krier@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 23611337SWilliam.Krier@Sun.COM param->status = 0; 23711337SWilliam.Krier@Sun.COM } else { 23811337SWilliam.Krier@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 23911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 24011337SWilliam.Krier@Sun.COM } 24111337SWilliam.Krier@Sun.COM 24211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 24311337SWilliam.Krier@Sun.COM } 24411337SWilliam.Krier@Sun.COM 24511337SWilliam.Krier@Sun.COM /* 24611337SWilliam.Krier@Sun.COM * samr_s_CloseHandle 24711337SWilliam.Krier@Sun.COM * 24811337SWilliam.Krier@Sun.COM * Close the SAM interface specified by the handle. 24911337SWilliam.Krier@Sun.COM * Free the handle and zero out the result handle for the client. 25011337SWilliam.Krier@Sun.COM */ 25111337SWilliam.Krier@Sun.COM static int 25211337SWilliam.Krier@Sun.COM samr_s_CloseHandle(void *arg, ndr_xa_t *mxa) 25311337SWilliam.Krier@Sun.COM { 25411337SWilliam.Krier@Sun.COM struct samr_CloseHandle *param = arg; 25511337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 25611337SWilliam.Krier@Sun.COM 25711337SWilliam.Krier@Sun.COM samr_hdfree(mxa, id); 25811337SWilliam.Krier@Sun.COM 25911337SWilliam.Krier@Sun.COM bzero(¶m->result_handle, sizeof (samr_handle_t)); 26011337SWilliam.Krier@Sun.COM param->status = 0; 26111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 26211337SWilliam.Krier@Sun.COM } 26311337SWilliam.Krier@Sun.COM 26411337SWilliam.Krier@Sun.COM /* 26511337SWilliam.Krier@Sun.COM * samr_s_LookupDomain 26611337SWilliam.Krier@Sun.COM * 26711337SWilliam.Krier@Sun.COM * This is a request to map a domain name to a domain SID. We can map 26811337SWilliam.Krier@Sun.COM * the primary domain name, our local domain name (hostname) and the 26911337SWilliam.Krier@Sun.COM * builtin domain names to the appropriate SID. Anything else will be 27011337SWilliam.Krier@Sun.COM * rejected. 27111337SWilliam.Krier@Sun.COM */ 27211337SWilliam.Krier@Sun.COM static int 27311337SWilliam.Krier@Sun.COM samr_s_LookupDomain(void *arg, ndr_xa_t *mxa) 27411337SWilliam.Krier@Sun.COM { 27511337SWilliam.Krier@Sun.COM struct samr_LookupDomain *param = arg; 27611337SWilliam.Krier@Sun.COM char *domain_name; 27711337SWilliam.Krier@Sun.COM smb_domain_t di; 27811337SWilliam.Krier@Sun.COM 27911337SWilliam.Krier@Sun.COM if ((domain_name = (char *)param->domain_name.str) == NULL) { 28011337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 28111337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 28211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 28311337SWilliam.Krier@Sun.COM } 28411337SWilliam.Krier@Sun.COM 28511337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_name(domain_name, &di)) { 28611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 28711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_DOMAIN); 28811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 28911337SWilliam.Krier@Sun.COM } 29011337SWilliam.Krier@Sun.COM 29111337SWilliam.Krier@Sun.COM param->sid = (struct samr_sid *)NDR_SIDDUP(mxa, di.di_binsid); 29211337SWilliam.Krier@Sun.COM if (param->sid == NULL) { 29311337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 29411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 29511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 29611337SWilliam.Krier@Sun.COM } 29711337SWilliam.Krier@Sun.COM 29811337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 29911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 30011337SWilliam.Krier@Sun.COM } 30111337SWilliam.Krier@Sun.COM 30211337SWilliam.Krier@Sun.COM /* 30311337SWilliam.Krier@Sun.COM * samr_s_EnumLocalDomains 30411337SWilliam.Krier@Sun.COM * 30511337SWilliam.Krier@Sun.COM * This is a request for the local domains supported by this server. 30611337SWilliam.Krier@Sun.COM * All we do here is validate the handle and set the status. The real 30711337SWilliam.Krier@Sun.COM * work is done in samr_s_enum_local_domains. 30811337SWilliam.Krier@Sun.COM */ 30911337SWilliam.Krier@Sun.COM static int 31011337SWilliam.Krier@Sun.COM samr_s_EnumLocalDomains(void *arg, ndr_xa_t *mxa) 31111337SWilliam.Krier@Sun.COM { 31211337SWilliam.Krier@Sun.COM struct samr_EnumLocalDomain *param = arg; 31311337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 31411337SWilliam.Krier@Sun.COM DWORD status; 31511337SWilliam.Krier@Sun.COM 31611337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) 31711337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 31811337SWilliam.Krier@Sun.COM else 31911337SWilliam.Krier@Sun.COM status = samr_s_enum_local_domains(param, mxa); 32011337SWilliam.Krier@Sun.COM 32111337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) { 32211337SWilliam.Krier@Sun.COM param->enum_context = param->info->entries_read; 32311337SWilliam.Krier@Sun.COM param->total_entries = param->info->entries_read; 32411337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 32511337SWilliam.Krier@Sun.COM } else { 32611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumLocalDomain)); 32711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 32811337SWilliam.Krier@Sun.COM } 32911337SWilliam.Krier@Sun.COM 33011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 33111337SWilliam.Krier@Sun.COM } 33211337SWilliam.Krier@Sun.COM 33311337SWilliam.Krier@Sun.COM 33411337SWilliam.Krier@Sun.COM /* 33511337SWilliam.Krier@Sun.COM * samr_s_enum_local_domains 33611337SWilliam.Krier@Sun.COM * 33711337SWilliam.Krier@Sun.COM * This function should only be called via samr_s_EnumLocalDomains to 33811337SWilliam.Krier@Sun.COM * ensure that the appropriate validation is performed. We will answer 33911337SWilliam.Krier@Sun.COM * queries about two domains: the local domain, synonymous with the 34011337SWilliam.Krier@Sun.COM * local hostname, and the BUILTIN domain. So we return these two 34111337SWilliam.Krier@Sun.COM * strings. 34211337SWilliam.Krier@Sun.COM * 34311337SWilliam.Krier@Sun.COM * Returns NT status values. 34411337SWilliam.Krier@Sun.COM */ 34511337SWilliam.Krier@Sun.COM static DWORD 34611337SWilliam.Krier@Sun.COM samr_s_enum_local_domains(struct samr_EnumLocalDomain *param, 34711337SWilliam.Krier@Sun.COM ndr_xa_t *mxa) 34811337SWilliam.Krier@Sun.COM { 34911337SWilliam.Krier@Sun.COM struct samr_LocalDomainInfo *info; 35011337SWilliam.Krier@Sun.COM struct samr_LocalDomainEntry *entry; 35111337SWilliam.Krier@Sun.COM char *hostname; 35211337SWilliam.Krier@Sun.COM 35311337SWilliam.Krier@Sun.COM hostname = NDR_MALLOC(mxa, NETBIOS_NAME_SZ); 35411337SWilliam.Krier@Sun.COM if (hostname == NULL) 35511337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 35611337SWilliam.Krier@Sun.COM 35711337SWilliam.Krier@Sun.COM if (smb_getnetbiosname(hostname, NETBIOS_NAME_SZ) != 0) 35811337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 35911337SWilliam.Krier@Sun.COM 36011337SWilliam.Krier@Sun.COM entry = NDR_NEWN(mxa, struct samr_LocalDomainEntry, 2); 36111337SWilliam.Krier@Sun.COM if (entry == NULL) 36211337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 36311337SWilliam.Krier@Sun.COM 36411337SWilliam.Krier@Sun.COM bzero(entry, (sizeof (struct samr_LocalDomainEntry) * 2)); 36511337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, hostname, (ndr_mstring_t *)&entry[0].name); 36611337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "Builtin", (ndr_mstring_t *)&entry[1].name); 36711337SWilliam.Krier@Sun.COM 36811337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_LocalDomainInfo); 36911337SWilliam.Krier@Sun.COM if (info == NULL) 37011337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 37111337SWilliam.Krier@Sun.COM 37211337SWilliam.Krier@Sun.COM info->entries_read = 2; 37311337SWilliam.Krier@Sun.COM info->entry = entry; 37411337SWilliam.Krier@Sun.COM param->info = info; 37511337SWilliam.Krier@Sun.COM return (NT_STATUS_SUCCESS); 37611337SWilliam.Krier@Sun.COM } 37711337SWilliam.Krier@Sun.COM 37811337SWilliam.Krier@Sun.COM /* 37911337SWilliam.Krier@Sun.COM * samr_s_OpenDomain 38011337SWilliam.Krier@Sun.COM * 38111337SWilliam.Krier@Sun.COM * This is a request to open a domain within the local SAM database. 38211337SWilliam.Krier@Sun.COM * The caller must supply a valid connect handle. 38311337SWilliam.Krier@Sun.COM * We return a handle to be used to access objects within this domain. 38411337SWilliam.Krier@Sun.COM */ 38511337SWilliam.Krier@Sun.COM static int 38611337SWilliam.Krier@Sun.COM samr_s_OpenDomain(void *arg, ndr_xa_t *mxa) 38711337SWilliam.Krier@Sun.COM { 38811337SWilliam.Krier@Sun.COM struct samr_OpenDomain *param = arg; 38911337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 39011337SWilliam.Krier@Sun.COM smb_domain_t domain; 39111337SWilliam.Krier@Sun.COM 39211337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) { 39311337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 39411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 39511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 39611337SWilliam.Krier@Sun.COM } 39711337SWilliam.Krier@Sun.COM 39811337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_sid((smb_sid_t *)param->sid, &domain)) { 39911337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 40011337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 40111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 40211337SWilliam.Krier@Sun.COM } 40311337SWilliam.Krier@Sun.COM 40411337SWilliam.Krier@Sun.COM if ((domain.di_type != SMB_DOMAIN_BUILTIN) && 40511337SWilliam.Krier@Sun.COM (domain.di_type != SMB_DOMAIN_LOCAL)) { 40611337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 40711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 40811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 40911337SWilliam.Krier@Sun.COM } 41011337SWilliam.Krier@Sun.COM 41111337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_DOMAIN, domain.di_type, 0); 41211337SWilliam.Krier@Sun.COM if (id) { 41311337SWilliam.Krier@Sun.COM bcopy(id, ¶m->domain_handle, sizeof (samr_handle_t)); 41411337SWilliam.Krier@Sun.COM param->status = 0; 41511337SWilliam.Krier@Sun.COM } else { 41611337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 41711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 41811337SWilliam.Krier@Sun.COM } 41911337SWilliam.Krier@Sun.COM 42011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 42111337SWilliam.Krier@Sun.COM } 42211337SWilliam.Krier@Sun.COM 42311337SWilliam.Krier@Sun.COM /* 42411337SWilliam.Krier@Sun.COM * samr_s_QueryDomainInfo 42511337SWilliam.Krier@Sun.COM * 42611337SWilliam.Krier@Sun.COM * The caller should pass a domain handle. 42711337SWilliam.Krier@Sun.COM * 42811337SWilliam.Krier@Sun.COM * Windows 95 Server Manager sends requests for levels 6 and 7 when 42911337SWilliam.Krier@Sun.COM * the services menu item is selected. Level 2 is basically for getting 43011337SWilliam.Krier@Sun.COM * number of users, groups, and aliases in a domain. 43111337SWilliam.Krier@Sun.COM * We have no information on what the various information levels mean. 43211337SWilliam.Krier@Sun.COM */ 43311337SWilliam.Krier@Sun.COM static int 43411337SWilliam.Krier@Sun.COM samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa) 43511337SWilliam.Krier@Sun.COM { 43611337SWilliam.Krier@Sun.COM struct samr_QueryDomainInfo *param = arg; 43711337SWilliam.Krier@Sun.COM struct samr_QueryDomainInfoRes *info; 43811337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 43911337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 44011337SWilliam.Krier@Sun.COM samr_keydata_t *data; 44111337SWilliam.Krier@Sun.COM char *domain; 44211337SWilliam.Krier@Sun.COM char hostname[NETBIOS_NAME_SZ]; 44311337SWilliam.Krier@Sun.COM int alias_cnt, user_cnt; 44411337SWilliam.Krier@Sun.COM int rc = 0; 44511337SWilliam.Krier@Sun.COM 44611337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 44711337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 44811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 44911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 45011337SWilliam.Krier@Sun.COM } 45111337SWilliam.Krier@Sun.COM 45211337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_QueryDomainInfoRes); 45311337SWilliam.Krier@Sun.COM if (info == NULL) { 45411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 45511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 45611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 45711337SWilliam.Krier@Sun.COM } 45811337SWilliam.Krier@Sun.COM info->switch_value = param->info_level; 45911337SWilliam.Krier@Sun.COM param->info = info; 46011337SWilliam.Krier@Sun.COM 46111337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 46211337SWilliam.Krier@Sun.COM 46311337SWilliam.Krier@Sun.COM switch (data->kd_type) { 46411337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 46511337SWilliam.Krier@Sun.COM domain = "BUILTIN"; 46611337SWilliam.Krier@Sun.COM user_cnt = 0; 46711337SWilliam.Krier@Sun.COM alias_cnt = smb_sam_grp_cnt(data->kd_type); 46811337SWilliam.Krier@Sun.COM break; 46911337SWilliam.Krier@Sun.COM 47011337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 47111337SWilliam.Krier@Sun.COM rc = smb_getnetbiosname(hostname, sizeof (hostname)); 47211337SWilliam.Krier@Sun.COM if (rc == 0) { 47311337SWilliam.Krier@Sun.COM domain = hostname; 47411337SWilliam.Krier@Sun.COM user_cnt = smb_sam_usr_cnt(); 47511337SWilliam.Krier@Sun.COM alias_cnt = smb_sam_grp_cnt(data->kd_type); 47611337SWilliam.Krier@Sun.COM } 47711337SWilliam.Krier@Sun.COM break; 47811337SWilliam.Krier@Sun.COM 47911337SWilliam.Krier@Sun.COM default: 48011337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 48111337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 48211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 48311337SWilliam.Krier@Sun.COM } 48411337SWilliam.Krier@Sun.COM 48511337SWilliam.Krier@Sun.COM if (rc != 0) { 48611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 48711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); 48811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 48911337SWilliam.Krier@Sun.COM } 49011337SWilliam.Krier@Sun.COM 49111337SWilliam.Krier@Sun.COM switch (param->info_level) { 49211337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_6: 49311337SWilliam.Krier@Sun.COM info->ru.info6.unknown1 = 0x00000000; 49411337SWilliam.Krier@Sun.COM info->ru.info6.unknown2 = 0x00147FB0; 49511337SWilliam.Krier@Sun.COM info->ru.info6.unknown3 = 0x00000000; 49611337SWilliam.Krier@Sun.COM info->ru.info6.unknown4 = 0x00000000; 49711337SWilliam.Krier@Sun.COM info->ru.info6.unknown5 = 0x00000000; 49811337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 49911337SWilliam.Krier@Sun.COM break; 50011337SWilliam.Krier@Sun.COM 50111337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_7: 50211337SWilliam.Krier@Sun.COM info->ru.info7.unknown1 = 0x00000003; 50311337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 50411337SWilliam.Krier@Sun.COM break; 50511337SWilliam.Krier@Sun.COM 50611337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_2: 50711337SWilliam.Krier@Sun.COM info->ru.info2.unknown1 = 0x00000000; 50811337SWilliam.Krier@Sun.COM info->ru.info2.unknown2 = 0x80000000; 50911337SWilliam.Krier@Sun.COM 51011337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "", 51111337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.s1)); 51211337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, domain, 51311337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.domain)); 51411337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "", 51511337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.s2)); 51611337SWilliam.Krier@Sun.COM 51711337SWilliam.Krier@Sun.COM info->ru.info2.sequence_num = 0x0000002B; 51811337SWilliam.Krier@Sun.COM info->ru.info2.unknown3 = 0x00000000; 51911337SWilliam.Krier@Sun.COM info->ru.info2.unknown4 = 0x00000001; 52011337SWilliam.Krier@Sun.COM info->ru.info2.unknown5 = 0x00000003; 52111337SWilliam.Krier@Sun.COM info->ru.info2.unknown6 = 0x00000001; 52211337SWilliam.Krier@Sun.COM info->ru.info2.num_users = user_cnt; 52311337SWilliam.Krier@Sun.COM info->ru.info2.num_groups = 0; 52411337SWilliam.Krier@Sun.COM info->ru.info2.num_aliases = alias_cnt; 52511337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 52611337SWilliam.Krier@Sun.COM break; 52711337SWilliam.Krier@Sun.COM 52811337SWilliam.Krier@Sun.COM default: 52911337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 53011337SWilliam.Krier@Sun.COM return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 53111337SWilliam.Krier@Sun.COM }; 53211337SWilliam.Krier@Sun.COM 53311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 53411337SWilliam.Krier@Sun.COM } 53511337SWilliam.Krier@Sun.COM 53611337SWilliam.Krier@Sun.COM /* 53711447Samw@Sun.COM * QueryInfoDomain2: Identical to QueryDomainInfo. 53811447Samw@Sun.COM */ 53911447Samw@Sun.COM static int 54011447Samw@Sun.COM samr_s_QueryInfoDomain2(void *arg, ndr_xa_t *mxa) 54111447Samw@Sun.COM { 54211447Samw@Sun.COM return (samr_s_QueryDomainInfo(arg, mxa)); 54311447Samw@Sun.COM } 54411447Samw@Sun.COM 54511447Samw@Sun.COM /* 54611337SWilliam.Krier@Sun.COM * Looks up the given name in the specified domain which could 54711337SWilliam.Krier@Sun.COM * be either the built-in or local domain. 54811337SWilliam.Krier@Sun.COM * 54911337SWilliam.Krier@Sun.COM * CAVEAT: this function should be able to handle a list of 55011337SWilliam.Krier@Sun.COM * names but currently it can only handle one name at a time. 55111337SWilliam.Krier@Sun.COM */ 55211337SWilliam.Krier@Sun.COM static int 55311337SWilliam.Krier@Sun.COM samr_s_LookupNames(void *arg, ndr_xa_t *mxa) 55411337SWilliam.Krier@Sun.COM { 55511337SWilliam.Krier@Sun.COM struct samr_LookupNames *param = arg; 55611337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 55711337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 55811337SWilliam.Krier@Sun.COM samr_keydata_t *data; 55911337SWilliam.Krier@Sun.COM smb_account_t account; 56011337SWilliam.Krier@Sun.COM smb_wka_t *wka; 56111337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 56211337SWilliam.Krier@Sun.COM 56311337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) 56411337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 56511337SWilliam.Krier@Sun.COM 56611337SWilliam.Krier@Sun.COM if (param->n_entry != 1) 56711337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 56811337SWilliam.Krier@Sun.COM 56911337SWilliam.Krier@Sun.COM if (param->name.str == NULL) { 57011337SWilliam.Krier@Sun.COM /* 57111337SWilliam.Krier@Sun.COM * Windows NT returns NT_STATUS_NONE_MAPPED. 57211337SWilliam.Krier@Sun.COM * Windows 2000 returns STATUS_INVALID_ACCOUNT_NAME. 57311337SWilliam.Krier@Sun.COM */ 57411337SWilliam.Krier@Sun.COM status = NT_STATUS_NONE_MAPPED; 57511337SWilliam.Krier@Sun.COM } 57611337SWilliam.Krier@Sun.COM 57711337SWilliam.Krier@Sun.COM if (status != NT_STATUS_SUCCESS) { 57811337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupNames)); 57911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 58011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 58111337SWilliam.Krier@Sun.COM } 58211337SWilliam.Krier@Sun.COM 58311337SWilliam.Krier@Sun.COM param->rids.rid = NDR_NEW(mxa, DWORD); 58411337SWilliam.Krier@Sun.COM param->rid_types.rid_type = NDR_NEW(mxa, DWORD); 58511337SWilliam.Krier@Sun.COM 58611337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 58711337SWilliam.Krier@Sun.COM 58811337SWilliam.Krier@Sun.COM switch (data->kd_type) { 58911337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 59011447Samw@Sun.COM wka = smb_wka_lookup_builtin((char *)param->name.str); 59111337SWilliam.Krier@Sun.COM if (wka != NULL) { 59211337SWilliam.Krier@Sun.COM param->rids.n_entry = 1; 59311337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(wka->wka_binsid, 59411337SWilliam.Krier@Sun.COM ¶m->rids.rid[0]); 59511337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 1; 59611337SWilliam.Krier@Sun.COM param->rid_types.rid_type[0] = wka->wka_type; 59711337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 59811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 59911337SWilliam.Krier@Sun.COM } 60011337SWilliam.Krier@Sun.COM break; 60111337SWilliam.Krier@Sun.COM 60211337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 60311337SWilliam.Krier@Sun.COM status = smb_sam_lookup_name(NULL, (char *)param->name.str, 60411337SWilliam.Krier@Sun.COM SidTypeUnknown, &account); 60511337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) { 60611337SWilliam.Krier@Sun.COM param->rids.n_entry = 1; 60711337SWilliam.Krier@Sun.COM param->rids.rid[0] = account.a_rid; 60811337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 1; 60911337SWilliam.Krier@Sun.COM param->rid_types.rid_type[0] = account.a_type; 61011337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 61111337SWilliam.Krier@Sun.COM smb_account_free(&account); 61211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 61311337SWilliam.Krier@Sun.COM } 61411337SWilliam.Krier@Sun.COM break; 61511337SWilliam.Krier@Sun.COM 61611337SWilliam.Krier@Sun.COM default: 61711337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupNames)); 61811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 61911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 62011337SWilliam.Krier@Sun.COM } 62111337SWilliam.Krier@Sun.COM 62211337SWilliam.Krier@Sun.COM param->rids.n_entry = 0; 62311337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 0; 62411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NONE_MAPPED); 62511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 62611337SWilliam.Krier@Sun.COM } 62711337SWilliam.Krier@Sun.COM 62811337SWilliam.Krier@Sun.COM /* 62911337SWilliam.Krier@Sun.COM * samr_s_OpenUser 63011337SWilliam.Krier@Sun.COM * 63111337SWilliam.Krier@Sun.COM * This is a request to open a user within a specified domain in the 63211337SWilliam.Krier@Sun.COM * local SAM database. The caller must supply a valid domain handle, 63311337SWilliam.Krier@Sun.COM * obtained via a successful domain open request. The user is 63411337SWilliam.Krier@Sun.COM * specified by the rid in the request. 63511337SWilliam.Krier@Sun.COM */ 63611337SWilliam.Krier@Sun.COM static int 63711337SWilliam.Krier@Sun.COM samr_s_OpenUser(void *arg, ndr_xa_t *mxa) 63811337SWilliam.Krier@Sun.COM { 63911337SWilliam.Krier@Sun.COM struct samr_OpenUser *param = arg; 64011337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 64111337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 64211337SWilliam.Krier@Sun.COM samr_keydata_t *data; 64311337SWilliam.Krier@Sun.COM 64411337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 64511337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 64611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 64711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 64811337SWilliam.Krier@Sun.COM } 64911337SWilliam.Krier@Sun.COM 65011337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 65111337SWilliam.Krier@Sun.COM 65211337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_USER, data->kd_type, param->rid); 65311337SWilliam.Krier@Sun.COM if (id == NULL) { 65411337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 65511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 65611337SWilliam.Krier@Sun.COM } else { 65711337SWilliam.Krier@Sun.COM bcopy(id, ¶m->user_handle, sizeof (samr_handle_t)); 65811337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 65911337SWilliam.Krier@Sun.COM } 66011337SWilliam.Krier@Sun.COM 66111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 66211337SWilliam.Krier@Sun.COM } 66311337SWilliam.Krier@Sun.COM 66411337SWilliam.Krier@Sun.COM /* 66511337SWilliam.Krier@Sun.COM * samr_s_DeleteUser 66611337SWilliam.Krier@Sun.COM * 66711337SWilliam.Krier@Sun.COM * Request to delete a user within a specified domain in the local 66811337SWilliam.Krier@Sun.COM * SAM database. The caller should supply a valid user handle. 66911337SWilliam.Krier@Sun.COM */ 67011337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 67111337SWilliam.Krier@Sun.COM static int 67211337SWilliam.Krier@Sun.COM samr_s_DeleteUser(void *arg, ndr_xa_t *mxa) 67311337SWilliam.Krier@Sun.COM { 67411337SWilliam.Krier@Sun.COM struct samr_DeleteUser *param = arg; 67511337SWilliam.Krier@Sun.COM 67611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteUser)); 67711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 67811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 67911337SWilliam.Krier@Sun.COM } 68011337SWilliam.Krier@Sun.COM 68111337SWilliam.Krier@Sun.COM /* 68211337SWilliam.Krier@Sun.COM * samr_s_QueryUserInfo 68311337SWilliam.Krier@Sun.COM * 68411337SWilliam.Krier@Sun.COM * Returns: 68511337SWilliam.Krier@Sun.COM * NT_STATUS_SUCCESS 68611337SWilliam.Krier@Sun.COM * NT_STATUS_ACCESS_DENIED 68711337SWilliam.Krier@Sun.COM * NT_STATUS_INVALID_INFO_CLASS 68811337SWilliam.Krier@Sun.COM */ 68911337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 69011337SWilliam.Krier@Sun.COM static int 69111337SWilliam.Krier@Sun.COM samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa) 69211337SWilliam.Krier@Sun.COM { 69311337SWilliam.Krier@Sun.COM static uint16_t owf_buf[8]; 69411337SWilliam.Krier@Sun.COM static uint8_t hour_buf[SAMR_SET_USER_HOURS_SZ]; 69511337SWilliam.Krier@Sun.COM struct samr_QueryUserInfo *param = arg; 69611337SWilliam.Krier@Sun.COM struct samr_QueryUserInfo21 *all_info; 69711337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 69811337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 69911337SWilliam.Krier@Sun.COM samr_keydata_t *data; 70011337SWilliam.Krier@Sun.COM smb_domain_t di; 70111337SWilliam.Krier@Sun.COM smb_account_t account; 70211337SWilliam.Krier@Sun.COM smb_sid_t *sid; 70311337SWilliam.Krier@Sun.COM uint32_t status; 70411337SWilliam.Krier@Sun.COM 70511337SWilliam.Krier@Sun.COM id = (ndr_hdid_t *)¶m->user_handle; 70611337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) { 70711337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 70811337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 70911337SWilliam.Krier@Sun.COM } 71011337SWilliam.Krier@Sun.COM 71111337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 71211337SWilliam.Krier@Sun.COM 71311337SWilliam.Krier@Sun.COM if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) { 71411337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 71511337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 71611337SWilliam.Krier@Sun.COM } 71711337SWilliam.Krier@Sun.COM 71811337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) { 71911337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 72011337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 72111337SWilliam.Krier@Sun.COM } 72211337SWilliam.Krier@Sun.COM 72311337SWilliam.Krier@Sun.COM if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) { 72411337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 72511337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 72611337SWilliam.Krier@Sun.COM } 72711337SWilliam.Krier@Sun.COM 72811337SWilliam.Krier@Sun.COM if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) { 72911337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 73011337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 73111337SWilliam.Krier@Sun.COM } 73211337SWilliam.Krier@Sun.COM 73311337SWilliam.Krier@Sun.COM all_info = ¶m->ru.info21; 73411337SWilliam.Krier@Sun.COM bzero(all_info, sizeof (struct samr_QueryUserInfo21)); 73511337SWilliam.Krier@Sun.COM 73611337SWilliam.Krier@Sun.COM all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID; 73711337SWilliam.Krier@Sun.COM 73811337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, account.a_name, 73911337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&all_info->UserName); 74011337SWilliam.Krier@Sun.COM all_info->UserId = data->kd_rid; 74111337SWilliam.Krier@Sun.COM 74211337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.length = 16; 74311337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.maxlen = 16; 74411337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.buf = owf_buf; 74511337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.length = 16; 74611337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.maxlen = 16; 74711337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.buf = owf_buf; 74811337SWilliam.Krier@Sun.COM all_info->LogonHours.units_per_week = SAMR_HOURS_PER_WEEK; 74911337SWilliam.Krier@Sun.COM all_info->LogonHours.hours = hour_buf; 75011337SWilliam.Krier@Sun.COM 75111337SWilliam.Krier@Sun.COM param->address = 1; 75211337SWilliam.Krier@Sun.COM param->switch_index = SAMR_QUERY_USER_ALL_INFO; 75311337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 754*11963SAfshin.Ardakani@Sun.COM smb_account_free(&account); 755*11963SAfshin.Ardakani@Sun.COM smb_sid_free(sid); 75611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 75711337SWilliam.Krier@Sun.COM 75811337SWilliam.Krier@Sun.COM QueryUserInfoError: 759*11963SAfshin.Ardakani@Sun.COM smb_sid_free(sid); 76011337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryUserInfo)); 76111337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 76211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 76311337SWilliam.Krier@Sun.COM } 76411337SWilliam.Krier@Sun.COM 76511337SWilliam.Krier@Sun.COM /* 76611337SWilliam.Krier@Sun.COM * samr_s_QueryUserGroups 76711337SWilliam.Krier@Sun.COM * 76811337SWilliam.Krier@Sun.COM * Request the list of groups of which a user is a member. 76911337SWilliam.Krier@Sun.COM * The user is identified from the handle, which contains an 77011337SWilliam.Krier@Sun.COM * rid in the discriminator field. Note that this is a local user. 77111337SWilliam.Krier@Sun.COM */ 77211337SWilliam.Krier@Sun.COM static int 77311337SWilliam.Krier@Sun.COM samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa) 77411337SWilliam.Krier@Sun.COM { 77511337SWilliam.Krier@Sun.COM struct samr_QueryUserGroups *param = arg; 77611337SWilliam.Krier@Sun.COM struct samr_UserGroupInfo *info; 77711337SWilliam.Krier@Sun.COM struct samr_UserGroups *group; 77811337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->user_handle; 77911337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 78011337SWilliam.Krier@Sun.COM samr_keydata_t *data; 78111337SWilliam.Krier@Sun.COM smb_sid_t *user_sid = NULL; 78211337SWilliam.Krier@Sun.COM smb_group_t grp; 78311337SWilliam.Krier@Sun.COM smb_giter_t gi; 78411337SWilliam.Krier@Sun.COM smb_domain_t di; 78511337SWilliam.Krier@Sun.COM uint32_t status; 78611337SWilliam.Krier@Sun.COM int size; 78711337SWilliam.Krier@Sun.COM int ngrp_max; 78811337SWilliam.Krier@Sun.COM 78911337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) { 79011337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 79111337SWilliam.Krier@Sun.COM goto query_error; 79211337SWilliam.Krier@Sun.COM } 79311337SWilliam.Krier@Sun.COM 79411337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 79511337SWilliam.Krier@Sun.COM switch (data->kd_type) { 79611337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 79711337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 79811337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_type(data->kd_type, &di)) { 79911337SWilliam.Krier@Sun.COM status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 80011337SWilliam.Krier@Sun.COM goto query_error; 80111337SWilliam.Krier@Sun.COM } 80211337SWilliam.Krier@Sun.COM break; 80311337SWilliam.Krier@Sun.COM default: 80411337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 80511337SWilliam.Krier@Sun.COM goto query_error; 80611337SWilliam.Krier@Sun.COM } 80711337SWilliam.Krier@Sun.COM 80811337SWilliam.Krier@Sun.COM user_sid = smb_sid_splice(di.di_binsid, data->kd_rid); 80911337SWilliam.Krier@Sun.COM if (user_sid == NULL) { 81011337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 81111337SWilliam.Krier@Sun.COM goto query_error; 81211337SWilliam.Krier@Sun.COM } 81311337SWilliam.Krier@Sun.COM 81411337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_UserGroupInfo); 81511337SWilliam.Krier@Sun.COM if (info == NULL) { 81611337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 81711337SWilliam.Krier@Sun.COM goto query_error; 81811337SWilliam.Krier@Sun.COM } 81911337SWilliam.Krier@Sun.COM bzero(info, sizeof (struct samr_UserGroupInfo)); 82011337SWilliam.Krier@Sun.COM 82111337SWilliam.Krier@Sun.COM size = 32 * 1024; 82211337SWilliam.Krier@Sun.COM info->groups = NDR_MALLOC(mxa, size); 82311337SWilliam.Krier@Sun.COM if (info->groups == NULL) { 82411337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 82511337SWilliam.Krier@Sun.COM goto query_error; 82611337SWilliam.Krier@Sun.COM } 82711337SWilliam.Krier@Sun.COM ngrp_max = size / sizeof (struct samr_UserGroups); 82811337SWilliam.Krier@Sun.COM 82911337SWilliam.Krier@Sun.COM if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 83011337SWilliam.Krier@Sun.COM status = NT_STATUS_INTERNAL_ERROR; 83111337SWilliam.Krier@Sun.COM goto query_error; 83211337SWilliam.Krier@Sun.COM } 83311337SWilliam.Krier@Sun.COM 83411337SWilliam.Krier@Sun.COM info->n_entry = 0; 83511337SWilliam.Krier@Sun.COM group = info->groups; 83611337SWilliam.Krier@Sun.COM while ((info->n_entry < ngrp_max) && 83711337SWilliam.Krier@Sun.COM (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS)) { 83811337SWilliam.Krier@Sun.COM if (smb_lgrp_is_member(&grp, user_sid)) { 83911337SWilliam.Krier@Sun.COM group->rid = grp.sg_rid; 84011337SWilliam.Krier@Sun.COM group->attr = grp.sg_attr; 84111337SWilliam.Krier@Sun.COM group++; 84211337SWilliam.Krier@Sun.COM info->n_entry++; 84311337SWilliam.Krier@Sun.COM } 84411337SWilliam.Krier@Sun.COM smb_lgrp_free(&grp); 84511337SWilliam.Krier@Sun.COM } 84611337SWilliam.Krier@Sun.COM smb_lgrp_iterclose(&gi); 84711337SWilliam.Krier@Sun.COM 84811337SWilliam.Krier@Sun.COM free(user_sid); 84911337SWilliam.Krier@Sun.COM param->info = info; 85011337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 85111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 85211337SWilliam.Krier@Sun.COM 85311337SWilliam.Krier@Sun.COM query_error: 85411337SWilliam.Krier@Sun.COM free(user_sid); 85511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryUserGroups)); 85611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 85711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 85811337SWilliam.Krier@Sun.COM } 85911337SWilliam.Krier@Sun.COM 86011337SWilliam.Krier@Sun.COM /* 86111337SWilliam.Krier@Sun.COM * samr_s_OpenGroup 86211337SWilliam.Krier@Sun.COM * 86311337SWilliam.Krier@Sun.COM * This is a request to open a group within the specified domain in the 86411337SWilliam.Krier@Sun.COM * local SAM database. The caller must supply a valid domain handle, 86511337SWilliam.Krier@Sun.COM * obtained via a successful domain open request. The group is 86611337SWilliam.Krier@Sun.COM * specified by the rid in the request. If this is a local RID it 86711337SWilliam.Krier@Sun.COM * should already be encoded with type information. 86811337SWilliam.Krier@Sun.COM * 86911337SWilliam.Krier@Sun.COM * We return a handle to be used to access information about this group. 87011337SWilliam.Krier@Sun.COM */ 87111337SWilliam.Krier@Sun.COM static int 87211337SWilliam.Krier@Sun.COM samr_s_OpenGroup(void *arg, ndr_xa_t *mxa) 87311337SWilliam.Krier@Sun.COM { 87411337SWilliam.Krier@Sun.COM struct samr_OpenGroup *param = arg; 87511337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 87611337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 87711337SWilliam.Krier@Sun.COM samr_keydata_t *data; 87811337SWilliam.Krier@Sun.COM 87911337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 88011337SWilliam.Krier@Sun.COM bzero(¶m->group_handle, sizeof (samr_handle_t)); 88111337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 88211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 88311337SWilliam.Krier@Sun.COM } 88411337SWilliam.Krier@Sun.COM 88511337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 88611337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_GROUP, data->kd_type, param->rid); 88711337SWilliam.Krier@Sun.COM 88811337SWilliam.Krier@Sun.COM if (id) { 88911337SWilliam.Krier@Sun.COM bcopy(id, ¶m->group_handle, sizeof (samr_handle_t)); 89011337SWilliam.Krier@Sun.COM param->status = 0; 89111337SWilliam.Krier@Sun.COM } else { 89211337SWilliam.Krier@Sun.COM bzero(¶m->group_handle, sizeof (samr_handle_t)); 89311337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 89411337SWilliam.Krier@Sun.COM } 89511337SWilliam.Krier@Sun.COM 89611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 89711337SWilliam.Krier@Sun.COM } 89811337SWilliam.Krier@Sun.COM 89911337SWilliam.Krier@Sun.COM /* 90011337SWilliam.Krier@Sun.COM * samr_s_Connect 90111337SWilliam.Krier@Sun.COM * 90211337SWilliam.Krier@Sun.COM * This is a request to connect to the local SAM database. 90311337SWilliam.Krier@Sun.COM * We don't support any form of update request and our database doesn't 90411337SWilliam.Krier@Sun.COM * contain any private information, so there is little point in doing 90511337SWilliam.Krier@Sun.COM * any access access checking here. 90611337SWilliam.Krier@Sun.COM * 90711337SWilliam.Krier@Sun.COM * Return a handle for use with subsequent SAM requests. 90811337SWilliam.Krier@Sun.COM */ 90911337SWilliam.Krier@Sun.COM static int 91011337SWilliam.Krier@Sun.COM samr_s_Connect(void *arg, ndr_xa_t *mxa) 91111337SWilliam.Krier@Sun.COM { 91211337SWilliam.Krier@Sun.COM struct samr_Connect *param = arg; 91311337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 91411337SWilliam.Krier@Sun.COM 91511337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 91611337SWilliam.Krier@Sun.COM if (id) { 91711337SWilliam.Krier@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 91811337SWilliam.Krier@Sun.COM param->status = 0; 91911337SWilliam.Krier@Sun.COM } else { 92011337SWilliam.Krier@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 92111337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 92211337SWilliam.Krier@Sun.COM } 92311337SWilliam.Krier@Sun.COM 92411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 92511337SWilliam.Krier@Sun.COM } 92611337SWilliam.Krier@Sun.COM 92711337SWilliam.Krier@Sun.COM /* 92811337SWilliam.Krier@Sun.COM * samr_s_GetUserPwInfo 92911337SWilliam.Krier@Sun.COM * 93011447Samw@Sun.COM * Request for a user's password policy information. 93111337SWilliam.Krier@Sun.COM */ 93211337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 93311337SWilliam.Krier@Sun.COM static int 93411337SWilliam.Krier@Sun.COM samr_s_GetUserPwInfo(void *arg, ndr_xa_t *mxa) 93511337SWilliam.Krier@Sun.COM { 93611447Samw@Sun.COM static samr_password_info_t pwinfo; 93711447Samw@Sun.COM struct samr_GetUserPwInfo *param = arg; 93811337SWilliam.Krier@Sun.COM 93911447Samw@Sun.COM param->pwinfo = &pwinfo; 94011447Samw@Sun.COM param->status = NT_STATUS_SUCCESS; 94111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 94211337SWilliam.Krier@Sun.COM } 94311337SWilliam.Krier@Sun.COM 94411337SWilliam.Krier@Sun.COM /* 94511337SWilliam.Krier@Sun.COM * samr_s_CreateUser 94611337SWilliam.Krier@Sun.COM */ 94711337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 94811337SWilliam.Krier@Sun.COM static int 94911337SWilliam.Krier@Sun.COM samr_s_CreateUser(void *arg, ndr_xa_t *mxa) 95011337SWilliam.Krier@Sun.COM { 95111337SWilliam.Krier@Sun.COM struct samr_CreateUser *param = arg; 95211337SWilliam.Krier@Sun.COM 95311337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 95411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 95511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 95611337SWilliam.Krier@Sun.COM } 95711337SWilliam.Krier@Sun.COM 95811337SWilliam.Krier@Sun.COM /* 95911337SWilliam.Krier@Sun.COM * samr_s_ChangeUserPasswd 96011337SWilliam.Krier@Sun.COM */ 96111337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 96211337SWilliam.Krier@Sun.COM static int 96311337SWilliam.Krier@Sun.COM samr_s_ChangeUserPasswd(void *arg, ndr_xa_t *mxa) 96411337SWilliam.Krier@Sun.COM { 96511337SWilliam.Krier@Sun.COM struct samr_ChangeUserPasswd *param = arg; 96611337SWilliam.Krier@Sun.COM 96711337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_ChangeUserPasswd)); 96811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 96911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 97011337SWilliam.Krier@Sun.COM } 97111337SWilliam.Krier@Sun.COM 97211337SWilliam.Krier@Sun.COM /* 97311337SWilliam.Krier@Sun.COM * samr_s_GetDomainPwInfo 97411447Samw@Sun.COM * 97511447Samw@Sun.COM * Request for the domain password policy information. 97611337SWilliam.Krier@Sun.COM */ 97711337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 97811337SWilliam.Krier@Sun.COM static int 97911337SWilliam.Krier@Sun.COM samr_s_GetDomainPwInfo(void *arg, ndr_xa_t *mxa) 98011337SWilliam.Krier@Sun.COM { 98111447Samw@Sun.COM static samr_password_info_t pwinfo; 98211447Samw@Sun.COM struct samr_GetDomainPwInfo *param = arg; 98311337SWilliam.Krier@Sun.COM 98411447Samw@Sun.COM param->pwinfo = &pwinfo; 98511447Samw@Sun.COM param->status = NT_STATUS_SUCCESS; 98611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 98711337SWilliam.Krier@Sun.COM } 98811337SWilliam.Krier@Sun.COM 98911337SWilliam.Krier@Sun.COM /* 99011337SWilliam.Krier@Sun.COM * samr_s_SetUserInfo 99111337SWilliam.Krier@Sun.COM */ 99211337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 99311337SWilliam.Krier@Sun.COM static int 99411337SWilliam.Krier@Sun.COM samr_s_SetUserInfo(void *arg, ndr_xa_t *mxa) 99511337SWilliam.Krier@Sun.COM { 99611337SWilliam.Krier@Sun.COM struct samr_SetUserInfo *param = arg; 99711337SWilliam.Krier@Sun.COM 99811337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_SetUserInfo)); 99911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 100011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 100111337SWilliam.Krier@Sun.COM } 100211337SWilliam.Krier@Sun.COM 100311337SWilliam.Krier@Sun.COM /* 100411337SWilliam.Krier@Sun.COM * samr_s_QueryDispInfo 100511337SWilliam.Krier@Sun.COM * 100611337SWilliam.Krier@Sun.COM * This function currently return local users' information only. 100711337SWilliam.Krier@Sun.COM * This RPC is called repeatedly until all the users info are 100811337SWilliam.Krier@Sun.COM * retrieved. 100911337SWilliam.Krier@Sun.COM * 101011337SWilliam.Krier@Sun.COM * The total count and the returned count are returned as total size 101111337SWilliam.Krier@Sun.COM * and returned size. The client doesn't seem to care. 101211337SWilliam.Krier@Sun.COM */ 101311337SWilliam.Krier@Sun.COM static int 101411337SWilliam.Krier@Sun.COM samr_s_QueryDispInfo(void *arg, ndr_xa_t *mxa) 101511337SWilliam.Krier@Sun.COM { 101611337SWilliam.Krier@Sun.COM struct samr_QueryDispInfo *param = arg; 101711337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 101811337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 101911337SWilliam.Krier@Sun.COM samr_keydata_t *data; 102011337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 102111337SWilliam.Krier@Sun.COM struct user_acct_info *user; 102211337SWilliam.Krier@Sun.COM smb_pwditer_t pwi; 102311337SWilliam.Krier@Sun.COM smb_luser_t *uinfo; 102411337SWilliam.Krier@Sun.COM int num_users; 102511337SWilliam.Krier@Sun.COM int start_idx; 102611337SWilliam.Krier@Sun.COM int max_retcnt, retcnt; 102711337SWilliam.Krier@Sun.COM int skip; 102811337SWilliam.Krier@Sun.COM 102911337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 103011337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 103111337SWilliam.Krier@Sun.COM goto error; 103211337SWilliam.Krier@Sun.COM } 103311337SWilliam.Krier@Sun.COM 103411337SWilliam.Krier@Sun.COM if (!SAMR_VALID_DISPLEVEL(param->level)) { 103511337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_INFO_CLASS; 103611337SWilliam.Krier@Sun.COM goto error; 103711337SWilliam.Krier@Sun.COM } 103811337SWilliam.Krier@Sun.COM 103911337SWilliam.Krier@Sun.COM if (!SAMR_SUPPORTED_DISPLEVEL(param->level)) { 104011337SWilliam.Krier@Sun.COM status = NT_STATUS_NOT_IMPLEMENTED; 104111337SWilliam.Krier@Sun.COM goto error; 104211337SWilliam.Krier@Sun.COM } 104311337SWilliam.Krier@Sun.COM 104411337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 104511337SWilliam.Krier@Sun.COM 104611337SWilliam.Krier@Sun.COM switch (data->kd_type) { 104711337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 104811337SWilliam.Krier@Sun.COM goto no_info; 104911337SWilliam.Krier@Sun.COM 105011337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 105111337SWilliam.Krier@Sun.COM num_users = smb_sam_usr_cnt(); 105211337SWilliam.Krier@Sun.COM start_idx = param->start_idx; 105311337SWilliam.Krier@Sun.COM if ((num_users == 0) || (start_idx >= num_users)) 105411337SWilliam.Krier@Sun.COM goto no_info; 105511337SWilliam.Krier@Sun.COM 105611337SWilliam.Krier@Sun.COM max_retcnt = num_users - start_idx; 105711337SWilliam.Krier@Sun.COM if (max_retcnt > param->max_entries) 105811337SWilliam.Krier@Sun.COM max_retcnt = param->max_entries; 105911337SWilliam.Krier@Sun.COM param->users.acct = NDR_MALLOC(mxa, 106011337SWilliam.Krier@Sun.COM max_retcnt * sizeof (struct user_acct_info)); 106111337SWilliam.Krier@Sun.COM user = param->users.acct; 106211337SWilliam.Krier@Sun.COM if (user == NULL) { 106311337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 106411337SWilliam.Krier@Sun.COM goto error; 106511337SWilliam.Krier@Sun.COM } 106611337SWilliam.Krier@Sun.COM bzero(user, max_retcnt * sizeof (struct user_acct_info)); 106711337SWilliam.Krier@Sun.COM 106811337SWilliam.Krier@Sun.COM if (smb_pwd_iteropen(&pwi) != SMB_PWE_SUCCESS) 106911337SWilliam.Krier@Sun.COM goto no_info; 107011337SWilliam.Krier@Sun.COM 107111337SWilliam.Krier@Sun.COM skip = retcnt = 0; 107211337SWilliam.Krier@Sun.COM while ((uinfo = smb_pwd_iterate(&pwi)) != NULL) { 107311337SWilliam.Krier@Sun.COM if (skip++ < start_idx) 107411337SWilliam.Krier@Sun.COM continue; 107511337SWilliam.Krier@Sun.COM 107611337SWilliam.Krier@Sun.COM if (retcnt++ >= max_retcnt) 107711337SWilliam.Krier@Sun.COM break; 107811337SWilliam.Krier@Sun.COM 107911337SWilliam.Krier@Sun.COM assert(uinfo->su_name != NULL); 108011337SWilliam.Krier@Sun.COM 108111337SWilliam.Krier@Sun.COM user->index = start_idx + retcnt; 108211337SWilliam.Krier@Sun.COM user->rid = uinfo->su_rid; 108311337SWilliam.Krier@Sun.COM user->ctrl = ACF_NORMUSER | ACF_PWDNOEXP; 108411337SWilliam.Krier@Sun.COM if (uinfo->su_ctrl & SMB_PWF_DISABLE) 108511337SWilliam.Krier@Sun.COM user->ctrl |= ACF_DISABLED; 108611337SWilliam.Krier@Sun.COM if (NDR_MSTRING(mxa, uinfo->su_name, 108711337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->name) == -1) { 108811337SWilliam.Krier@Sun.COM smb_pwd_iterclose(&pwi); 108911337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 109011337SWilliam.Krier@Sun.COM goto error; 109111337SWilliam.Krier@Sun.COM } 109211337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, uinfo->su_fullname, 109311337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->fullname); 109411337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, uinfo->su_desc, 109511337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->desc); 109611337SWilliam.Krier@Sun.COM user++; 109711337SWilliam.Krier@Sun.COM } 109811337SWilliam.Krier@Sun.COM smb_pwd_iterclose(&pwi); 109911337SWilliam.Krier@Sun.COM 110011337SWilliam.Krier@Sun.COM if (retcnt >= max_retcnt) { 110111337SWilliam.Krier@Sun.COM retcnt = max_retcnt; 110211337SWilliam.Krier@Sun.COM param->status = status; 110311337SWilliam.Krier@Sun.COM } else { 110411337SWilliam.Krier@Sun.COM param->status = ERROR_MORE_ENTRIES; 110511337SWilliam.Krier@Sun.COM } 110611337SWilliam.Krier@Sun.COM 110711337SWilliam.Krier@Sun.COM param->users.total_size = num_users; 110811337SWilliam.Krier@Sun.COM param->users.returned_size = retcnt; 110911337SWilliam.Krier@Sun.COM param->users.switch_value = param->level; 111011337SWilliam.Krier@Sun.COM param->users.count = retcnt; 111111337SWilliam.Krier@Sun.COM 111211337SWilliam.Krier@Sun.COM break; 111311337SWilliam.Krier@Sun.COM 111411337SWilliam.Krier@Sun.COM default: 111511337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 111611337SWilliam.Krier@Sun.COM goto error; 111711337SWilliam.Krier@Sun.COM } 111811337SWilliam.Krier@Sun.COM 111911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 112011337SWilliam.Krier@Sun.COM 112111337SWilliam.Krier@Sun.COM no_info: 112211337SWilliam.Krier@Sun.COM param->users.total_size = 0; 112311337SWilliam.Krier@Sun.COM param->users.returned_size = 0; 112411337SWilliam.Krier@Sun.COM param->users.switch_value = param->level; 112511337SWilliam.Krier@Sun.COM param->users.count = 0; 112611337SWilliam.Krier@Sun.COM param->users.acct = NULL; 112711337SWilliam.Krier@Sun.COM param->status = status; 112811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 112911337SWilliam.Krier@Sun.COM 113011337SWilliam.Krier@Sun.COM error: 113111337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDispInfo)); 113211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 113311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 113411337SWilliam.Krier@Sun.COM } 113511337SWilliam.Krier@Sun.COM 113611337SWilliam.Krier@Sun.COM /* 113711337SWilliam.Krier@Sun.COM * samr_s_EnumDomainGroups 113811337SWilliam.Krier@Sun.COM * 113911337SWilliam.Krier@Sun.COM * 114011337SWilliam.Krier@Sun.COM * This function is supposed to return local group information. 114111337SWilliam.Krier@Sun.COM * As we don't support local users, this function dosen't send 114211337SWilliam.Krier@Sun.COM * back any information. 114311337SWilliam.Krier@Sun.COM * 114411337SWilliam.Krier@Sun.COM * Added template that returns information for a domain group as None. 114511337SWilliam.Krier@Sun.COM * All information is hard-coded from packet captures. 114611337SWilliam.Krier@Sun.COM */ 114711337SWilliam.Krier@Sun.COM static int 114811337SWilliam.Krier@Sun.COM samr_s_EnumDomainGroups(void *arg, ndr_xa_t *mxa) 114911337SWilliam.Krier@Sun.COM { 115011337SWilliam.Krier@Sun.COM struct samr_EnumDomainGroups *param = arg; 115111337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 115211337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 115311337SWilliam.Krier@Sun.COM 115411337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) 115511337SWilliam.Krier@Sun.COM status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 115611337SWilliam.Krier@Sun.COM 115711337SWilliam.Krier@Sun.COM param->total_size = 0; 115811337SWilliam.Krier@Sun.COM param->returned_size = 0; 115911337SWilliam.Krier@Sun.COM param->switch_value = 3; 116011337SWilliam.Krier@Sun.COM param->count = 0; 116111337SWilliam.Krier@Sun.COM param->groups = 0; 116211337SWilliam.Krier@Sun.COM param->status = status; 116311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 116411337SWilliam.Krier@Sun.COM 116511337SWilliam.Krier@Sun.COM #ifdef SAMR_SUPPORT_GROUPS 116611337SWilliam.Krier@Sun.COM if ((desc->discrim != SAMR_LOCAL_DOMAIN) || (param->start_idx != 0)) { 116711337SWilliam.Krier@Sun.COM param->total_size = 0; 116811337SWilliam.Krier@Sun.COM param->returned_size = 0; 116911337SWilliam.Krier@Sun.COM param->switch_value = 3; 117011337SWilliam.Krier@Sun.COM param->count = 0; 117111337SWilliam.Krier@Sun.COM param->groups = 0; 117211337SWilliam.Krier@Sun.COM } else { 117311337SWilliam.Krier@Sun.COM param->total_size = 64; 117411337SWilliam.Krier@Sun.COM param->returned_size = 64; 117511337SWilliam.Krier@Sun.COM param->switch_value = 3; 117611337SWilliam.Krier@Sun.COM param->count = 1; 117711337SWilliam.Krier@Sun.COM param->groups = (struct group_disp_info *)NDR_MALLOC( 117811337SWilliam.Krier@Sun.COM mxa, sizeof (struct group_disp_info)); 117911337SWilliam.Krier@Sun.COM 118011337SWilliam.Krier@Sun.COM param->groups->count = 1; 118111337SWilliam.Krier@Sun.COM param->groups->acct[0].index = 1; 118211337SWilliam.Krier@Sun.COM param->groups->acct[0].rid = 513; 118311337SWilliam.Krier@Sun.COM param->groups->acct[0].ctrl = 0x7; 118411337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "None", 118511337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->groups->acct[0].name); 118611337SWilliam.Krier@Sun.COM 118711337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "Ordinary users", 118811337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->groups->acct[0].desc); 118911337SWilliam.Krier@Sun.COM } 119011337SWilliam.Krier@Sun.COM 119111337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 119211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 119311337SWilliam.Krier@Sun.COM #endif 119411337SWilliam.Krier@Sun.COM } 119511337SWilliam.Krier@Sun.COM 119611337SWilliam.Krier@Sun.COM /* 119711337SWilliam.Krier@Sun.COM * samr_s_OpenAlias 119811337SWilliam.Krier@Sun.COM * 119911337SWilliam.Krier@Sun.COM * Lookup for requested alias, if it exists return a handle 120011337SWilliam.Krier@Sun.COM * for that alias. The alias domain sid should match with 120111337SWilliam.Krier@Sun.COM * the passed domain handle. 120211337SWilliam.Krier@Sun.COM */ 120311337SWilliam.Krier@Sun.COM static int 120411337SWilliam.Krier@Sun.COM samr_s_OpenAlias(void *arg, ndr_xa_t *mxa) 120511337SWilliam.Krier@Sun.COM { 120611337SWilliam.Krier@Sun.COM struct samr_OpenAlias *param = arg; 120711447Samw@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 120811447Samw@Sun.COM ndr_handle_t *hd; 120911447Samw@Sun.COM samr_keydata_t *data; 1210*11963SAfshin.Ardakani@Sun.COM smb_domain_type_t gd_type; 121111447Samw@Sun.COM smb_sid_t *sid; 121211447Samw@Sun.COM smb_wka_t *wka; 121311447Samw@Sun.COM char sidstr[SMB_SID_STRSZ]; 121411447Samw@Sun.COM uint32_t rid; 121511447Samw@Sun.COM uint32_t status; 121611447Samw@Sun.COM int rc; 121711337SWilliam.Krier@Sun.COM 121811337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 121911337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 122011337SWilliam.Krier@Sun.COM goto open_alias_err; 122111337SWilliam.Krier@Sun.COM } 122211337SWilliam.Krier@Sun.COM 122311337SWilliam.Krier@Sun.COM if (param->access_mask != SAMR_ALIAS_ACCESS_GET_INFO) { 122411337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 122511337SWilliam.Krier@Sun.COM goto open_alias_err; 122611337SWilliam.Krier@Sun.COM } 122711337SWilliam.Krier@Sun.COM 122811337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 1229*11963SAfshin.Ardakani@Sun.COM gd_type = (smb_domain_type_t)data->kd_type; 123011447Samw@Sun.COM rid = param->rid; 123111447Samw@Sun.COM 123211447Samw@Sun.COM switch (gd_type) { 1233*11963SAfshin.Ardakani@Sun.COM case SMB_DOMAIN_BUILTIN: 123411447Samw@Sun.COM (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d", 123511447Samw@Sun.COM NT_BUILTIN_DOMAIN_SIDSTR, rid); 123611447Samw@Sun.COM if ((sid = smb_sid_fromstr(sidstr)) == NULL) { 123711447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 123811447Samw@Sun.COM goto open_alias_err; 123911447Samw@Sun.COM } 124011447Samw@Sun.COM 124111447Samw@Sun.COM wka = smb_wka_lookup_sid(sid); 124211447Samw@Sun.COM smb_sid_free(sid); 124311447Samw@Sun.COM 124411447Samw@Sun.COM if (wka == NULL) { 124511447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 124611447Samw@Sun.COM goto open_alias_err; 124711447Samw@Sun.COM } 124811447Samw@Sun.COM break; 124911447Samw@Sun.COM 1250*11963SAfshin.Ardakani@Sun.COM case SMB_DOMAIN_LOCAL: 125111447Samw@Sun.COM rc = smb_lgrp_getbyrid(rid, gd_type, NULL); 125211447Samw@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 125311447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 125411447Samw@Sun.COM goto open_alias_err; 125511447Samw@Sun.COM } 125611447Samw@Sun.COM break; 125711447Samw@Sun.COM 125811447Samw@Sun.COM default: 125911337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 126011337SWilliam.Krier@Sun.COM goto open_alias_err; 126111337SWilliam.Krier@Sun.COM } 126211337SWilliam.Krier@Sun.COM 126311337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, data->kd_type, param->rid); 126411337SWilliam.Krier@Sun.COM if (id) { 126511337SWilliam.Krier@Sun.COM bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t)); 126611337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 126711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 126811337SWilliam.Krier@Sun.COM } 126911337SWilliam.Krier@Sun.COM 127011337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 127111337SWilliam.Krier@Sun.COM 127211337SWilliam.Krier@Sun.COM open_alias_err: 127311337SWilliam.Krier@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 127411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 127511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 127611337SWilliam.Krier@Sun.COM } 127711337SWilliam.Krier@Sun.COM 127811337SWilliam.Krier@Sun.COM /* 127911337SWilliam.Krier@Sun.COM * samr_s_CreateDomainAlias 128011337SWilliam.Krier@Sun.COM * 128111337SWilliam.Krier@Sun.COM * Creates a local group in the security database, which is the 128211337SWilliam.Krier@Sun.COM * security accounts manager (SAM) 128311337SWilliam.Krier@Sun.COM * For more information you can look at MSDN page for NetLocalGroupAdd. 128411337SWilliam.Krier@Sun.COM * This RPC is used by CMC and right now it returns access denied. 128511337SWilliam.Krier@Sun.COM * The peice of code that creates a local group doesn't get compiled. 128611337SWilliam.Krier@Sun.COM */ 128711337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 128811337SWilliam.Krier@Sun.COM static int 128911337SWilliam.Krier@Sun.COM samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa) 129011337SWilliam.Krier@Sun.COM { 129111337SWilliam.Krier@Sun.COM struct samr_CreateDomainAlias *param = arg; 129211337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 129311337SWilliam.Krier@Sun.COM 129411337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) { 129511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_CreateDomainAlias)); 129611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 129711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 129811337SWilliam.Krier@Sun.COM } 129911337SWilliam.Krier@Sun.COM 130011337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_CreateDomainAlias)); 130111337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 130211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 130311337SWilliam.Krier@Sun.COM 130411337SWilliam.Krier@Sun.COM #ifdef SAMR_SUPPORT_ADD_ALIAS 130511337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 130611337SWilliam.Krier@Sun.COM nt_group_t *grp; 130711337SWilliam.Krier@Sun.COM char *alias_name; 130811337SWilliam.Krier@Sun.COM 130911337SWilliam.Krier@Sun.COM alias_name = param->alias_name.str; 131011337SWilliam.Krier@Sun.COM if (alias_name == 0) { 131111337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_PARAMETER; 131211337SWilliam.Krier@Sun.COM goto create_alias_err; 131311337SWilliam.Krier@Sun.COM } 131411337SWilliam.Krier@Sun.COM 131511337SWilliam.Krier@Sun.COM /* 131611337SWilliam.Krier@Sun.COM * Check access mask. User should be member of 131711337SWilliam.Krier@Sun.COM * Administrators or Account Operators local group. 131811337SWilliam.Krier@Sun.COM */ 131911337SWilliam.Krier@Sun.COM status = nt_group_add(alias_name, 0, 132011337SWilliam.Krier@Sun.COM NT_GROUP_AF_ADD | NT_GROUP_AF_LOCAL); 132111337SWilliam.Krier@Sun.COM 132211337SWilliam.Krier@Sun.COM if (status != NT_STATUS_SUCCESS) 132311337SWilliam.Krier@Sun.COM goto create_alias_err; 132411337SWilliam.Krier@Sun.COM 132511337SWilliam.Krier@Sun.COM grp = nt_group_getinfo(alias_name, RWLOCK_READER); 132611337SWilliam.Krier@Sun.COM if (grp == NULL) { 132711337SWilliam.Krier@Sun.COM status = NT_STATUS_INTERNAL_ERROR; 132811337SWilliam.Krier@Sun.COM goto create_alias_err; 132911337SWilliam.Krier@Sun.COM } 133011337SWilliam.Krier@Sun.COM 133111337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(grp->sid, ¶m->rid); 133211337SWilliam.Krier@Sun.COM nt_group_putinfo(grp); 133311337SWilliam.Krier@Sun.COM handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR, SAMR_ALIAS_KEY, 133411337SWilliam.Krier@Sun.COM param->rid); 133511337SWilliam.Krier@Sun.COM bcopy(handle, ¶m->alias_handle, sizeof (samr_handle_t)); 133611337SWilliam.Krier@Sun.COM 133711337SWilliam.Krier@Sun.COM param->status = 0; 133811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 133911337SWilliam.Krier@Sun.COM 134011337SWilliam.Krier@Sun.COM create_alias_err: 134111337SWilliam.Krier@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 134211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 134311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 134411337SWilliam.Krier@Sun.COM #endif 134511337SWilliam.Krier@Sun.COM } 134611337SWilliam.Krier@Sun.COM 134711337SWilliam.Krier@Sun.COM /* 134811337SWilliam.Krier@Sun.COM * samr_s_SetAliasInfo 134911337SWilliam.Krier@Sun.COM * 135011337SWilliam.Krier@Sun.COM * Similar to NetLocalGroupSetInfo. 135111337SWilliam.Krier@Sun.COM */ 135211337SWilliam.Krier@Sun.COM static int 135311337SWilliam.Krier@Sun.COM samr_s_SetAliasInfo(void *arg, ndr_xa_t *mxa) 135411337SWilliam.Krier@Sun.COM { 135511337SWilliam.Krier@Sun.COM struct samr_SetAliasInfo *param = arg; 135611337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 135711337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 135811337SWilliam.Krier@Sun.COM 135911337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) 136011337SWilliam.Krier@Sun.COM status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 136111337SWilliam.Krier@Sun.COM 136211337SWilliam.Krier@Sun.COM param->status = status; 136311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 136411337SWilliam.Krier@Sun.COM } 136511337SWilliam.Krier@Sun.COM 136611337SWilliam.Krier@Sun.COM /* 136711337SWilliam.Krier@Sun.COM * samr_s_QueryAliasInfo 136811337SWilliam.Krier@Sun.COM * 136911337SWilliam.Krier@Sun.COM * Retrieves information about the specified local group account 137011337SWilliam.Krier@Sun.COM * by given handle. 137111337SWilliam.Krier@Sun.COM */ 137211337SWilliam.Krier@Sun.COM static int 137311337SWilliam.Krier@Sun.COM samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa) 137411337SWilliam.Krier@Sun.COM { 137511337SWilliam.Krier@Sun.COM struct samr_QueryAliasInfo *param = arg; 137611447Samw@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 137711447Samw@Sun.COM ndr_handle_t *hd; 137811447Samw@Sun.COM samr_keydata_t *data; 137911447Samw@Sun.COM smb_group_t grp; 1380*11963SAfshin.Ardakani@Sun.COM smb_domain_type_t gd_type; 138111447Samw@Sun.COM smb_sid_t *sid; 138211447Samw@Sun.COM smb_wka_t *wka; 138311447Samw@Sun.COM char sidstr[SMB_SID_STRSZ]; 138411447Samw@Sun.COM char *name; 138511447Samw@Sun.COM char *desc; 138611447Samw@Sun.COM uint32_t rid; 138711447Samw@Sun.COM uint32_t status; 138811447Samw@Sun.COM int rc; 138911337SWilliam.Krier@Sun.COM 139011337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 139111337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 139211337SWilliam.Krier@Sun.COM goto query_alias_err; 139311337SWilliam.Krier@Sun.COM } 139411337SWilliam.Krier@Sun.COM 139511337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 1396*11963SAfshin.Ardakani@Sun.COM gd_type = (smb_domain_type_t)data->kd_type; 139711447Samw@Sun.COM rid = data->kd_rid; 139811447Samw@Sun.COM 139911447Samw@Sun.COM switch (gd_type) { 1400*11963SAfshin.Ardakani@Sun.COM case SMB_DOMAIN_BUILTIN: 140111447Samw@Sun.COM (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d", 140211447Samw@Sun.COM NT_BUILTIN_DOMAIN_SIDSTR, rid); 140311447Samw@Sun.COM if ((sid = smb_sid_fromstr(sidstr)) == NULL) { 140411447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 140511447Samw@Sun.COM goto query_alias_err; 140611447Samw@Sun.COM } 140711447Samw@Sun.COM 140811447Samw@Sun.COM wka = smb_wka_lookup_sid(sid); 140911447Samw@Sun.COM smb_sid_free(sid); 141011447Samw@Sun.COM 141111447Samw@Sun.COM if (wka == NULL) { 141211447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 141311447Samw@Sun.COM goto query_alias_err; 141411447Samw@Sun.COM } 141511447Samw@Sun.COM 141611447Samw@Sun.COM name = wka->wka_name; 141711447Samw@Sun.COM desc = (wka->wka_desc != NULL) ? wka->wka_desc : ""; 141811447Samw@Sun.COM break; 141911447Samw@Sun.COM 1420*11963SAfshin.Ardakani@Sun.COM case SMB_DOMAIN_LOCAL: 142111447Samw@Sun.COM rc = smb_lgrp_getbyrid(rid, gd_type, &grp); 142211447Samw@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 142311447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 142411447Samw@Sun.COM goto query_alias_err; 142511447Samw@Sun.COM } 142611447Samw@Sun.COM name = grp.sg_name; 142711447Samw@Sun.COM desc = grp.sg_cmnt; 142811447Samw@Sun.COM break; 142911447Samw@Sun.COM 143011447Samw@Sun.COM default: 143111337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 143211337SWilliam.Krier@Sun.COM goto query_alias_err; 143311337SWilliam.Krier@Sun.COM } 143411337SWilliam.Krier@Sun.COM 143511337SWilliam.Krier@Sun.COM switch (param->level) { 143611337SWilliam.Krier@Sun.COM case SAMR_QUERY_ALIAS_INFO_1: 143711337SWilliam.Krier@Sun.COM param->ru.info1.level = param->level; 143811447Samw@Sun.COM (void) NDR_MSTRING(mxa, name, 143911337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info1.name); 144011337SWilliam.Krier@Sun.COM 144111447Samw@Sun.COM (void) NDR_MSTRING(mxa, desc, 144211337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info1.desc); 144311337SWilliam.Krier@Sun.COM 144411337SWilliam.Krier@Sun.COM param->ru.info1.unknown = 1; 144511337SWilliam.Krier@Sun.COM break; 144611337SWilliam.Krier@Sun.COM 144711337SWilliam.Krier@Sun.COM case SAMR_QUERY_ALIAS_INFO_3: 144811337SWilliam.Krier@Sun.COM param->ru.info3.level = param->level; 144911447Samw@Sun.COM (void) NDR_MSTRING(mxa, desc, 145011337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info3.desc); 145111337SWilliam.Krier@Sun.COM break; 145211337SWilliam.Krier@Sun.COM 145311337SWilliam.Krier@Sun.COM default: 1454*11963SAfshin.Ardakani@Sun.COM if (gd_type == SMB_DOMAIN_LOCAL) 145511447Samw@Sun.COM smb_lgrp_free(&grp); 145611337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_INFO_CLASS; 145711337SWilliam.Krier@Sun.COM goto query_alias_err; 145811337SWilliam.Krier@Sun.COM }; 145911337SWilliam.Krier@Sun.COM 1460*11963SAfshin.Ardakani@Sun.COM if (gd_type == SMB_DOMAIN_LOCAL) 146111447Samw@Sun.COM smb_lgrp_free(&grp); 146211337SWilliam.Krier@Sun.COM param->address = (DWORD)(uintptr_t)¶m->ru; 146311337SWilliam.Krier@Sun.COM param->status = 0; 146411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 146511337SWilliam.Krier@Sun.COM 146611337SWilliam.Krier@Sun.COM query_alias_err: 146711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 146811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 146911337SWilliam.Krier@Sun.COM } 147011337SWilliam.Krier@Sun.COM 147111337SWilliam.Krier@Sun.COM /* 147211337SWilliam.Krier@Sun.COM * samr_s_DeleteDomainAlias 147311337SWilliam.Krier@Sun.COM * 147411337SWilliam.Krier@Sun.COM * Deletes a local group account and all its members from the 147511337SWilliam.Krier@Sun.COM * security database, which is the security accounts manager (SAM) database. 147611337SWilliam.Krier@Sun.COM * Only members of the Administrators or Account Operators local group can 147711337SWilliam.Krier@Sun.COM * execute this function. 147811337SWilliam.Krier@Sun.COM * For more information you can look at MSDN page for NetLocalGroupSetInfo. 147911337SWilliam.Krier@Sun.COM * 148011337SWilliam.Krier@Sun.COM * This RPC is used by CMC and right now it returns access denied. 148111337SWilliam.Krier@Sun.COM * The peice of code that removes a local group doesn't get compiled. 148211337SWilliam.Krier@Sun.COM */ 148311337SWilliam.Krier@Sun.COM static int 148411337SWilliam.Krier@Sun.COM samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa) 148511337SWilliam.Krier@Sun.COM { 148611337SWilliam.Krier@Sun.COM struct samr_DeleteDomainAlias *param = arg; 148711337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 148811337SWilliam.Krier@Sun.COM 148911337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) { 149011337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 149111337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 149211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 149311337SWilliam.Krier@Sun.COM } 149411337SWilliam.Krier@Sun.COM 149511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 149611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 149711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 149811337SWilliam.Krier@Sun.COM 149911337SWilliam.Krier@Sun.COM #ifdef SAMR_SUPPORT_DEL_ALIAS 150011337SWilliam.Krier@Sun.COM nt_group_t *grp; 150111337SWilliam.Krier@Sun.COM char *alias_name; 150211337SWilliam.Krier@Sun.COM DWORD status; 150311337SWilliam.Krier@Sun.COM 150411337SWilliam.Krier@Sun.COM grp = nt_groups_lookup_rid(desc->discrim); 150511337SWilliam.Krier@Sun.COM if (grp == 0) { 150611337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 150711337SWilliam.Krier@Sun.COM goto delete_alias_err; 150811337SWilliam.Krier@Sun.COM } 150911337SWilliam.Krier@Sun.COM 151011337SWilliam.Krier@Sun.COM alias_name = strdup(grp->name); 151111337SWilliam.Krier@Sun.COM if (alias_name == 0) { 151211337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 151311337SWilliam.Krier@Sun.COM goto delete_alias_err; 151411337SWilliam.Krier@Sun.COM } 151511337SWilliam.Krier@Sun.COM 151611337SWilliam.Krier@Sun.COM status = nt_group_delete(alias_name); 151711337SWilliam.Krier@Sun.COM free(alias_name); 151811337SWilliam.Krier@Sun.COM if (status != NT_STATUS_SUCCESS) 151911337SWilliam.Krier@Sun.COM goto delete_alias_err; 152011337SWilliam.Krier@Sun.COM 152111337SWilliam.Krier@Sun.COM param->status = 0; 152211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 152311337SWilliam.Krier@Sun.COM 152411337SWilliam.Krier@Sun.COM delete_alias_err: 152511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 152611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 152711337SWilliam.Krier@Sun.COM #endif 152811337SWilliam.Krier@Sun.COM } 152911337SWilliam.Krier@Sun.COM 153011337SWilliam.Krier@Sun.COM /* 153111337SWilliam.Krier@Sun.COM * samr_s_EnumDomainAliases 153211337SWilliam.Krier@Sun.COM * 153311337SWilliam.Krier@Sun.COM * This function sends back a list which contains all local groups' name. 153411337SWilliam.Krier@Sun.COM */ 153511337SWilliam.Krier@Sun.COM static int 153611337SWilliam.Krier@Sun.COM samr_s_EnumDomainAliases(void *arg, ndr_xa_t *mxa) 153711337SWilliam.Krier@Sun.COM { 153811337SWilliam.Krier@Sun.COM struct samr_EnumDomainAliases *param = arg; 153911337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 154011337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 154111337SWilliam.Krier@Sun.COM samr_keydata_t *data; 154211337SWilliam.Krier@Sun.COM smb_group_t grp; 154311337SWilliam.Krier@Sun.COM smb_giter_t gi; 154411337SWilliam.Krier@Sun.COM int cnt, skip, i; 154511337SWilliam.Krier@Sun.COM struct name_rid *info; 154611337SWilliam.Krier@Sun.COM 154711337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 154811337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 154911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 155011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 155111337SWilliam.Krier@Sun.COM } 155211337SWilliam.Krier@Sun.COM 155311337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 155411337SWilliam.Krier@Sun.COM 155511337SWilliam.Krier@Sun.COM cnt = smb_sam_grp_cnt(data->kd_type); 155611337SWilliam.Krier@Sun.COM if (cnt <= param->resume_handle) { 155711337SWilliam.Krier@Sun.COM param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, 155811337SWilliam.Krier@Sun.COM sizeof (struct aliases_info)); 155911337SWilliam.Krier@Sun.COM 156011337SWilliam.Krier@Sun.COM if (param->aliases == NULL) { 156111337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 156211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 156311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 156411337SWilliam.Krier@Sun.COM } 156511337SWilliam.Krier@Sun.COM 156611337SWilliam.Krier@Sun.COM bzero(param->aliases, sizeof (struct aliases_info)); 156711337SWilliam.Krier@Sun.COM param->out_resume = 0; 156811337SWilliam.Krier@Sun.COM param->entries = 0; 156911337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 157011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 157111337SWilliam.Krier@Sun.COM } 157211337SWilliam.Krier@Sun.COM 157311337SWilliam.Krier@Sun.COM cnt -= param->resume_handle; 157411337SWilliam.Krier@Sun.COM param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, 157511337SWilliam.Krier@Sun.COM sizeof (struct aliases_info) + (cnt-1) * sizeof (struct name_rid)); 157611337SWilliam.Krier@Sun.COM 157711337SWilliam.Krier@Sun.COM if (param->aliases == NULL) { 157811337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 157911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 158011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 158111337SWilliam.Krier@Sun.COM } 158211337SWilliam.Krier@Sun.COM 158311337SWilliam.Krier@Sun.COM if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 158411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 158511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); 158611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 158711337SWilliam.Krier@Sun.COM } 158811337SWilliam.Krier@Sun.COM 158911337SWilliam.Krier@Sun.COM skip = i = 0; 159011337SWilliam.Krier@Sun.COM info = param->aliases->info; 159111337SWilliam.Krier@Sun.COM while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) { 159211337SWilliam.Krier@Sun.COM if ((skip++ >= param->resume_handle) && 159311337SWilliam.Krier@Sun.COM (grp.sg_domain == data->kd_type) && (i++ < cnt)) { 159411337SWilliam.Krier@Sun.COM info->rid = grp.sg_rid; 159511337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, grp.sg_name, 159611337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&info->name); 159711337SWilliam.Krier@Sun.COM 159811337SWilliam.Krier@Sun.COM info++; 159911337SWilliam.Krier@Sun.COM } 160011337SWilliam.Krier@Sun.COM smb_lgrp_free(&grp); 160111337SWilliam.Krier@Sun.COM } 160211337SWilliam.Krier@Sun.COM smb_lgrp_iterclose(&gi); 160311337SWilliam.Krier@Sun.COM 160411337SWilliam.Krier@Sun.COM param->aliases->count = i; 160511337SWilliam.Krier@Sun.COM param->aliases->address = i; 160611337SWilliam.Krier@Sun.COM 160711337SWilliam.Krier@Sun.COM param->out_resume = i; 160811337SWilliam.Krier@Sun.COM param->entries = i; 160911337SWilliam.Krier@Sun.COM param->status = 0; 161011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 161111337SWilliam.Krier@Sun.COM } 161211337SWilliam.Krier@Sun.COM 161311337SWilliam.Krier@Sun.COM /* 161411337SWilliam.Krier@Sun.COM * samr_s_Connect3 161511337SWilliam.Krier@Sun.COM */ 161611337SWilliam.Krier@Sun.COM static int 161711337SWilliam.Krier@Sun.COM samr_s_Connect3(void *arg, ndr_xa_t *mxa) 161811337SWilliam.Krier@Sun.COM { 161911447Samw@Sun.COM struct samr_Connect3 *param = arg; 162011447Samw@Sun.COM ndr_hdid_t *id; 162111337SWilliam.Krier@Sun.COM 162211447Samw@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 162311447Samw@Sun.COM if (id) { 162411447Samw@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 162511447Samw@Sun.COM param->status = 0; 162611447Samw@Sun.COM } else { 162711447Samw@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 162811447Samw@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 162911447Samw@Sun.COM } 163011447Samw@Sun.COM 163111447Samw@Sun.COM return (NDR_DRC_OK); 163211337SWilliam.Krier@Sun.COM } 163311337SWilliam.Krier@Sun.COM 163411337SWilliam.Krier@Sun.COM /* 163511337SWilliam.Krier@Sun.COM * samr_s_Connect4 163611337SWilliam.Krier@Sun.COM * 163711337SWilliam.Krier@Sun.COM * This is the connect4 form of the connect request used by Windows XP. 163811337SWilliam.Krier@Sun.COM * Returns an RPC fault for now. 163911337SWilliam.Krier@Sun.COM */ 164011337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 164111337SWilliam.Krier@Sun.COM static int 164211337SWilliam.Krier@Sun.COM samr_s_Connect4(void *arg, ndr_xa_t *mxa) 164311337SWilliam.Krier@Sun.COM { 164411337SWilliam.Krier@Sun.COM struct samr_Connect4 *param = arg; 164511337SWilliam.Krier@Sun.COM 164611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_Connect4)); 164711337SWilliam.Krier@Sun.COM return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 164811337SWilliam.Krier@Sun.COM } 164911337SWilliam.Krier@Sun.COM 165011337SWilliam.Krier@Sun.COM static ndr_stub_table_t samr_stub_table[] = { 165111337SWilliam.Krier@Sun.COM { samr_s_ConnectAnon, SAMR_OPNUM_ConnectAnon }, 165211337SWilliam.Krier@Sun.COM { samr_s_CloseHandle, SAMR_OPNUM_CloseHandle }, 165311337SWilliam.Krier@Sun.COM { samr_s_LookupDomain, SAMR_OPNUM_LookupDomain }, 165411337SWilliam.Krier@Sun.COM { samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains }, 165511337SWilliam.Krier@Sun.COM { samr_s_OpenDomain, SAMR_OPNUM_OpenDomain }, 165611337SWilliam.Krier@Sun.COM { samr_s_QueryDomainInfo, SAMR_OPNUM_QueryDomainInfo }, 165711447Samw@Sun.COM { samr_s_QueryInfoDomain2, SAMR_OPNUM_QueryInfoDomain2 }, 165811337SWilliam.Krier@Sun.COM { samr_s_LookupNames, SAMR_OPNUM_LookupNames }, 165911337SWilliam.Krier@Sun.COM { samr_s_OpenUser, SAMR_OPNUM_OpenUser }, 166011337SWilliam.Krier@Sun.COM { samr_s_DeleteUser, SAMR_OPNUM_DeleteUser }, 166111337SWilliam.Krier@Sun.COM { samr_s_QueryUserInfo, SAMR_OPNUM_QueryUserInfo }, 166211337SWilliam.Krier@Sun.COM { samr_s_QueryUserGroups, SAMR_OPNUM_QueryUserGroups }, 166311337SWilliam.Krier@Sun.COM { samr_s_OpenGroup, SAMR_OPNUM_OpenGroup }, 166411337SWilliam.Krier@Sun.COM { samr_s_Connect, SAMR_OPNUM_Connect }, 166511337SWilliam.Krier@Sun.COM { samr_s_GetUserPwInfo, SAMR_OPNUM_GetUserPwInfo }, 166611337SWilliam.Krier@Sun.COM { samr_s_CreateUser, SAMR_OPNUM_CreateUser }, 166711337SWilliam.Krier@Sun.COM { samr_s_ChangeUserPasswd, SAMR_OPNUM_ChangeUserPasswd }, 166811337SWilliam.Krier@Sun.COM { samr_s_GetDomainPwInfo, SAMR_OPNUM_GetDomainPwInfo }, 166911337SWilliam.Krier@Sun.COM { samr_s_SetUserInfo, SAMR_OPNUM_SetUserInfo }, 167011337SWilliam.Krier@Sun.COM { samr_s_Connect3, SAMR_OPNUM_Connect3 }, 167111337SWilliam.Krier@Sun.COM { samr_s_Connect4, SAMR_OPNUM_Connect4 }, 167211337SWilliam.Krier@Sun.COM { samr_s_QueryDispInfo, SAMR_OPNUM_QueryDispInfo }, 167311337SWilliam.Krier@Sun.COM { samr_s_OpenAlias, SAMR_OPNUM_OpenAlias }, 167411337SWilliam.Krier@Sun.COM { samr_s_CreateDomainAlias, SAMR_OPNUM_CreateDomainAlias }, 167511337SWilliam.Krier@Sun.COM { samr_s_SetAliasInfo, SAMR_OPNUM_SetAliasInfo }, 167611337SWilliam.Krier@Sun.COM { samr_s_QueryAliasInfo, SAMR_OPNUM_QueryAliasInfo }, 167711337SWilliam.Krier@Sun.COM { samr_s_DeleteDomainAlias, SAMR_OPNUM_DeleteDomainAlias }, 167811337SWilliam.Krier@Sun.COM { samr_s_EnumDomainAliases, SAMR_OPNUM_EnumDomainAliases }, 167911337SWilliam.Krier@Sun.COM { samr_s_EnumDomainGroups, SAMR_OPNUM_EnumDomainGroups }, 168011337SWilliam.Krier@Sun.COM {0} 168111337SWilliam.Krier@Sun.COM }; 168211337SWilliam.Krier@Sun.COM 168311337SWilliam.Krier@Sun.COM /* 168411337SWilliam.Krier@Sun.COM * There is a bug in the way that midl and the marshalling code handles 168511337SWilliam.Krier@Sun.COM * unions so we need to fix some of the data offsets at runtime. The 168611337SWilliam.Krier@Sun.COM * following macros and the fixup functions handle the corrections. 168711337SWilliam.Krier@Sun.COM */ 168811337SWilliam.Krier@Sun.COM 168911337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfo_ru); 169011337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfoRes); 169111337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfo); 169211337SWilliam.Krier@Sun.COM 169311337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(QueryUserInfo_result_u); 169411337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(QueryUserInfo_result); 169511337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryUserInfo); 169611337SWilliam.Krier@Sun.COM 169711337SWilliam.Krier@Sun.COM void 169811337SWilliam.Krier@Sun.COM fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo *val) 169911337SWilliam.Krier@Sun.COM { 170011337SWilliam.Krier@Sun.COM unsigned short size1 = 0; 170111337SWilliam.Krier@Sun.COM unsigned short size2 = 0; 170211337SWilliam.Krier@Sun.COM unsigned short size3 = 0; 170311337SWilliam.Krier@Sun.COM 170411337SWilliam.Krier@Sun.COM switch (val->level) { 170511337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryAliasInfo, 1); 170611337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryAliasInfo, 3); 170711337SWilliam.Krier@Sun.COM 170811337SWilliam.Krier@Sun.COM default: 170911337SWilliam.Krier@Sun.COM return; 171011337SWilliam.Krier@Sun.COM }; 171111337SWilliam.Krier@Sun.COM 171211337SWilliam.Krier@Sun.COM size2 = size1 + (2 * sizeof (DWORD)); 171311337SWilliam.Krier@Sun.COM size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 171411337SWilliam.Krier@Sun.COM 171511337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfo_ru, size1); 171611337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfoRes, size2); 171711337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfo, size3); 171811337SWilliam.Krier@Sun.COM } 171911337SWilliam.Krier@Sun.COM 172011337SWilliam.Krier@Sun.COM void 172111337SWilliam.Krier@Sun.COM fixup_samr_QueryUserInfo(struct samr_QueryUserInfo *val) 172211337SWilliam.Krier@Sun.COM { 172311337SWilliam.Krier@Sun.COM unsigned short size1 = 0; 172411337SWilliam.Krier@Sun.COM unsigned short size2 = 0; 172511337SWilliam.Krier@Sun.COM unsigned short size3 = 0; 172611337SWilliam.Krier@Sun.COM 172711337SWilliam.Krier@Sun.COM switch (val->switch_index) { 172811337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 1); 172911337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 6); 173011337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 7); 173111337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 8); 173211337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 9); 173311337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 16); 173411337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 21); 173511337SWilliam.Krier@Sun.COM 173611337SWilliam.Krier@Sun.COM default: 173711337SWilliam.Krier@Sun.COM return; 173811337SWilliam.Krier@Sun.COM }; 173911337SWilliam.Krier@Sun.COM 174011337SWilliam.Krier@Sun.COM size2 = size1 + (2 * sizeof (DWORD)); 174111337SWilliam.Krier@Sun.COM size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 174211337SWilliam.Krier@Sun.COM 174311337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(QueryUserInfo_result_u, size1); 174411337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(QueryUserInfo_result, size2); 174511337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryUserInfo, size3); 174611337SWilliam.Krier@Sun.COM } 174711337SWilliam.Krier@Sun.COM 174811337SWilliam.Krier@Sun.COM /* 174911337SWilliam.Krier@Sun.COM * As long as there is only one entry in the union, there is no need 175011337SWilliam.Krier@Sun.COM * to patch anything. 175111337SWilliam.Krier@Sun.COM */ 175211337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 175311337SWilliam.Krier@Sun.COM void 175411337SWilliam.Krier@Sun.COM fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo *val) 175511337SWilliam.Krier@Sun.COM { 175611337SWilliam.Krier@Sun.COM } 1757