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 /* 22*11447Samw@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 { 15911337SWilliam.Krier@Sun.COM samr_keydata_t *data; 16011337SWilliam.Krier@Sun.COM 16111337SWilliam.Krier@Sun.COM if ((data = malloc(sizeof (samr_keydata_t))) == NULL) 16211337SWilliam.Krier@Sun.COM return (NULL); 16311337SWilliam.Krier@Sun.COM 16411337SWilliam.Krier@Sun.COM data->kd_key = key; 16511337SWilliam.Krier@Sun.COM data->kd_type = domain_type; 16611337SWilliam.Krier@Sun.COM data->kd_rid = rid; 16711337SWilliam.Krier@Sun.COM 16811337SWilliam.Krier@Sun.COM return (ndr_hdalloc(mxa, data)); 16911337SWilliam.Krier@Sun.COM } 17011337SWilliam.Krier@Sun.COM 17111337SWilliam.Krier@Sun.COM /* 17211337SWilliam.Krier@Sun.COM * Handle deallocation wrapper to free the local context. 17311337SWilliam.Krier@Sun.COM */ 17411337SWilliam.Krier@Sun.COM static void 17511337SWilliam.Krier@Sun.COM samr_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id) 17611337SWilliam.Krier@Sun.COM { 17711337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 17811337SWilliam.Krier@Sun.COM 17911337SWilliam.Krier@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL) { 18011337SWilliam.Krier@Sun.COM free(hd->nh_data); 18111337SWilliam.Krier@Sun.COM ndr_hdfree(mxa, id); 18211337SWilliam.Krier@Sun.COM } 18311337SWilliam.Krier@Sun.COM } 18411337SWilliam.Krier@Sun.COM 18511337SWilliam.Krier@Sun.COM /* 18611337SWilliam.Krier@Sun.COM * Handle lookup wrapper to validate the local context. 18711337SWilliam.Krier@Sun.COM */ 18811337SWilliam.Krier@Sun.COM static ndr_handle_t * 18911337SWilliam.Krier@Sun.COM samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key) 19011337SWilliam.Krier@Sun.COM { 19111337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 19211337SWilliam.Krier@Sun.COM samr_keydata_t *data; 19311337SWilliam.Krier@Sun.COM 19411337SWilliam.Krier@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) == NULL) 19511337SWilliam.Krier@Sun.COM return (NULL); 19611337SWilliam.Krier@Sun.COM 19711337SWilliam.Krier@Sun.COM if ((data = (samr_keydata_t *)hd->nh_data) == NULL) 19811337SWilliam.Krier@Sun.COM return (NULL); 19911337SWilliam.Krier@Sun.COM 20011337SWilliam.Krier@Sun.COM if (data->kd_key != key) 20111337SWilliam.Krier@Sun.COM return (NULL); 20211337SWilliam.Krier@Sun.COM 20311337SWilliam.Krier@Sun.COM return (hd); 20411337SWilliam.Krier@Sun.COM } 20511337SWilliam.Krier@Sun.COM 20611337SWilliam.Krier@Sun.COM /* 20711337SWilliam.Krier@Sun.COM * samr_s_ConnectAnon 20811337SWilliam.Krier@Sun.COM * 20911337SWilliam.Krier@Sun.COM * This is a request to connect to the local SAM database. We don't 21011337SWilliam.Krier@Sun.COM * support any form of update request and our database doesn't 21111337SWilliam.Krier@Sun.COM * contain any private information, so there is little point in 21211337SWilliam.Krier@Sun.COM * doing any access access checking here. 21311337SWilliam.Krier@Sun.COM * 21411337SWilliam.Krier@Sun.COM * Return a handle for use with subsequent SAM requests. 21511337SWilliam.Krier@Sun.COM */ 21611337SWilliam.Krier@Sun.COM static int 21711337SWilliam.Krier@Sun.COM samr_s_ConnectAnon(void *arg, ndr_xa_t *mxa) 21811337SWilliam.Krier@Sun.COM { 21911337SWilliam.Krier@Sun.COM struct samr_ConnectAnon *param = arg; 22011337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 22111337SWilliam.Krier@Sun.COM 22211337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 22311337SWilliam.Krier@Sun.COM if (id) { 22411337SWilliam.Krier@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 22511337SWilliam.Krier@Sun.COM param->status = 0; 22611337SWilliam.Krier@Sun.COM } else { 22711337SWilliam.Krier@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 22811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 22911337SWilliam.Krier@Sun.COM } 23011337SWilliam.Krier@Sun.COM 23111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 23211337SWilliam.Krier@Sun.COM } 23311337SWilliam.Krier@Sun.COM 23411337SWilliam.Krier@Sun.COM /* 23511337SWilliam.Krier@Sun.COM * samr_s_CloseHandle 23611337SWilliam.Krier@Sun.COM * 23711337SWilliam.Krier@Sun.COM * Close the SAM interface specified by the handle. 23811337SWilliam.Krier@Sun.COM * Free the handle and zero out the result handle for the client. 23911337SWilliam.Krier@Sun.COM */ 24011337SWilliam.Krier@Sun.COM static int 24111337SWilliam.Krier@Sun.COM samr_s_CloseHandle(void *arg, ndr_xa_t *mxa) 24211337SWilliam.Krier@Sun.COM { 24311337SWilliam.Krier@Sun.COM struct samr_CloseHandle *param = arg; 24411337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 24511337SWilliam.Krier@Sun.COM 24611337SWilliam.Krier@Sun.COM samr_hdfree(mxa, id); 24711337SWilliam.Krier@Sun.COM 24811337SWilliam.Krier@Sun.COM bzero(¶m->result_handle, sizeof (samr_handle_t)); 24911337SWilliam.Krier@Sun.COM param->status = 0; 25011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 25111337SWilliam.Krier@Sun.COM } 25211337SWilliam.Krier@Sun.COM 25311337SWilliam.Krier@Sun.COM /* 25411337SWilliam.Krier@Sun.COM * samr_s_LookupDomain 25511337SWilliam.Krier@Sun.COM * 25611337SWilliam.Krier@Sun.COM * This is a request to map a domain name to a domain SID. We can map 25711337SWilliam.Krier@Sun.COM * the primary domain name, our local domain name (hostname) and the 25811337SWilliam.Krier@Sun.COM * builtin domain names to the appropriate SID. Anything else will be 25911337SWilliam.Krier@Sun.COM * rejected. 26011337SWilliam.Krier@Sun.COM */ 26111337SWilliam.Krier@Sun.COM static int 26211337SWilliam.Krier@Sun.COM samr_s_LookupDomain(void *arg, ndr_xa_t *mxa) 26311337SWilliam.Krier@Sun.COM { 26411337SWilliam.Krier@Sun.COM struct samr_LookupDomain *param = arg; 26511337SWilliam.Krier@Sun.COM char *domain_name; 26611337SWilliam.Krier@Sun.COM smb_domain_t di; 26711337SWilliam.Krier@Sun.COM 26811337SWilliam.Krier@Sun.COM if ((domain_name = (char *)param->domain_name.str) == NULL) { 26911337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 27011337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 27111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 27211337SWilliam.Krier@Sun.COM } 27311337SWilliam.Krier@Sun.COM 27411337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_name(domain_name, &di)) { 27511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 27611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_DOMAIN); 27711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 27811337SWilliam.Krier@Sun.COM } 27911337SWilliam.Krier@Sun.COM 28011337SWilliam.Krier@Sun.COM param->sid = (struct samr_sid *)NDR_SIDDUP(mxa, di.di_binsid); 28111337SWilliam.Krier@Sun.COM if (param->sid == NULL) { 28211337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 28311337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 28411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 28511337SWilliam.Krier@Sun.COM } 28611337SWilliam.Krier@Sun.COM 28711337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 28811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 28911337SWilliam.Krier@Sun.COM } 29011337SWilliam.Krier@Sun.COM 29111337SWilliam.Krier@Sun.COM /* 29211337SWilliam.Krier@Sun.COM * samr_s_EnumLocalDomains 29311337SWilliam.Krier@Sun.COM * 29411337SWilliam.Krier@Sun.COM * This is a request for the local domains supported by this server. 29511337SWilliam.Krier@Sun.COM * All we do here is validate the handle and set the status. The real 29611337SWilliam.Krier@Sun.COM * work is done in samr_s_enum_local_domains. 29711337SWilliam.Krier@Sun.COM */ 29811337SWilliam.Krier@Sun.COM static int 29911337SWilliam.Krier@Sun.COM samr_s_EnumLocalDomains(void *arg, ndr_xa_t *mxa) 30011337SWilliam.Krier@Sun.COM { 30111337SWilliam.Krier@Sun.COM struct samr_EnumLocalDomain *param = arg; 30211337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 30311337SWilliam.Krier@Sun.COM DWORD status; 30411337SWilliam.Krier@Sun.COM 30511337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) 30611337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 30711337SWilliam.Krier@Sun.COM else 30811337SWilliam.Krier@Sun.COM status = samr_s_enum_local_domains(param, mxa); 30911337SWilliam.Krier@Sun.COM 31011337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) { 31111337SWilliam.Krier@Sun.COM param->enum_context = param->info->entries_read; 31211337SWilliam.Krier@Sun.COM param->total_entries = param->info->entries_read; 31311337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 31411337SWilliam.Krier@Sun.COM } else { 31511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumLocalDomain)); 31611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 31711337SWilliam.Krier@Sun.COM } 31811337SWilliam.Krier@Sun.COM 31911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 32011337SWilliam.Krier@Sun.COM } 32111337SWilliam.Krier@Sun.COM 32211337SWilliam.Krier@Sun.COM 32311337SWilliam.Krier@Sun.COM /* 32411337SWilliam.Krier@Sun.COM * samr_s_enum_local_domains 32511337SWilliam.Krier@Sun.COM * 32611337SWilliam.Krier@Sun.COM * This function should only be called via samr_s_EnumLocalDomains to 32711337SWilliam.Krier@Sun.COM * ensure that the appropriate validation is performed. We will answer 32811337SWilliam.Krier@Sun.COM * queries about two domains: the local domain, synonymous with the 32911337SWilliam.Krier@Sun.COM * local hostname, and the BUILTIN domain. So we return these two 33011337SWilliam.Krier@Sun.COM * strings. 33111337SWilliam.Krier@Sun.COM * 33211337SWilliam.Krier@Sun.COM * Returns NT status values. 33311337SWilliam.Krier@Sun.COM */ 33411337SWilliam.Krier@Sun.COM static DWORD 33511337SWilliam.Krier@Sun.COM samr_s_enum_local_domains(struct samr_EnumLocalDomain *param, 33611337SWilliam.Krier@Sun.COM ndr_xa_t *mxa) 33711337SWilliam.Krier@Sun.COM { 33811337SWilliam.Krier@Sun.COM struct samr_LocalDomainInfo *info; 33911337SWilliam.Krier@Sun.COM struct samr_LocalDomainEntry *entry; 34011337SWilliam.Krier@Sun.COM char *hostname; 34111337SWilliam.Krier@Sun.COM 34211337SWilliam.Krier@Sun.COM hostname = NDR_MALLOC(mxa, NETBIOS_NAME_SZ); 34311337SWilliam.Krier@Sun.COM if (hostname == NULL) 34411337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 34511337SWilliam.Krier@Sun.COM 34611337SWilliam.Krier@Sun.COM if (smb_getnetbiosname(hostname, NETBIOS_NAME_SZ) != 0) 34711337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 34811337SWilliam.Krier@Sun.COM 34911337SWilliam.Krier@Sun.COM entry = NDR_NEWN(mxa, struct samr_LocalDomainEntry, 2); 35011337SWilliam.Krier@Sun.COM if (entry == NULL) 35111337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 35211337SWilliam.Krier@Sun.COM 35311337SWilliam.Krier@Sun.COM bzero(entry, (sizeof (struct samr_LocalDomainEntry) * 2)); 35411337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, hostname, (ndr_mstring_t *)&entry[0].name); 35511337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "Builtin", (ndr_mstring_t *)&entry[1].name); 35611337SWilliam.Krier@Sun.COM 35711337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_LocalDomainInfo); 35811337SWilliam.Krier@Sun.COM if (info == NULL) 35911337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 36011337SWilliam.Krier@Sun.COM 36111337SWilliam.Krier@Sun.COM info->entries_read = 2; 36211337SWilliam.Krier@Sun.COM info->entry = entry; 36311337SWilliam.Krier@Sun.COM param->info = info; 36411337SWilliam.Krier@Sun.COM return (NT_STATUS_SUCCESS); 36511337SWilliam.Krier@Sun.COM } 36611337SWilliam.Krier@Sun.COM 36711337SWilliam.Krier@Sun.COM /* 36811337SWilliam.Krier@Sun.COM * samr_s_OpenDomain 36911337SWilliam.Krier@Sun.COM * 37011337SWilliam.Krier@Sun.COM * This is a request to open a domain within the local SAM database. 37111337SWilliam.Krier@Sun.COM * The caller must supply a valid connect handle. 37211337SWilliam.Krier@Sun.COM * We return a handle to be used to access objects within this domain. 37311337SWilliam.Krier@Sun.COM */ 37411337SWilliam.Krier@Sun.COM static int 37511337SWilliam.Krier@Sun.COM samr_s_OpenDomain(void *arg, ndr_xa_t *mxa) 37611337SWilliam.Krier@Sun.COM { 37711337SWilliam.Krier@Sun.COM struct samr_OpenDomain *param = arg; 37811337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 37911337SWilliam.Krier@Sun.COM smb_domain_t domain; 38011337SWilliam.Krier@Sun.COM 38111337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) { 38211337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 38311337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 38411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 38511337SWilliam.Krier@Sun.COM } 38611337SWilliam.Krier@Sun.COM 38711337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_sid((smb_sid_t *)param->sid, &domain)) { 38811337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 38911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 39011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 39111337SWilliam.Krier@Sun.COM } 39211337SWilliam.Krier@Sun.COM 39311337SWilliam.Krier@Sun.COM if ((domain.di_type != SMB_DOMAIN_BUILTIN) && 39411337SWilliam.Krier@Sun.COM (domain.di_type != SMB_DOMAIN_LOCAL)) { 39511337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 39611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 39711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 39811337SWilliam.Krier@Sun.COM } 39911337SWilliam.Krier@Sun.COM 40011337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_DOMAIN, domain.di_type, 0); 40111337SWilliam.Krier@Sun.COM if (id) { 40211337SWilliam.Krier@Sun.COM bcopy(id, ¶m->domain_handle, sizeof (samr_handle_t)); 40311337SWilliam.Krier@Sun.COM param->status = 0; 40411337SWilliam.Krier@Sun.COM } else { 40511337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 40611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 40711337SWilliam.Krier@Sun.COM } 40811337SWilliam.Krier@Sun.COM 40911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 41011337SWilliam.Krier@Sun.COM } 41111337SWilliam.Krier@Sun.COM 41211337SWilliam.Krier@Sun.COM /* 41311337SWilliam.Krier@Sun.COM * samr_s_QueryDomainInfo 41411337SWilliam.Krier@Sun.COM * 41511337SWilliam.Krier@Sun.COM * The caller should pass a domain handle. 41611337SWilliam.Krier@Sun.COM * 41711337SWilliam.Krier@Sun.COM * Windows 95 Server Manager sends requests for levels 6 and 7 when 41811337SWilliam.Krier@Sun.COM * the services menu item is selected. Level 2 is basically for getting 41911337SWilliam.Krier@Sun.COM * number of users, groups, and aliases in a domain. 42011337SWilliam.Krier@Sun.COM * We have no information on what the various information levels mean. 42111337SWilliam.Krier@Sun.COM */ 42211337SWilliam.Krier@Sun.COM static int 42311337SWilliam.Krier@Sun.COM samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa) 42411337SWilliam.Krier@Sun.COM { 42511337SWilliam.Krier@Sun.COM struct samr_QueryDomainInfo *param = arg; 42611337SWilliam.Krier@Sun.COM struct samr_QueryDomainInfoRes *info; 42711337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 42811337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 42911337SWilliam.Krier@Sun.COM samr_keydata_t *data; 43011337SWilliam.Krier@Sun.COM char *domain; 43111337SWilliam.Krier@Sun.COM char hostname[NETBIOS_NAME_SZ]; 43211337SWilliam.Krier@Sun.COM int alias_cnt, user_cnt; 43311337SWilliam.Krier@Sun.COM int rc = 0; 43411337SWilliam.Krier@Sun.COM 43511337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 43611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 43711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 43811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 43911337SWilliam.Krier@Sun.COM } 44011337SWilliam.Krier@Sun.COM 44111337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_QueryDomainInfoRes); 44211337SWilliam.Krier@Sun.COM if (info == NULL) { 44311337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 44411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 44511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 44611337SWilliam.Krier@Sun.COM } 44711337SWilliam.Krier@Sun.COM info->switch_value = param->info_level; 44811337SWilliam.Krier@Sun.COM param->info = info; 44911337SWilliam.Krier@Sun.COM 45011337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 45111337SWilliam.Krier@Sun.COM 45211337SWilliam.Krier@Sun.COM switch (data->kd_type) { 45311337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 45411337SWilliam.Krier@Sun.COM domain = "BUILTIN"; 45511337SWilliam.Krier@Sun.COM user_cnt = 0; 45611337SWilliam.Krier@Sun.COM alias_cnt = smb_sam_grp_cnt(data->kd_type); 45711337SWilliam.Krier@Sun.COM break; 45811337SWilliam.Krier@Sun.COM 45911337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 46011337SWilliam.Krier@Sun.COM rc = smb_getnetbiosname(hostname, sizeof (hostname)); 46111337SWilliam.Krier@Sun.COM if (rc == 0) { 46211337SWilliam.Krier@Sun.COM domain = hostname; 46311337SWilliam.Krier@Sun.COM user_cnt = smb_sam_usr_cnt(); 46411337SWilliam.Krier@Sun.COM alias_cnt = smb_sam_grp_cnt(data->kd_type); 46511337SWilliam.Krier@Sun.COM } 46611337SWilliam.Krier@Sun.COM break; 46711337SWilliam.Krier@Sun.COM 46811337SWilliam.Krier@Sun.COM default: 46911337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 47011337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 47111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 47211337SWilliam.Krier@Sun.COM } 47311337SWilliam.Krier@Sun.COM 47411337SWilliam.Krier@Sun.COM if (rc != 0) { 47511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 47611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); 47711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 47811337SWilliam.Krier@Sun.COM } 47911337SWilliam.Krier@Sun.COM 48011337SWilliam.Krier@Sun.COM switch (param->info_level) { 48111337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_6: 48211337SWilliam.Krier@Sun.COM info->ru.info6.unknown1 = 0x00000000; 48311337SWilliam.Krier@Sun.COM info->ru.info6.unknown2 = 0x00147FB0; 48411337SWilliam.Krier@Sun.COM info->ru.info6.unknown3 = 0x00000000; 48511337SWilliam.Krier@Sun.COM info->ru.info6.unknown4 = 0x00000000; 48611337SWilliam.Krier@Sun.COM info->ru.info6.unknown5 = 0x00000000; 48711337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 48811337SWilliam.Krier@Sun.COM break; 48911337SWilliam.Krier@Sun.COM 49011337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_7: 49111337SWilliam.Krier@Sun.COM info->ru.info7.unknown1 = 0x00000003; 49211337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 49311337SWilliam.Krier@Sun.COM break; 49411337SWilliam.Krier@Sun.COM 49511337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_2: 49611337SWilliam.Krier@Sun.COM info->ru.info2.unknown1 = 0x00000000; 49711337SWilliam.Krier@Sun.COM info->ru.info2.unknown2 = 0x80000000; 49811337SWilliam.Krier@Sun.COM 49911337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "", 50011337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.s1)); 50111337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, domain, 50211337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.domain)); 50311337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "", 50411337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.s2)); 50511337SWilliam.Krier@Sun.COM 50611337SWilliam.Krier@Sun.COM info->ru.info2.sequence_num = 0x0000002B; 50711337SWilliam.Krier@Sun.COM info->ru.info2.unknown3 = 0x00000000; 50811337SWilliam.Krier@Sun.COM info->ru.info2.unknown4 = 0x00000001; 50911337SWilliam.Krier@Sun.COM info->ru.info2.unknown5 = 0x00000003; 51011337SWilliam.Krier@Sun.COM info->ru.info2.unknown6 = 0x00000001; 51111337SWilliam.Krier@Sun.COM info->ru.info2.num_users = user_cnt; 51211337SWilliam.Krier@Sun.COM info->ru.info2.num_groups = 0; 51311337SWilliam.Krier@Sun.COM info->ru.info2.num_aliases = alias_cnt; 51411337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 51511337SWilliam.Krier@Sun.COM break; 51611337SWilliam.Krier@Sun.COM 51711337SWilliam.Krier@Sun.COM default: 51811337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 51911337SWilliam.Krier@Sun.COM return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 52011337SWilliam.Krier@Sun.COM }; 52111337SWilliam.Krier@Sun.COM 52211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 52311337SWilliam.Krier@Sun.COM } 52411337SWilliam.Krier@Sun.COM 52511337SWilliam.Krier@Sun.COM /* 526*11447Samw@Sun.COM * QueryInfoDomain2: Identical to QueryDomainInfo. 527*11447Samw@Sun.COM */ 528*11447Samw@Sun.COM static int 529*11447Samw@Sun.COM samr_s_QueryInfoDomain2(void *arg, ndr_xa_t *mxa) 530*11447Samw@Sun.COM { 531*11447Samw@Sun.COM return (samr_s_QueryDomainInfo(arg, mxa)); 532*11447Samw@Sun.COM } 533*11447Samw@Sun.COM 534*11447Samw@Sun.COM /* 53511337SWilliam.Krier@Sun.COM * Looks up the given name in the specified domain which could 53611337SWilliam.Krier@Sun.COM * be either the built-in or local domain. 53711337SWilliam.Krier@Sun.COM * 53811337SWilliam.Krier@Sun.COM * CAVEAT: this function should be able to handle a list of 53911337SWilliam.Krier@Sun.COM * names but currently it can only handle one name at a time. 54011337SWilliam.Krier@Sun.COM */ 54111337SWilliam.Krier@Sun.COM static int 54211337SWilliam.Krier@Sun.COM samr_s_LookupNames(void *arg, ndr_xa_t *mxa) 54311337SWilliam.Krier@Sun.COM { 54411337SWilliam.Krier@Sun.COM struct samr_LookupNames *param = arg; 54511337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 54611337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 54711337SWilliam.Krier@Sun.COM samr_keydata_t *data; 54811337SWilliam.Krier@Sun.COM smb_account_t account; 54911337SWilliam.Krier@Sun.COM smb_wka_t *wka; 55011337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 55111337SWilliam.Krier@Sun.COM 55211337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) 55311337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 55411337SWilliam.Krier@Sun.COM 55511337SWilliam.Krier@Sun.COM if (param->n_entry != 1) 55611337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 55711337SWilliam.Krier@Sun.COM 55811337SWilliam.Krier@Sun.COM if (param->name.str == NULL) { 55911337SWilliam.Krier@Sun.COM /* 56011337SWilliam.Krier@Sun.COM * Windows NT returns NT_STATUS_NONE_MAPPED. 56111337SWilliam.Krier@Sun.COM * Windows 2000 returns STATUS_INVALID_ACCOUNT_NAME. 56211337SWilliam.Krier@Sun.COM */ 56311337SWilliam.Krier@Sun.COM status = NT_STATUS_NONE_MAPPED; 56411337SWilliam.Krier@Sun.COM } 56511337SWilliam.Krier@Sun.COM 56611337SWilliam.Krier@Sun.COM if (status != NT_STATUS_SUCCESS) { 56711337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupNames)); 56811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 56911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 57011337SWilliam.Krier@Sun.COM } 57111337SWilliam.Krier@Sun.COM 57211337SWilliam.Krier@Sun.COM param->rids.rid = NDR_NEW(mxa, DWORD); 57311337SWilliam.Krier@Sun.COM param->rid_types.rid_type = NDR_NEW(mxa, DWORD); 57411337SWilliam.Krier@Sun.COM 57511337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 57611337SWilliam.Krier@Sun.COM 57711337SWilliam.Krier@Sun.COM switch (data->kd_type) { 57811337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 579*11447Samw@Sun.COM wka = smb_wka_lookup_builtin((char *)param->name.str); 58011337SWilliam.Krier@Sun.COM if (wka != NULL) { 58111337SWilliam.Krier@Sun.COM param->rids.n_entry = 1; 58211337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(wka->wka_binsid, 58311337SWilliam.Krier@Sun.COM ¶m->rids.rid[0]); 58411337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 1; 58511337SWilliam.Krier@Sun.COM param->rid_types.rid_type[0] = wka->wka_type; 58611337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 58711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 58811337SWilliam.Krier@Sun.COM } 58911337SWilliam.Krier@Sun.COM break; 59011337SWilliam.Krier@Sun.COM 59111337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 59211337SWilliam.Krier@Sun.COM status = smb_sam_lookup_name(NULL, (char *)param->name.str, 59311337SWilliam.Krier@Sun.COM SidTypeUnknown, &account); 59411337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) { 59511337SWilliam.Krier@Sun.COM param->rids.n_entry = 1; 59611337SWilliam.Krier@Sun.COM param->rids.rid[0] = account.a_rid; 59711337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 1; 59811337SWilliam.Krier@Sun.COM param->rid_types.rid_type[0] = account.a_type; 59911337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 60011337SWilliam.Krier@Sun.COM smb_account_free(&account); 60111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 60211337SWilliam.Krier@Sun.COM } 60311337SWilliam.Krier@Sun.COM break; 60411337SWilliam.Krier@Sun.COM 60511337SWilliam.Krier@Sun.COM default: 60611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupNames)); 60711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 60811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 60911337SWilliam.Krier@Sun.COM } 61011337SWilliam.Krier@Sun.COM 61111337SWilliam.Krier@Sun.COM param->rids.n_entry = 0; 61211337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 0; 61311337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NONE_MAPPED); 61411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 61511337SWilliam.Krier@Sun.COM } 61611337SWilliam.Krier@Sun.COM 61711337SWilliam.Krier@Sun.COM /* 61811337SWilliam.Krier@Sun.COM * samr_s_OpenUser 61911337SWilliam.Krier@Sun.COM * 62011337SWilliam.Krier@Sun.COM * This is a request to open a user within a specified domain in the 62111337SWilliam.Krier@Sun.COM * local SAM database. The caller must supply a valid domain handle, 62211337SWilliam.Krier@Sun.COM * obtained via a successful domain open request. The user is 62311337SWilliam.Krier@Sun.COM * specified by the rid in the request. 62411337SWilliam.Krier@Sun.COM */ 62511337SWilliam.Krier@Sun.COM static int 62611337SWilliam.Krier@Sun.COM samr_s_OpenUser(void *arg, ndr_xa_t *mxa) 62711337SWilliam.Krier@Sun.COM { 62811337SWilliam.Krier@Sun.COM struct samr_OpenUser *param = arg; 62911337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 63011337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 63111337SWilliam.Krier@Sun.COM samr_keydata_t *data; 63211337SWilliam.Krier@Sun.COM 63311337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 63411337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 63511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 63611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 63711337SWilliam.Krier@Sun.COM } 63811337SWilliam.Krier@Sun.COM 63911337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 64011337SWilliam.Krier@Sun.COM 64111337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_USER, data->kd_type, param->rid); 64211337SWilliam.Krier@Sun.COM if (id == NULL) { 64311337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 64411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 64511337SWilliam.Krier@Sun.COM } else { 64611337SWilliam.Krier@Sun.COM bcopy(id, ¶m->user_handle, sizeof (samr_handle_t)); 64711337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 64811337SWilliam.Krier@Sun.COM } 64911337SWilliam.Krier@Sun.COM 65011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 65111337SWilliam.Krier@Sun.COM } 65211337SWilliam.Krier@Sun.COM 65311337SWilliam.Krier@Sun.COM /* 65411337SWilliam.Krier@Sun.COM * samr_s_DeleteUser 65511337SWilliam.Krier@Sun.COM * 65611337SWilliam.Krier@Sun.COM * Request to delete a user within a specified domain in the local 65711337SWilliam.Krier@Sun.COM * SAM database. The caller should supply a valid user handle. 65811337SWilliam.Krier@Sun.COM */ 65911337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 66011337SWilliam.Krier@Sun.COM static int 66111337SWilliam.Krier@Sun.COM samr_s_DeleteUser(void *arg, ndr_xa_t *mxa) 66211337SWilliam.Krier@Sun.COM { 66311337SWilliam.Krier@Sun.COM struct samr_DeleteUser *param = arg; 66411337SWilliam.Krier@Sun.COM 66511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteUser)); 66611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 66711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 66811337SWilliam.Krier@Sun.COM } 66911337SWilliam.Krier@Sun.COM 67011337SWilliam.Krier@Sun.COM /* 67111337SWilliam.Krier@Sun.COM * samr_s_QueryUserInfo 67211337SWilliam.Krier@Sun.COM * 67311337SWilliam.Krier@Sun.COM * Returns: 67411337SWilliam.Krier@Sun.COM * NT_STATUS_SUCCESS 67511337SWilliam.Krier@Sun.COM * NT_STATUS_ACCESS_DENIED 67611337SWilliam.Krier@Sun.COM * NT_STATUS_INVALID_INFO_CLASS 67711337SWilliam.Krier@Sun.COM */ 67811337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 67911337SWilliam.Krier@Sun.COM static int 68011337SWilliam.Krier@Sun.COM samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa) 68111337SWilliam.Krier@Sun.COM { 68211337SWilliam.Krier@Sun.COM static uint16_t owf_buf[8]; 68311337SWilliam.Krier@Sun.COM static uint8_t hour_buf[SAMR_SET_USER_HOURS_SZ]; 68411337SWilliam.Krier@Sun.COM struct samr_QueryUserInfo *param = arg; 68511337SWilliam.Krier@Sun.COM struct samr_QueryUserInfo21 *all_info; 68611337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 68711337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 68811337SWilliam.Krier@Sun.COM samr_keydata_t *data; 68911337SWilliam.Krier@Sun.COM smb_domain_t di; 69011337SWilliam.Krier@Sun.COM smb_account_t account; 69111337SWilliam.Krier@Sun.COM smb_sid_t *sid; 69211337SWilliam.Krier@Sun.COM uint32_t status; 69311337SWilliam.Krier@Sun.COM 69411337SWilliam.Krier@Sun.COM id = (ndr_hdid_t *)¶m->user_handle; 69511337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) { 69611337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 69711337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 69811337SWilliam.Krier@Sun.COM } 69911337SWilliam.Krier@Sun.COM 70011337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 70111337SWilliam.Krier@Sun.COM 70211337SWilliam.Krier@Sun.COM if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) { 70311337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 70411337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 70511337SWilliam.Krier@Sun.COM } 70611337SWilliam.Krier@Sun.COM 70711337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) { 70811337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 70911337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 71011337SWilliam.Krier@Sun.COM } 71111337SWilliam.Krier@Sun.COM 71211337SWilliam.Krier@Sun.COM if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) { 71311337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 71411337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 71511337SWilliam.Krier@Sun.COM } 71611337SWilliam.Krier@Sun.COM 71711337SWilliam.Krier@Sun.COM if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) { 71811337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 71911337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 72011337SWilliam.Krier@Sun.COM } 72111337SWilliam.Krier@Sun.COM 72211337SWilliam.Krier@Sun.COM all_info = ¶m->ru.info21; 72311337SWilliam.Krier@Sun.COM bzero(all_info, sizeof (struct samr_QueryUserInfo21)); 72411337SWilliam.Krier@Sun.COM 72511337SWilliam.Krier@Sun.COM all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID; 72611337SWilliam.Krier@Sun.COM 72711337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, account.a_name, 72811337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&all_info->UserName); 72911337SWilliam.Krier@Sun.COM all_info->UserId = data->kd_rid; 73011337SWilliam.Krier@Sun.COM 73111337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.length = 16; 73211337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.maxlen = 16; 73311337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.buf = owf_buf; 73411337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.length = 16; 73511337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.maxlen = 16; 73611337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.buf = owf_buf; 73711337SWilliam.Krier@Sun.COM all_info->LogonHours.units_per_week = SAMR_HOURS_PER_WEEK; 73811337SWilliam.Krier@Sun.COM all_info->LogonHours.hours = hour_buf; 73911337SWilliam.Krier@Sun.COM 74011337SWilliam.Krier@Sun.COM param->address = 1; 74111337SWilliam.Krier@Sun.COM param->switch_index = SAMR_QUERY_USER_ALL_INFO; 74211337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 74311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 74411337SWilliam.Krier@Sun.COM 74511337SWilliam.Krier@Sun.COM QueryUserInfoError: 74611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryUserInfo)); 74711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 74811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 74911337SWilliam.Krier@Sun.COM } 75011337SWilliam.Krier@Sun.COM 75111337SWilliam.Krier@Sun.COM /* 75211337SWilliam.Krier@Sun.COM * samr_s_QueryUserGroups 75311337SWilliam.Krier@Sun.COM * 75411337SWilliam.Krier@Sun.COM * Request the list of groups of which a user is a member. 75511337SWilliam.Krier@Sun.COM * The user is identified from the handle, which contains an 75611337SWilliam.Krier@Sun.COM * rid in the discriminator field. Note that this is a local user. 75711337SWilliam.Krier@Sun.COM */ 75811337SWilliam.Krier@Sun.COM static int 75911337SWilliam.Krier@Sun.COM samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa) 76011337SWilliam.Krier@Sun.COM { 76111337SWilliam.Krier@Sun.COM struct samr_QueryUserGroups *param = arg; 76211337SWilliam.Krier@Sun.COM struct samr_UserGroupInfo *info; 76311337SWilliam.Krier@Sun.COM struct samr_UserGroups *group; 76411337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->user_handle; 76511337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 76611337SWilliam.Krier@Sun.COM samr_keydata_t *data; 76711337SWilliam.Krier@Sun.COM smb_sid_t *user_sid = NULL; 76811337SWilliam.Krier@Sun.COM smb_group_t grp; 76911337SWilliam.Krier@Sun.COM smb_giter_t gi; 77011337SWilliam.Krier@Sun.COM smb_domain_t di; 77111337SWilliam.Krier@Sun.COM uint32_t status; 77211337SWilliam.Krier@Sun.COM int size; 77311337SWilliam.Krier@Sun.COM int ngrp_max; 77411337SWilliam.Krier@Sun.COM 77511337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) { 77611337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 77711337SWilliam.Krier@Sun.COM goto query_error; 77811337SWilliam.Krier@Sun.COM } 77911337SWilliam.Krier@Sun.COM 78011337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 78111337SWilliam.Krier@Sun.COM switch (data->kd_type) { 78211337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 78311337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 78411337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_type(data->kd_type, &di)) { 78511337SWilliam.Krier@Sun.COM status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 78611337SWilliam.Krier@Sun.COM goto query_error; 78711337SWilliam.Krier@Sun.COM } 78811337SWilliam.Krier@Sun.COM break; 78911337SWilliam.Krier@Sun.COM default: 79011337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 79111337SWilliam.Krier@Sun.COM goto query_error; 79211337SWilliam.Krier@Sun.COM } 79311337SWilliam.Krier@Sun.COM 79411337SWilliam.Krier@Sun.COM user_sid = smb_sid_splice(di.di_binsid, data->kd_rid); 79511337SWilliam.Krier@Sun.COM if (user_sid == NULL) { 79611337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 79711337SWilliam.Krier@Sun.COM goto query_error; 79811337SWilliam.Krier@Sun.COM } 79911337SWilliam.Krier@Sun.COM 80011337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_UserGroupInfo); 80111337SWilliam.Krier@Sun.COM if (info == NULL) { 80211337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 80311337SWilliam.Krier@Sun.COM goto query_error; 80411337SWilliam.Krier@Sun.COM } 80511337SWilliam.Krier@Sun.COM bzero(info, sizeof (struct samr_UserGroupInfo)); 80611337SWilliam.Krier@Sun.COM 80711337SWilliam.Krier@Sun.COM size = 32 * 1024; 80811337SWilliam.Krier@Sun.COM info->groups = NDR_MALLOC(mxa, size); 80911337SWilliam.Krier@Sun.COM if (info->groups == 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 ngrp_max = size / sizeof (struct samr_UserGroups); 81411337SWilliam.Krier@Sun.COM 81511337SWilliam.Krier@Sun.COM if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 81611337SWilliam.Krier@Sun.COM status = NT_STATUS_INTERNAL_ERROR; 81711337SWilliam.Krier@Sun.COM goto query_error; 81811337SWilliam.Krier@Sun.COM } 81911337SWilliam.Krier@Sun.COM 82011337SWilliam.Krier@Sun.COM info->n_entry = 0; 82111337SWilliam.Krier@Sun.COM group = info->groups; 82211337SWilliam.Krier@Sun.COM while ((info->n_entry < ngrp_max) && 82311337SWilliam.Krier@Sun.COM (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS)) { 82411337SWilliam.Krier@Sun.COM if (smb_lgrp_is_member(&grp, user_sid)) { 82511337SWilliam.Krier@Sun.COM group->rid = grp.sg_rid; 82611337SWilliam.Krier@Sun.COM group->attr = grp.sg_attr; 82711337SWilliam.Krier@Sun.COM group++; 82811337SWilliam.Krier@Sun.COM info->n_entry++; 82911337SWilliam.Krier@Sun.COM } 83011337SWilliam.Krier@Sun.COM smb_lgrp_free(&grp); 83111337SWilliam.Krier@Sun.COM } 83211337SWilliam.Krier@Sun.COM smb_lgrp_iterclose(&gi); 83311337SWilliam.Krier@Sun.COM 83411337SWilliam.Krier@Sun.COM free(user_sid); 83511337SWilliam.Krier@Sun.COM param->info = info; 83611337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 83711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 83811337SWilliam.Krier@Sun.COM 83911337SWilliam.Krier@Sun.COM query_error: 84011337SWilliam.Krier@Sun.COM free(user_sid); 84111337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryUserGroups)); 84211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 84311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 84411337SWilliam.Krier@Sun.COM } 84511337SWilliam.Krier@Sun.COM 84611337SWilliam.Krier@Sun.COM /* 84711337SWilliam.Krier@Sun.COM * samr_s_OpenGroup 84811337SWilliam.Krier@Sun.COM * 84911337SWilliam.Krier@Sun.COM * This is a request to open a group within the specified domain in the 85011337SWilliam.Krier@Sun.COM * local SAM database. The caller must supply a valid domain handle, 85111337SWilliam.Krier@Sun.COM * obtained via a successful domain open request. The group is 85211337SWilliam.Krier@Sun.COM * specified by the rid in the request. If this is a local RID it 85311337SWilliam.Krier@Sun.COM * should already be encoded with type information. 85411337SWilliam.Krier@Sun.COM * 85511337SWilliam.Krier@Sun.COM * We return a handle to be used to access information about this group. 85611337SWilliam.Krier@Sun.COM */ 85711337SWilliam.Krier@Sun.COM static int 85811337SWilliam.Krier@Sun.COM samr_s_OpenGroup(void *arg, ndr_xa_t *mxa) 85911337SWilliam.Krier@Sun.COM { 86011337SWilliam.Krier@Sun.COM struct samr_OpenGroup *param = arg; 86111337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 86211337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 86311337SWilliam.Krier@Sun.COM samr_keydata_t *data; 86411337SWilliam.Krier@Sun.COM 86511337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 86611337SWilliam.Krier@Sun.COM bzero(¶m->group_handle, sizeof (samr_handle_t)); 86711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 86811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 86911337SWilliam.Krier@Sun.COM } 87011337SWilliam.Krier@Sun.COM 87111337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 87211337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_GROUP, data->kd_type, param->rid); 87311337SWilliam.Krier@Sun.COM 87411337SWilliam.Krier@Sun.COM if (id) { 87511337SWilliam.Krier@Sun.COM bcopy(id, ¶m->group_handle, sizeof (samr_handle_t)); 87611337SWilliam.Krier@Sun.COM param->status = 0; 87711337SWilliam.Krier@Sun.COM } else { 87811337SWilliam.Krier@Sun.COM bzero(¶m->group_handle, sizeof (samr_handle_t)); 87911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 88011337SWilliam.Krier@Sun.COM } 88111337SWilliam.Krier@Sun.COM 88211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 88311337SWilliam.Krier@Sun.COM } 88411337SWilliam.Krier@Sun.COM 88511337SWilliam.Krier@Sun.COM /* 88611337SWilliam.Krier@Sun.COM * samr_s_Connect 88711337SWilliam.Krier@Sun.COM * 88811337SWilliam.Krier@Sun.COM * This is a request to connect to the local SAM database. 88911337SWilliam.Krier@Sun.COM * We don't support any form of update request and our database doesn't 89011337SWilliam.Krier@Sun.COM * contain any private information, so there is little point in doing 89111337SWilliam.Krier@Sun.COM * any access access checking here. 89211337SWilliam.Krier@Sun.COM * 89311337SWilliam.Krier@Sun.COM * Return a handle for use with subsequent SAM requests. 89411337SWilliam.Krier@Sun.COM */ 89511337SWilliam.Krier@Sun.COM static int 89611337SWilliam.Krier@Sun.COM samr_s_Connect(void *arg, ndr_xa_t *mxa) 89711337SWilliam.Krier@Sun.COM { 89811337SWilliam.Krier@Sun.COM struct samr_Connect *param = arg; 89911337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 90011337SWilliam.Krier@Sun.COM 90111337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 90211337SWilliam.Krier@Sun.COM if (id) { 90311337SWilliam.Krier@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 90411337SWilliam.Krier@Sun.COM param->status = 0; 90511337SWilliam.Krier@Sun.COM } else { 90611337SWilliam.Krier@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 90711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 90811337SWilliam.Krier@Sun.COM } 90911337SWilliam.Krier@Sun.COM 91011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 91111337SWilliam.Krier@Sun.COM } 91211337SWilliam.Krier@Sun.COM 91311337SWilliam.Krier@Sun.COM /* 91411337SWilliam.Krier@Sun.COM * samr_s_GetUserPwInfo 91511337SWilliam.Krier@Sun.COM * 916*11447Samw@Sun.COM * Request for a user's password policy information. 91711337SWilliam.Krier@Sun.COM */ 91811337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 91911337SWilliam.Krier@Sun.COM static int 92011337SWilliam.Krier@Sun.COM samr_s_GetUserPwInfo(void *arg, ndr_xa_t *mxa) 92111337SWilliam.Krier@Sun.COM { 922*11447Samw@Sun.COM static samr_password_info_t pwinfo; 923*11447Samw@Sun.COM struct samr_GetUserPwInfo *param = arg; 92411337SWilliam.Krier@Sun.COM 925*11447Samw@Sun.COM param->pwinfo = &pwinfo; 926*11447Samw@Sun.COM param->status = NT_STATUS_SUCCESS; 92711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 92811337SWilliam.Krier@Sun.COM } 92911337SWilliam.Krier@Sun.COM 93011337SWilliam.Krier@Sun.COM /* 93111337SWilliam.Krier@Sun.COM * samr_s_CreateUser 93211337SWilliam.Krier@Sun.COM */ 93311337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 93411337SWilliam.Krier@Sun.COM static int 93511337SWilliam.Krier@Sun.COM samr_s_CreateUser(void *arg, ndr_xa_t *mxa) 93611337SWilliam.Krier@Sun.COM { 93711337SWilliam.Krier@Sun.COM struct samr_CreateUser *param = arg; 93811337SWilliam.Krier@Sun.COM 93911337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 94011337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 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_ChangeUserPasswd 94611337SWilliam.Krier@Sun.COM */ 94711337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 94811337SWilliam.Krier@Sun.COM static int 94911337SWilliam.Krier@Sun.COM samr_s_ChangeUserPasswd(void *arg, ndr_xa_t *mxa) 95011337SWilliam.Krier@Sun.COM { 95111337SWilliam.Krier@Sun.COM struct samr_ChangeUserPasswd *param = arg; 95211337SWilliam.Krier@Sun.COM 95311337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_ChangeUserPasswd)); 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_GetDomainPwInfo 960*11447Samw@Sun.COM * 961*11447Samw@Sun.COM * Request for the domain password policy information. 96211337SWilliam.Krier@Sun.COM */ 96311337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 96411337SWilliam.Krier@Sun.COM static int 96511337SWilliam.Krier@Sun.COM samr_s_GetDomainPwInfo(void *arg, ndr_xa_t *mxa) 96611337SWilliam.Krier@Sun.COM { 967*11447Samw@Sun.COM static samr_password_info_t pwinfo; 968*11447Samw@Sun.COM struct samr_GetDomainPwInfo *param = arg; 96911337SWilliam.Krier@Sun.COM 970*11447Samw@Sun.COM param->pwinfo = &pwinfo; 971*11447Samw@Sun.COM param->status = NT_STATUS_SUCCESS; 97211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 97311337SWilliam.Krier@Sun.COM } 97411337SWilliam.Krier@Sun.COM 97511337SWilliam.Krier@Sun.COM /* 97611337SWilliam.Krier@Sun.COM * samr_s_SetUserInfo 97711337SWilliam.Krier@Sun.COM */ 97811337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 97911337SWilliam.Krier@Sun.COM static int 98011337SWilliam.Krier@Sun.COM samr_s_SetUserInfo(void *arg, ndr_xa_t *mxa) 98111337SWilliam.Krier@Sun.COM { 98211337SWilliam.Krier@Sun.COM struct samr_SetUserInfo *param = arg; 98311337SWilliam.Krier@Sun.COM 98411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_SetUserInfo)); 98511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 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_QueryDispInfo 99111337SWilliam.Krier@Sun.COM * 99211337SWilliam.Krier@Sun.COM * This function currently return local users' information only. 99311337SWilliam.Krier@Sun.COM * This RPC is called repeatedly until all the users info are 99411337SWilliam.Krier@Sun.COM * retrieved. 99511337SWilliam.Krier@Sun.COM * 99611337SWilliam.Krier@Sun.COM * The total count and the returned count are returned as total size 99711337SWilliam.Krier@Sun.COM * and returned size. The client doesn't seem to care. 99811337SWilliam.Krier@Sun.COM */ 99911337SWilliam.Krier@Sun.COM static int 100011337SWilliam.Krier@Sun.COM samr_s_QueryDispInfo(void *arg, ndr_xa_t *mxa) 100111337SWilliam.Krier@Sun.COM { 100211337SWilliam.Krier@Sun.COM struct samr_QueryDispInfo *param = arg; 100311337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 100411337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 100511337SWilliam.Krier@Sun.COM samr_keydata_t *data; 100611337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 100711337SWilliam.Krier@Sun.COM struct user_acct_info *user; 100811337SWilliam.Krier@Sun.COM smb_pwditer_t pwi; 100911337SWilliam.Krier@Sun.COM smb_luser_t *uinfo; 101011337SWilliam.Krier@Sun.COM int num_users; 101111337SWilliam.Krier@Sun.COM int start_idx; 101211337SWilliam.Krier@Sun.COM int max_retcnt, retcnt; 101311337SWilliam.Krier@Sun.COM int skip; 101411337SWilliam.Krier@Sun.COM 101511337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 101611337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 101711337SWilliam.Krier@Sun.COM goto error; 101811337SWilliam.Krier@Sun.COM } 101911337SWilliam.Krier@Sun.COM 102011337SWilliam.Krier@Sun.COM if (!SAMR_VALID_DISPLEVEL(param->level)) { 102111337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_INFO_CLASS; 102211337SWilliam.Krier@Sun.COM goto error; 102311337SWilliam.Krier@Sun.COM } 102411337SWilliam.Krier@Sun.COM 102511337SWilliam.Krier@Sun.COM if (!SAMR_SUPPORTED_DISPLEVEL(param->level)) { 102611337SWilliam.Krier@Sun.COM status = NT_STATUS_NOT_IMPLEMENTED; 102711337SWilliam.Krier@Sun.COM goto error; 102811337SWilliam.Krier@Sun.COM } 102911337SWilliam.Krier@Sun.COM 103011337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 103111337SWilliam.Krier@Sun.COM 103211337SWilliam.Krier@Sun.COM switch (data->kd_type) { 103311337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 103411337SWilliam.Krier@Sun.COM goto no_info; 103511337SWilliam.Krier@Sun.COM 103611337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 103711337SWilliam.Krier@Sun.COM num_users = smb_sam_usr_cnt(); 103811337SWilliam.Krier@Sun.COM start_idx = param->start_idx; 103911337SWilliam.Krier@Sun.COM if ((num_users == 0) || (start_idx >= num_users)) 104011337SWilliam.Krier@Sun.COM goto no_info; 104111337SWilliam.Krier@Sun.COM 104211337SWilliam.Krier@Sun.COM max_retcnt = num_users - start_idx; 104311337SWilliam.Krier@Sun.COM if (max_retcnt > param->max_entries) 104411337SWilliam.Krier@Sun.COM max_retcnt = param->max_entries; 104511337SWilliam.Krier@Sun.COM param->users.acct = NDR_MALLOC(mxa, 104611337SWilliam.Krier@Sun.COM max_retcnt * sizeof (struct user_acct_info)); 104711337SWilliam.Krier@Sun.COM user = param->users.acct; 104811337SWilliam.Krier@Sun.COM if (user == NULL) { 104911337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 105011337SWilliam.Krier@Sun.COM goto error; 105111337SWilliam.Krier@Sun.COM } 105211337SWilliam.Krier@Sun.COM bzero(user, max_retcnt * sizeof (struct user_acct_info)); 105311337SWilliam.Krier@Sun.COM 105411337SWilliam.Krier@Sun.COM if (smb_pwd_iteropen(&pwi) != SMB_PWE_SUCCESS) 105511337SWilliam.Krier@Sun.COM goto no_info; 105611337SWilliam.Krier@Sun.COM 105711337SWilliam.Krier@Sun.COM skip = retcnt = 0; 105811337SWilliam.Krier@Sun.COM while ((uinfo = smb_pwd_iterate(&pwi)) != NULL) { 105911337SWilliam.Krier@Sun.COM if (skip++ < start_idx) 106011337SWilliam.Krier@Sun.COM continue; 106111337SWilliam.Krier@Sun.COM 106211337SWilliam.Krier@Sun.COM if (retcnt++ >= max_retcnt) 106311337SWilliam.Krier@Sun.COM break; 106411337SWilliam.Krier@Sun.COM 106511337SWilliam.Krier@Sun.COM assert(uinfo->su_name != NULL); 106611337SWilliam.Krier@Sun.COM 106711337SWilliam.Krier@Sun.COM user->index = start_idx + retcnt; 106811337SWilliam.Krier@Sun.COM user->rid = uinfo->su_rid; 106911337SWilliam.Krier@Sun.COM user->ctrl = ACF_NORMUSER | ACF_PWDNOEXP; 107011337SWilliam.Krier@Sun.COM if (uinfo->su_ctrl & SMB_PWF_DISABLE) 107111337SWilliam.Krier@Sun.COM user->ctrl |= ACF_DISABLED; 107211337SWilliam.Krier@Sun.COM if (NDR_MSTRING(mxa, uinfo->su_name, 107311337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->name) == -1) { 107411337SWilliam.Krier@Sun.COM smb_pwd_iterclose(&pwi); 107511337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 107611337SWilliam.Krier@Sun.COM goto error; 107711337SWilliam.Krier@Sun.COM } 107811337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, uinfo->su_fullname, 107911337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->fullname); 108011337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, uinfo->su_desc, 108111337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->desc); 108211337SWilliam.Krier@Sun.COM user++; 108311337SWilliam.Krier@Sun.COM } 108411337SWilliam.Krier@Sun.COM smb_pwd_iterclose(&pwi); 108511337SWilliam.Krier@Sun.COM 108611337SWilliam.Krier@Sun.COM if (retcnt >= max_retcnt) { 108711337SWilliam.Krier@Sun.COM retcnt = max_retcnt; 108811337SWilliam.Krier@Sun.COM param->status = status; 108911337SWilliam.Krier@Sun.COM } else { 109011337SWilliam.Krier@Sun.COM param->status = ERROR_MORE_ENTRIES; 109111337SWilliam.Krier@Sun.COM } 109211337SWilliam.Krier@Sun.COM 109311337SWilliam.Krier@Sun.COM param->users.total_size = num_users; 109411337SWilliam.Krier@Sun.COM param->users.returned_size = retcnt; 109511337SWilliam.Krier@Sun.COM param->users.switch_value = param->level; 109611337SWilliam.Krier@Sun.COM param->users.count = retcnt; 109711337SWilliam.Krier@Sun.COM 109811337SWilliam.Krier@Sun.COM break; 109911337SWilliam.Krier@Sun.COM 110011337SWilliam.Krier@Sun.COM default: 110111337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 110211337SWilliam.Krier@Sun.COM goto error; 110311337SWilliam.Krier@Sun.COM } 110411337SWilliam.Krier@Sun.COM 110511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 110611337SWilliam.Krier@Sun.COM 110711337SWilliam.Krier@Sun.COM no_info: 110811337SWilliam.Krier@Sun.COM param->users.total_size = 0; 110911337SWilliam.Krier@Sun.COM param->users.returned_size = 0; 111011337SWilliam.Krier@Sun.COM param->users.switch_value = param->level; 111111337SWilliam.Krier@Sun.COM param->users.count = 0; 111211337SWilliam.Krier@Sun.COM param->users.acct = NULL; 111311337SWilliam.Krier@Sun.COM param->status = status; 111411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 111511337SWilliam.Krier@Sun.COM 111611337SWilliam.Krier@Sun.COM error: 111711337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDispInfo)); 111811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 111911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 112011337SWilliam.Krier@Sun.COM } 112111337SWilliam.Krier@Sun.COM 112211337SWilliam.Krier@Sun.COM /* 112311337SWilliam.Krier@Sun.COM * samr_s_EnumDomainGroups 112411337SWilliam.Krier@Sun.COM * 112511337SWilliam.Krier@Sun.COM * 112611337SWilliam.Krier@Sun.COM * This function is supposed to return local group information. 112711337SWilliam.Krier@Sun.COM * As we don't support local users, this function dosen't send 112811337SWilliam.Krier@Sun.COM * back any information. 112911337SWilliam.Krier@Sun.COM * 113011337SWilliam.Krier@Sun.COM * Added template that returns information for a domain group as None. 113111337SWilliam.Krier@Sun.COM * All information is hard-coded from packet captures. 113211337SWilliam.Krier@Sun.COM */ 113311337SWilliam.Krier@Sun.COM static int 113411337SWilliam.Krier@Sun.COM samr_s_EnumDomainGroups(void *arg, ndr_xa_t *mxa) 113511337SWilliam.Krier@Sun.COM { 113611337SWilliam.Krier@Sun.COM struct samr_EnumDomainGroups *param = arg; 113711337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 113811337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 113911337SWilliam.Krier@Sun.COM 114011337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) 114111337SWilliam.Krier@Sun.COM status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 114211337SWilliam.Krier@Sun.COM 114311337SWilliam.Krier@Sun.COM param->total_size = 0; 114411337SWilliam.Krier@Sun.COM param->returned_size = 0; 114511337SWilliam.Krier@Sun.COM param->switch_value = 3; 114611337SWilliam.Krier@Sun.COM param->count = 0; 114711337SWilliam.Krier@Sun.COM param->groups = 0; 114811337SWilliam.Krier@Sun.COM param->status = status; 114911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 115011337SWilliam.Krier@Sun.COM 115111337SWilliam.Krier@Sun.COM #ifdef SAMR_SUPPORT_GROUPS 115211337SWilliam.Krier@Sun.COM if ((desc->discrim != SAMR_LOCAL_DOMAIN) || (param->start_idx != 0)) { 115311337SWilliam.Krier@Sun.COM param->total_size = 0; 115411337SWilliam.Krier@Sun.COM param->returned_size = 0; 115511337SWilliam.Krier@Sun.COM param->switch_value = 3; 115611337SWilliam.Krier@Sun.COM param->count = 0; 115711337SWilliam.Krier@Sun.COM param->groups = 0; 115811337SWilliam.Krier@Sun.COM } else { 115911337SWilliam.Krier@Sun.COM param->total_size = 64; 116011337SWilliam.Krier@Sun.COM param->returned_size = 64; 116111337SWilliam.Krier@Sun.COM param->switch_value = 3; 116211337SWilliam.Krier@Sun.COM param->count = 1; 116311337SWilliam.Krier@Sun.COM param->groups = (struct group_disp_info *)NDR_MALLOC( 116411337SWilliam.Krier@Sun.COM mxa, sizeof (struct group_disp_info)); 116511337SWilliam.Krier@Sun.COM 116611337SWilliam.Krier@Sun.COM param->groups->count = 1; 116711337SWilliam.Krier@Sun.COM param->groups->acct[0].index = 1; 116811337SWilliam.Krier@Sun.COM param->groups->acct[0].rid = 513; 116911337SWilliam.Krier@Sun.COM param->groups->acct[0].ctrl = 0x7; 117011337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "None", 117111337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->groups->acct[0].name); 117211337SWilliam.Krier@Sun.COM 117311337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "Ordinary users", 117411337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->groups->acct[0].desc); 117511337SWilliam.Krier@Sun.COM } 117611337SWilliam.Krier@Sun.COM 117711337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 117811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 117911337SWilliam.Krier@Sun.COM #endif 118011337SWilliam.Krier@Sun.COM } 118111337SWilliam.Krier@Sun.COM 118211337SWilliam.Krier@Sun.COM /* 118311337SWilliam.Krier@Sun.COM * samr_s_OpenAlias 118411337SWilliam.Krier@Sun.COM * 118511337SWilliam.Krier@Sun.COM * Lookup for requested alias, if it exists return a handle 118611337SWilliam.Krier@Sun.COM * for that alias. The alias domain sid should match with 118711337SWilliam.Krier@Sun.COM * the passed domain handle. 118811337SWilliam.Krier@Sun.COM */ 118911337SWilliam.Krier@Sun.COM static int 119011337SWilliam.Krier@Sun.COM samr_s_OpenAlias(void *arg, ndr_xa_t *mxa) 119111337SWilliam.Krier@Sun.COM { 119211337SWilliam.Krier@Sun.COM struct samr_OpenAlias *param = arg; 1193*11447Samw@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 1194*11447Samw@Sun.COM ndr_handle_t *hd; 1195*11447Samw@Sun.COM samr_keydata_t *data; 1196*11447Samw@Sun.COM smb_gdomain_t gd_type; 1197*11447Samw@Sun.COM smb_sid_t *sid; 1198*11447Samw@Sun.COM smb_wka_t *wka; 1199*11447Samw@Sun.COM char sidstr[SMB_SID_STRSZ]; 1200*11447Samw@Sun.COM uint32_t rid; 1201*11447Samw@Sun.COM uint32_t status; 1202*11447Samw@Sun.COM int rc; 120311337SWilliam.Krier@Sun.COM 120411337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 120511337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 120611337SWilliam.Krier@Sun.COM goto open_alias_err; 120711337SWilliam.Krier@Sun.COM } 120811337SWilliam.Krier@Sun.COM 120911337SWilliam.Krier@Sun.COM if (param->access_mask != SAMR_ALIAS_ACCESS_GET_INFO) { 121011337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 121111337SWilliam.Krier@Sun.COM goto open_alias_err; 121211337SWilliam.Krier@Sun.COM } 121311337SWilliam.Krier@Sun.COM 121411337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 1215*11447Samw@Sun.COM gd_type = (smb_gdomain_t)data->kd_type; 1216*11447Samw@Sun.COM rid = param->rid; 1217*11447Samw@Sun.COM 1218*11447Samw@Sun.COM switch (gd_type) { 1219*11447Samw@Sun.COM case SMB_LGRP_BUILTIN: 1220*11447Samw@Sun.COM (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d", 1221*11447Samw@Sun.COM NT_BUILTIN_DOMAIN_SIDSTR, rid); 1222*11447Samw@Sun.COM if ((sid = smb_sid_fromstr(sidstr)) == NULL) { 1223*11447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 1224*11447Samw@Sun.COM goto open_alias_err; 1225*11447Samw@Sun.COM } 1226*11447Samw@Sun.COM 1227*11447Samw@Sun.COM wka = smb_wka_lookup_sid(sid); 1228*11447Samw@Sun.COM smb_sid_free(sid); 1229*11447Samw@Sun.COM 1230*11447Samw@Sun.COM if (wka == NULL) { 1231*11447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 1232*11447Samw@Sun.COM goto open_alias_err; 1233*11447Samw@Sun.COM } 1234*11447Samw@Sun.COM break; 1235*11447Samw@Sun.COM 1236*11447Samw@Sun.COM case SMB_LGRP_LOCAL: 1237*11447Samw@Sun.COM rc = smb_lgrp_getbyrid(rid, gd_type, NULL); 1238*11447Samw@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 1239*11447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 1240*11447Samw@Sun.COM goto open_alias_err; 1241*11447Samw@Sun.COM } 1242*11447Samw@Sun.COM break; 1243*11447Samw@Sun.COM 1244*11447Samw@Sun.COM default: 124511337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 124611337SWilliam.Krier@Sun.COM goto open_alias_err; 124711337SWilliam.Krier@Sun.COM } 124811337SWilliam.Krier@Sun.COM 124911337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, data->kd_type, param->rid); 125011337SWilliam.Krier@Sun.COM if (id) { 125111337SWilliam.Krier@Sun.COM bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t)); 125211337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 125311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 125411337SWilliam.Krier@Sun.COM } 125511337SWilliam.Krier@Sun.COM 125611337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 125711337SWilliam.Krier@Sun.COM 125811337SWilliam.Krier@Sun.COM open_alias_err: 125911337SWilliam.Krier@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 126011337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 126111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 126211337SWilliam.Krier@Sun.COM } 126311337SWilliam.Krier@Sun.COM 126411337SWilliam.Krier@Sun.COM /* 126511337SWilliam.Krier@Sun.COM * samr_s_CreateDomainAlias 126611337SWilliam.Krier@Sun.COM * 126711337SWilliam.Krier@Sun.COM * Creates a local group in the security database, which is the 126811337SWilliam.Krier@Sun.COM * security accounts manager (SAM) 126911337SWilliam.Krier@Sun.COM * For more information you can look at MSDN page for NetLocalGroupAdd. 127011337SWilliam.Krier@Sun.COM * This RPC is used by CMC and right now it returns access denied. 127111337SWilliam.Krier@Sun.COM * The peice of code that creates a local group doesn't get compiled. 127211337SWilliam.Krier@Sun.COM */ 127311337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 127411337SWilliam.Krier@Sun.COM static int 127511337SWilliam.Krier@Sun.COM samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa) 127611337SWilliam.Krier@Sun.COM { 127711337SWilliam.Krier@Sun.COM struct samr_CreateDomainAlias *param = arg; 127811337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 127911337SWilliam.Krier@Sun.COM 128011337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) { 128111337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_CreateDomainAlias)); 128211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 128311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 128411337SWilliam.Krier@Sun.COM } 128511337SWilliam.Krier@Sun.COM 128611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_CreateDomainAlias)); 128711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 128811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 128911337SWilliam.Krier@Sun.COM 129011337SWilliam.Krier@Sun.COM #ifdef SAMR_SUPPORT_ADD_ALIAS 129111337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 129211337SWilliam.Krier@Sun.COM nt_group_t *grp; 129311337SWilliam.Krier@Sun.COM char *alias_name; 129411337SWilliam.Krier@Sun.COM 129511337SWilliam.Krier@Sun.COM alias_name = param->alias_name.str; 129611337SWilliam.Krier@Sun.COM if (alias_name == 0) { 129711337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_PARAMETER; 129811337SWilliam.Krier@Sun.COM goto create_alias_err; 129911337SWilliam.Krier@Sun.COM } 130011337SWilliam.Krier@Sun.COM 130111337SWilliam.Krier@Sun.COM /* 130211337SWilliam.Krier@Sun.COM * Check access mask. User should be member of 130311337SWilliam.Krier@Sun.COM * Administrators or Account Operators local group. 130411337SWilliam.Krier@Sun.COM */ 130511337SWilliam.Krier@Sun.COM status = nt_group_add(alias_name, 0, 130611337SWilliam.Krier@Sun.COM NT_GROUP_AF_ADD | NT_GROUP_AF_LOCAL); 130711337SWilliam.Krier@Sun.COM 130811337SWilliam.Krier@Sun.COM if (status != NT_STATUS_SUCCESS) 130911337SWilliam.Krier@Sun.COM goto create_alias_err; 131011337SWilliam.Krier@Sun.COM 131111337SWilliam.Krier@Sun.COM grp = nt_group_getinfo(alias_name, RWLOCK_READER); 131211337SWilliam.Krier@Sun.COM if (grp == NULL) { 131311337SWilliam.Krier@Sun.COM status = NT_STATUS_INTERNAL_ERROR; 131411337SWilliam.Krier@Sun.COM goto create_alias_err; 131511337SWilliam.Krier@Sun.COM } 131611337SWilliam.Krier@Sun.COM 131711337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(grp->sid, ¶m->rid); 131811337SWilliam.Krier@Sun.COM nt_group_putinfo(grp); 131911337SWilliam.Krier@Sun.COM handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR, SAMR_ALIAS_KEY, 132011337SWilliam.Krier@Sun.COM param->rid); 132111337SWilliam.Krier@Sun.COM bcopy(handle, ¶m->alias_handle, sizeof (samr_handle_t)); 132211337SWilliam.Krier@Sun.COM 132311337SWilliam.Krier@Sun.COM param->status = 0; 132411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 132511337SWilliam.Krier@Sun.COM 132611337SWilliam.Krier@Sun.COM create_alias_err: 132711337SWilliam.Krier@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 132811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 132911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 133011337SWilliam.Krier@Sun.COM #endif 133111337SWilliam.Krier@Sun.COM } 133211337SWilliam.Krier@Sun.COM 133311337SWilliam.Krier@Sun.COM /* 133411337SWilliam.Krier@Sun.COM * samr_s_SetAliasInfo 133511337SWilliam.Krier@Sun.COM * 133611337SWilliam.Krier@Sun.COM * Similar to NetLocalGroupSetInfo. 133711337SWilliam.Krier@Sun.COM */ 133811337SWilliam.Krier@Sun.COM static int 133911337SWilliam.Krier@Sun.COM samr_s_SetAliasInfo(void *arg, ndr_xa_t *mxa) 134011337SWilliam.Krier@Sun.COM { 134111337SWilliam.Krier@Sun.COM struct samr_SetAliasInfo *param = arg; 134211337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 134311337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 134411337SWilliam.Krier@Sun.COM 134511337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) 134611337SWilliam.Krier@Sun.COM status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 134711337SWilliam.Krier@Sun.COM 134811337SWilliam.Krier@Sun.COM param->status = status; 134911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 135011337SWilliam.Krier@Sun.COM } 135111337SWilliam.Krier@Sun.COM 135211337SWilliam.Krier@Sun.COM /* 135311337SWilliam.Krier@Sun.COM * samr_s_QueryAliasInfo 135411337SWilliam.Krier@Sun.COM * 135511337SWilliam.Krier@Sun.COM * Retrieves information about the specified local group account 135611337SWilliam.Krier@Sun.COM * by given handle. 135711337SWilliam.Krier@Sun.COM */ 135811337SWilliam.Krier@Sun.COM static int 135911337SWilliam.Krier@Sun.COM samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa) 136011337SWilliam.Krier@Sun.COM { 136111337SWilliam.Krier@Sun.COM struct samr_QueryAliasInfo *param = arg; 1362*11447Samw@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1363*11447Samw@Sun.COM ndr_handle_t *hd; 1364*11447Samw@Sun.COM samr_keydata_t *data; 1365*11447Samw@Sun.COM smb_group_t grp; 1366*11447Samw@Sun.COM smb_gdomain_t gd_type; 1367*11447Samw@Sun.COM smb_sid_t *sid; 1368*11447Samw@Sun.COM smb_wka_t *wka; 1369*11447Samw@Sun.COM char sidstr[SMB_SID_STRSZ]; 1370*11447Samw@Sun.COM char *name; 1371*11447Samw@Sun.COM char *desc; 1372*11447Samw@Sun.COM uint32_t rid; 1373*11447Samw@Sun.COM uint32_t status; 1374*11447Samw@Sun.COM int rc; 137511337SWilliam.Krier@Sun.COM 137611337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 137711337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 137811337SWilliam.Krier@Sun.COM goto query_alias_err; 137911337SWilliam.Krier@Sun.COM } 138011337SWilliam.Krier@Sun.COM 138111337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 1382*11447Samw@Sun.COM gd_type = (smb_gdomain_t)data->kd_type; 1383*11447Samw@Sun.COM rid = data->kd_rid; 1384*11447Samw@Sun.COM 1385*11447Samw@Sun.COM switch (gd_type) { 1386*11447Samw@Sun.COM case SMB_LGRP_BUILTIN: 1387*11447Samw@Sun.COM (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d", 1388*11447Samw@Sun.COM NT_BUILTIN_DOMAIN_SIDSTR, rid); 1389*11447Samw@Sun.COM if ((sid = smb_sid_fromstr(sidstr)) == NULL) { 1390*11447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 1391*11447Samw@Sun.COM goto query_alias_err; 1392*11447Samw@Sun.COM } 1393*11447Samw@Sun.COM 1394*11447Samw@Sun.COM wka = smb_wka_lookup_sid(sid); 1395*11447Samw@Sun.COM smb_sid_free(sid); 1396*11447Samw@Sun.COM 1397*11447Samw@Sun.COM if (wka == NULL) { 1398*11447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 1399*11447Samw@Sun.COM goto query_alias_err; 1400*11447Samw@Sun.COM } 1401*11447Samw@Sun.COM 1402*11447Samw@Sun.COM name = wka->wka_name; 1403*11447Samw@Sun.COM desc = (wka->wka_desc != NULL) ? wka->wka_desc : ""; 1404*11447Samw@Sun.COM break; 1405*11447Samw@Sun.COM 1406*11447Samw@Sun.COM case SMB_LGRP_LOCAL: 1407*11447Samw@Sun.COM rc = smb_lgrp_getbyrid(rid, gd_type, &grp); 1408*11447Samw@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 1409*11447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 1410*11447Samw@Sun.COM goto query_alias_err; 1411*11447Samw@Sun.COM } 1412*11447Samw@Sun.COM name = grp.sg_name; 1413*11447Samw@Sun.COM desc = grp.sg_cmnt; 1414*11447Samw@Sun.COM break; 1415*11447Samw@Sun.COM 1416*11447Samw@Sun.COM default: 141711337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 141811337SWilliam.Krier@Sun.COM goto query_alias_err; 141911337SWilliam.Krier@Sun.COM } 142011337SWilliam.Krier@Sun.COM 142111337SWilliam.Krier@Sun.COM switch (param->level) { 142211337SWilliam.Krier@Sun.COM case SAMR_QUERY_ALIAS_INFO_1: 142311337SWilliam.Krier@Sun.COM param->ru.info1.level = param->level; 1424*11447Samw@Sun.COM (void) NDR_MSTRING(mxa, name, 142511337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info1.name); 142611337SWilliam.Krier@Sun.COM 1427*11447Samw@Sun.COM (void) NDR_MSTRING(mxa, desc, 142811337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info1.desc); 142911337SWilliam.Krier@Sun.COM 143011337SWilliam.Krier@Sun.COM param->ru.info1.unknown = 1; 143111337SWilliam.Krier@Sun.COM break; 143211337SWilliam.Krier@Sun.COM 143311337SWilliam.Krier@Sun.COM case SAMR_QUERY_ALIAS_INFO_3: 143411337SWilliam.Krier@Sun.COM param->ru.info3.level = param->level; 1435*11447Samw@Sun.COM (void) NDR_MSTRING(mxa, desc, 143611337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info3.desc); 143711337SWilliam.Krier@Sun.COM break; 143811337SWilliam.Krier@Sun.COM 143911337SWilliam.Krier@Sun.COM default: 1440*11447Samw@Sun.COM if (gd_type == SMB_LGRP_LOCAL) 1441*11447Samw@Sun.COM smb_lgrp_free(&grp); 144211337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_INFO_CLASS; 144311337SWilliam.Krier@Sun.COM goto query_alias_err; 144411337SWilliam.Krier@Sun.COM }; 144511337SWilliam.Krier@Sun.COM 1446*11447Samw@Sun.COM if (gd_type == SMB_LGRP_LOCAL) 1447*11447Samw@Sun.COM smb_lgrp_free(&grp); 144811337SWilliam.Krier@Sun.COM param->address = (DWORD)(uintptr_t)¶m->ru; 144911337SWilliam.Krier@Sun.COM param->status = 0; 145011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 145111337SWilliam.Krier@Sun.COM 145211337SWilliam.Krier@Sun.COM query_alias_err: 145311337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 145411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 145511337SWilliam.Krier@Sun.COM } 145611337SWilliam.Krier@Sun.COM 145711337SWilliam.Krier@Sun.COM /* 145811337SWilliam.Krier@Sun.COM * samr_s_DeleteDomainAlias 145911337SWilliam.Krier@Sun.COM * 146011337SWilliam.Krier@Sun.COM * Deletes a local group account and all its members from the 146111337SWilliam.Krier@Sun.COM * security database, which is the security accounts manager (SAM) database. 146211337SWilliam.Krier@Sun.COM * Only members of the Administrators or Account Operators local group can 146311337SWilliam.Krier@Sun.COM * execute this function. 146411337SWilliam.Krier@Sun.COM * For more information you can look at MSDN page for NetLocalGroupSetInfo. 146511337SWilliam.Krier@Sun.COM * 146611337SWilliam.Krier@Sun.COM * This RPC is used by CMC and right now it returns access denied. 146711337SWilliam.Krier@Sun.COM * The peice of code that removes a local group doesn't get compiled. 146811337SWilliam.Krier@Sun.COM */ 146911337SWilliam.Krier@Sun.COM static int 147011337SWilliam.Krier@Sun.COM samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa) 147111337SWilliam.Krier@Sun.COM { 147211337SWilliam.Krier@Sun.COM struct samr_DeleteDomainAlias *param = arg; 147311337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 147411337SWilliam.Krier@Sun.COM 147511337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) { 147611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 147711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 147811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 147911337SWilliam.Krier@Sun.COM } 148011337SWilliam.Krier@Sun.COM 148111337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 148211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 148311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 148411337SWilliam.Krier@Sun.COM 148511337SWilliam.Krier@Sun.COM #ifdef SAMR_SUPPORT_DEL_ALIAS 148611337SWilliam.Krier@Sun.COM nt_group_t *grp; 148711337SWilliam.Krier@Sun.COM char *alias_name; 148811337SWilliam.Krier@Sun.COM DWORD status; 148911337SWilliam.Krier@Sun.COM 149011337SWilliam.Krier@Sun.COM grp = nt_groups_lookup_rid(desc->discrim); 149111337SWilliam.Krier@Sun.COM if (grp == 0) { 149211337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 149311337SWilliam.Krier@Sun.COM goto delete_alias_err; 149411337SWilliam.Krier@Sun.COM } 149511337SWilliam.Krier@Sun.COM 149611337SWilliam.Krier@Sun.COM alias_name = strdup(grp->name); 149711337SWilliam.Krier@Sun.COM if (alias_name == 0) { 149811337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 149911337SWilliam.Krier@Sun.COM goto delete_alias_err; 150011337SWilliam.Krier@Sun.COM } 150111337SWilliam.Krier@Sun.COM 150211337SWilliam.Krier@Sun.COM status = nt_group_delete(alias_name); 150311337SWilliam.Krier@Sun.COM free(alias_name); 150411337SWilliam.Krier@Sun.COM if (status != NT_STATUS_SUCCESS) 150511337SWilliam.Krier@Sun.COM goto delete_alias_err; 150611337SWilliam.Krier@Sun.COM 150711337SWilliam.Krier@Sun.COM param->status = 0; 150811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 150911337SWilliam.Krier@Sun.COM 151011337SWilliam.Krier@Sun.COM delete_alias_err: 151111337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 151211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 151311337SWilliam.Krier@Sun.COM #endif 151411337SWilliam.Krier@Sun.COM } 151511337SWilliam.Krier@Sun.COM 151611337SWilliam.Krier@Sun.COM /* 151711337SWilliam.Krier@Sun.COM * samr_s_EnumDomainAliases 151811337SWilliam.Krier@Sun.COM * 151911337SWilliam.Krier@Sun.COM * This function sends back a list which contains all local groups' name. 152011337SWilliam.Krier@Sun.COM */ 152111337SWilliam.Krier@Sun.COM static int 152211337SWilliam.Krier@Sun.COM samr_s_EnumDomainAliases(void *arg, ndr_xa_t *mxa) 152311337SWilliam.Krier@Sun.COM { 152411337SWilliam.Krier@Sun.COM struct samr_EnumDomainAliases *param = arg; 152511337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 152611337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 152711337SWilliam.Krier@Sun.COM samr_keydata_t *data; 152811337SWilliam.Krier@Sun.COM smb_group_t grp; 152911337SWilliam.Krier@Sun.COM smb_giter_t gi; 153011337SWilliam.Krier@Sun.COM int cnt, skip, i; 153111337SWilliam.Krier@Sun.COM struct name_rid *info; 153211337SWilliam.Krier@Sun.COM 153311337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 153411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 153511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 153611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 153711337SWilliam.Krier@Sun.COM } 153811337SWilliam.Krier@Sun.COM 153911337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 154011337SWilliam.Krier@Sun.COM 154111337SWilliam.Krier@Sun.COM cnt = smb_sam_grp_cnt(data->kd_type); 154211337SWilliam.Krier@Sun.COM if (cnt <= param->resume_handle) { 154311337SWilliam.Krier@Sun.COM param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, 154411337SWilliam.Krier@Sun.COM sizeof (struct aliases_info)); 154511337SWilliam.Krier@Sun.COM 154611337SWilliam.Krier@Sun.COM if (param->aliases == NULL) { 154711337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 154811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 154911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 155011337SWilliam.Krier@Sun.COM } 155111337SWilliam.Krier@Sun.COM 155211337SWilliam.Krier@Sun.COM bzero(param->aliases, sizeof (struct aliases_info)); 155311337SWilliam.Krier@Sun.COM param->out_resume = 0; 155411337SWilliam.Krier@Sun.COM param->entries = 0; 155511337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 155611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 155711337SWilliam.Krier@Sun.COM } 155811337SWilliam.Krier@Sun.COM 155911337SWilliam.Krier@Sun.COM cnt -= param->resume_handle; 156011337SWilliam.Krier@Sun.COM param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, 156111337SWilliam.Krier@Sun.COM sizeof (struct aliases_info) + (cnt-1) * sizeof (struct name_rid)); 156211337SWilliam.Krier@Sun.COM 156311337SWilliam.Krier@Sun.COM if (param->aliases == NULL) { 156411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 156511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 156611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 156711337SWilliam.Krier@Sun.COM } 156811337SWilliam.Krier@Sun.COM 156911337SWilliam.Krier@Sun.COM if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 157011337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 157111337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); 157211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 157311337SWilliam.Krier@Sun.COM } 157411337SWilliam.Krier@Sun.COM 157511337SWilliam.Krier@Sun.COM skip = i = 0; 157611337SWilliam.Krier@Sun.COM info = param->aliases->info; 157711337SWilliam.Krier@Sun.COM while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) { 157811337SWilliam.Krier@Sun.COM if ((skip++ >= param->resume_handle) && 157911337SWilliam.Krier@Sun.COM (grp.sg_domain == data->kd_type) && (i++ < cnt)) { 158011337SWilliam.Krier@Sun.COM info->rid = grp.sg_rid; 158111337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, grp.sg_name, 158211337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&info->name); 158311337SWilliam.Krier@Sun.COM 158411337SWilliam.Krier@Sun.COM info++; 158511337SWilliam.Krier@Sun.COM } 158611337SWilliam.Krier@Sun.COM smb_lgrp_free(&grp); 158711337SWilliam.Krier@Sun.COM } 158811337SWilliam.Krier@Sun.COM smb_lgrp_iterclose(&gi); 158911337SWilliam.Krier@Sun.COM 159011337SWilliam.Krier@Sun.COM param->aliases->count = i; 159111337SWilliam.Krier@Sun.COM param->aliases->address = i; 159211337SWilliam.Krier@Sun.COM 159311337SWilliam.Krier@Sun.COM param->out_resume = i; 159411337SWilliam.Krier@Sun.COM param->entries = i; 159511337SWilliam.Krier@Sun.COM param->status = 0; 159611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 159711337SWilliam.Krier@Sun.COM } 159811337SWilliam.Krier@Sun.COM 159911337SWilliam.Krier@Sun.COM /* 160011337SWilliam.Krier@Sun.COM * samr_s_Connect3 160111337SWilliam.Krier@Sun.COM */ 160211337SWilliam.Krier@Sun.COM static int 160311337SWilliam.Krier@Sun.COM samr_s_Connect3(void *arg, ndr_xa_t *mxa) 160411337SWilliam.Krier@Sun.COM { 1605*11447Samw@Sun.COM struct samr_Connect3 *param = arg; 1606*11447Samw@Sun.COM ndr_hdid_t *id; 160711337SWilliam.Krier@Sun.COM 1608*11447Samw@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 1609*11447Samw@Sun.COM if (id) { 1610*11447Samw@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 1611*11447Samw@Sun.COM param->status = 0; 1612*11447Samw@Sun.COM } else { 1613*11447Samw@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 1614*11447Samw@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1615*11447Samw@Sun.COM } 1616*11447Samw@Sun.COM 1617*11447Samw@Sun.COM return (NDR_DRC_OK); 161811337SWilliam.Krier@Sun.COM } 161911337SWilliam.Krier@Sun.COM 162011337SWilliam.Krier@Sun.COM /* 162111337SWilliam.Krier@Sun.COM * samr_s_Connect4 162211337SWilliam.Krier@Sun.COM * 162311337SWilliam.Krier@Sun.COM * This is the connect4 form of the connect request used by Windows XP. 162411337SWilliam.Krier@Sun.COM * Returns an RPC fault for now. 162511337SWilliam.Krier@Sun.COM */ 162611337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 162711337SWilliam.Krier@Sun.COM static int 162811337SWilliam.Krier@Sun.COM samr_s_Connect4(void *arg, ndr_xa_t *mxa) 162911337SWilliam.Krier@Sun.COM { 163011337SWilliam.Krier@Sun.COM struct samr_Connect4 *param = arg; 163111337SWilliam.Krier@Sun.COM 163211337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_Connect4)); 163311337SWilliam.Krier@Sun.COM return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 163411337SWilliam.Krier@Sun.COM } 163511337SWilliam.Krier@Sun.COM 163611337SWilliam.Krier@Sun.COM static ndr_stub_table_t samr_stub_table[] = { 163711337SWilliam.Krier@Sun.COM { samr_s_ConnectAnon, SAMR_OPNUM_ConnectAnon }, 163811337SWilliam.Krier@Sun.COM { samr_s_CloseHandle, SAMR_OPNUM_CloseHandle }, 163911337SWilliam.Krier@Sun.COM { samr_s_LookupDomain, SAMR_OPNUM_LookupDomain }, 164011337SWilliam.Krier@Sun.COM { samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains }, 164111337SWilliam.Krier@Sun.COM { samr_s_OpenDomain, SAMR_OPNUM_OpenDomain }, 164211337SWilliam.Krier@Sun.COM { samr_s_QueryDomainInfo, SAMR_OPNUM_QueryDomainInfo }, 1643*11447Samw@Sun.COM { samr_s_QueryInfoDomain2, SAMR_OPNUM_QueryInfoDomain2 }, 164411337SWilliam.Krier@Sun.COM { samr_s_LookupNames, SAMR_OPNUM_LookupNames }, 164511337SWilliam.Krier@Sun.COM { samr_s_OpenUser, SAMR_OPNUM_OpenUser }, 164611337SWilliam.Krier@Sun.COM { samr_s_DeleteUser, SAMR_OPNUM_DeleteUser }, 164711337SWilliam.Krier@Sun.COM { samr_s_QueryUserInfo, SAMR_OPNUM_QueryUserInfo }, 164811337SWilliam.Krier@Sun.COM { samr_s_QueryUserGroups, SAMR_OPNUM_QueryUserGroups }, 164911337SWilliam.Krier@Sun.COM { samr_s_OpenGroup, SAMR_OPNUM_OpenGroup }, 165011337SWilliam.Krier@Sun.COM { samr_s_Connect, SAMR_OPNUM_Connect }, 165111337SWilliam.Krier@Sun.COM { samr_s_GetUserPwInfo, SAMR_OPNUM_GetUserPwInfo }, 165211337SWilliam.Krier@Sun.COM { samr_s_CreateUser, SAMR_OPNUM_CreateUser }, 165311337SWilliam.Krier@Sun.COM { samr_s_ChangeUserPasswd, SAMR_OPNUM_ChangeUserPasswd }, 165411337SWilliam.Krier@Sun.COM { samr_s_GetDomainPwInfo, SAMR_OPNUM_GetDomainPwInfo }, 165511337SWilliam.Krier@Sun.COM { samr_s_SetUserInfo, SAMR_OPNUM_SetUserInfo }, 165611337SWilliam.Krier@Sun.COM { samr_s_Connect3, SAMR_OPNUM_Connect3 }, 165711337SWilliam.Krier@Sun.COM { samr_s_Connect4, SAMR_OPNUM_Connect4 }, 165811337SWilliam.Krier@Sun.COM { samr_s_QueryDispInfo, SAMR_OPNUM_QueryDispInfo }, 165911337SWilliam.Krier@Sun.COM { samr_s_OpenAlias, SAMR_OPNUM_OpenAlias }, 166011337SWilliam.Krier@Sun.COM { samr_s_CreateDomainAlias, SAMR_OPNUM_CreateDomainAlias }, 166111337SWilliam.Krier@Sun.COM { samr_s_SetAliasInfo, SAMR_OPNUM_SetAliasInfo }, 166211337SWilliam.Krier@Sun.COM { samr_s_QueryAliasInfo, SAMR_OPNUM_QueryAliasInfo }, 166311337SWilliam.Krier@Sun.COM { samr_s_DeleteDomainAlias, SAMR_OPNUM_DeleteDomainAlias }, 166411337SWilliam.Krier@Sun.COM { samr_s_EnumDomainAliases, SAMR_OPNUM_EnumDomainAliases }, 166511337SWilliam.Krier@Sun.COM { samr_s_EnumDomainGroups, SAMR_OPNUM_EnumDomainGroups }, 166611337SWilliam.Krier@Sun.COM {0} 166711337SWilliam.Krier@Sun.COM }; 166811337SWilliam.Krier@Sun.COM 166911337SWilliam.Krier@Sun.COM /* 167011337SWilliam.Krier@Sun.COM * There is a bug in the way that midl and the marshalling code handles 167111337SWilliam.Krier@Sun.COM * unions so we need to fix some of the data offsets at runtime. The 167211337SWilliam.Krier@Sun.COM * following macros and the fixup functions handle the corrections. 167311337SWilliam.Krier@Sun.COM */ 167411337SWilliam.Krier@Sun.COM 167511337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfo_ru); 167611337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfoRes); 167711337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfo); 167811337SWilliam.Krier@Sun.COM 167911337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(QueryUserInfo_result_u); 168011337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(QueryUserInfo_result); 168111337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryUserInfo); 168211337SWilliam.Krier@Sun.COM 168311337SWilliam.Krier@Sun.COM void 168411337SWilliam.Krier@Sun.COM fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo *val) 168511337SWilliam.Krier@Sun.COM { 168611337SWilliam.Krier@Sun.COM unsigned short size1 = 0; 168711337SWilliam.Krier@Sun.COM unsigned short size2 = 0; 168811337SWilliam.Krier@Sun.COM unsigned short size3 = 0; 168911337SWilliam.Krier@Sun.COM 169011337SWilliam.Krier@Sun.COM switch (val->level) { 169111337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryAliasInfo, 1); 169211337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryAliasInfo, 3); 169311337SWilliam.Krier@Sun.COM 169411337SWilliam.Krier@Sun.COM default: 169511337SWilliam.Krier@Sun.COM return; 169611337SWilliam.Krier@Sun.COM }; 169711337SWilliam.Krier@Sun.COM 169811337SWilliam.Krier@Sun.COM size2 = size1 + (2 * sizeof (DWORD)); 169911337SWilliam.Krier@Sun.COM size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 170011337SWilliam.Krier@Sun.COM 170111337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfo_ru, size1); 170211337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfoRes, size2); 170311337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfo, size3); 170411337SWilliam.Krier@Sun.COM } 170511337SWilliam.Krier@Sun.COM 170611337SWilliam.Krier@Sun.COM void 170711337SWilliam.Krier@Sun.COM fixup_samr_QueryUserInfo(struct samr_QueryUserInfo *val) 170811337SWilliam.Krier@Sun.COM { 170911337SWilliam.Krier@Sun.COM unsigned short size1 = 0; 171011337SWilliam.Krier@Sun.COM unsigned short size2 = 0; 171111337SWilliam.Krier@Sun.COM unsigned short size3 = 0; 171211337SWilliam.Krier@Sun.COM 171311337SWilliam.Krier@Sun.COM switch (val->switch_index) { 171411337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 1); 171511337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 6); 171611337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 7); 171711337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 8); 171811337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 9); 171911337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 16); 172011337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 21); 172111337SWilliam.Krier@Sun.COM 172211337SWilliam.Krier@Sun.COM default: 172311337SWilliam.Krier@Sun.COM return; 172411337SWilliam.Krier@Sun.COM }; 172511337SWilliam.Krier@Sun.COM 172611337SWilliam.Krier@Sun.COM size2 = size1 + (2 * sizeof (DWORD)); 172711337SWilliam.Krier@Sun.COM size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 172811337SWilliam.Krier@Sun.COM 172911337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(QueryUserInfo_result_u, size1); 173011337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(QueryUserInfo_result, size2); 173111337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryUserInfo, size3); 173211337SWilliam.Krier@Sun.COM } 173311337SWilliam.Krier@Sun.COM 173411337SWilliam.Krier@Sun.COM /* 173511337SWilliam.Krier@Sun.COM * As long as there is only one entry in the union, there is no need 173611337SWilliam.Krier@Sun.COM * to patch anything. 173711337SWilliam.Krier@Sun.COM */ 173811337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 173911337SWilliam.Krier@Sun.COM void 174011337SWilliam.Krier@Sun.COM fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo *val) 174111337SWilliam.Krier@Sun.COM { 174211337SWilliam.Krier@Sun.COM } 1743