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 */ 21*12508Samw@Sun.COM 2211337SWilliam.Krier@Sun.COM /* 2312065SKeyur.Desai@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 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> 4012065SKeyur.Desai@Sun.COM #include <grp.h> 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/smbinfo.h> 4511337SWilliam.Krier@Sun.COM #include <smbsrv/nmpipes.h> 4611337SWilliam.Krier@Sun.COM #include <smbsrv/ndl/samrpc.ndl> 4711337SWilliam.Krier@Sun.COM #include <samlib.h> 4811337SWilliam.Krier@Sun.COM 4911337SWilliam.Krier@Sun.COM /* 5011337SWilliam.Krier@Sun.COM * The keys associated with the various handles dispensed by the SAMR 5111337SWilliam.Krier@Sun.COM * server. These keys can be used to validate client activity. 5211337SWilliam.Krier@Sun.COM * These values are never passed over the wire so security shouldn't 5311337SWilliam.Krier@Sun.COM * be an issue. 5411337SWilliam.Krier@Sun.COM */ 5511337SWilliam.Krier@Sun.COM typedef enum { 5611337SWilliam.Krier@Sun.COM SAMR_KEY_NULL = 0, 5711337SWilliam.Krier@Sun.COM SAMR_KEY_CONNECT, 5811337SWilliam.Krier@Sun.COM SAMR_KEY_DOMAIN, 5911337SWilliam.Krier@Sun.COM SAMR_KEY_USER, 6011337SWilliam.Krier@Sun.COM SAMR_KEY_GROUP, 6111337SWilliam.Krier@Sun.COM SAMR_KEY_ALIAS 6211337SWilliam.Krier@Sun.COM } samr_key_t; 6311337SWilliam.Krier@Sun.COM 6411337SWilliam.Krier@Sun.COM typedef struct samr_keydata { 6511337SWilliam.Krier@Sun.COM samr_key_t kd_key; 6611337SWilliam.Krier@Sun.COM smb_domain_type_t kd_type; 6711337SWilliam.Krier@Sun.COM DWORD kd_rid; 6811337SWilliam.Krier@Sun.COM } samr_keydata_t; 6911337SWilliam.Krier@Sun.COM 7011337SWilliam.Krier@Sun.COM /* 7111337SWilliam.Krier@Sun.COM * DomainDisplayUser All user objects (or those derived from user) with 7211337SWilliam.Krier@Sun.COM * userAccountControl containing the UF_NORMAL_ACCOUNT bit. 7311337SWilliam.Krier@Sun.COM * 7411337SWilliam.Krier@Sun.COM * DomainDisplayMachine All user objects (or those derived from user) with 7511337SWilliam.Krier@Sun.COM * userAccountControl containing the 7611337SWilliam.Krier@Sun.COM * UF_WORKSTATION_TRUST_ACCOUNT or UF_SERVER_TRUST_ACCOUNT 7711337SWilliam.Krier@Sun.COM * bit. 7811337SWilliam.Krier@Sun.COM * 7911337SWilliam.Krier@Sun.COM * DomainDisplayGroup All group objects (or those derived from group) with 8011337SWilliam.Krier@Sun.COM * groupType equal to GROUP_TYPE_SECURITY_UNIVERSAL or 8111337SWilliam.Krier@Sun.COM * GROUP_TYPE_SECURITY_ACCOUNT. 8211337SWilliam.Krier@Sun.COM * 8311337SWilliam.Krier@Sun.COM * DomainDisplayOemUser Same as DomainDisplayUser with OEM strings 8411337SWilliam.Krier@Sun.COM * 8511337SWilliam.Krier@Sun.COM * DomainDisplayOemGroup Same as DomainDisplayGroup with OEM strings 8611337SWilliam.Krier@Sun.COM */ 8711337SWilliam.Krier@Sun.COM typedef enum { 8811337SWilliam.Krier@Sun.COM DomainDisplayUser = 1, 8911337SWilliam.Krier@Sun.COM DomainDisplayMachine, 9011337SWilliam.Krier@Sun.COM DomainDispalyGroup, 9111337SWilliam.Krier@Sun.COM DomainDisplayOemUser, 9211337SWilliam.Krier@Sun.COM DomainDisplayOemGroup 9311337SWilliam.Krier@Sun.COM } samr_displvl_t; 9411337SWilliam.Krier@Sun.COM 9511337SWilliam.Krier@Sun.COM #define SAMR_VALID_DISPLEVEL(lvl) \ 9611337SWilliam.Krier@Sun.COM (((lvl) >= DomainDisplayUser) && ((lvl) <= DomainDisplayOemGroup)) 9711337SWilliam.Krier@Sun.COM 9811337SWilliam.Krier@Sun.COM #define SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser) 9911337SWilliam.Krier@Sun.COM 10011337SWilliam.Krier@Sun.COM static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t, 10111337SWilliam.Krier@Sun.COM DWORD); 10211337SWilliam.Krier@Sun.COM static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *); 10311337SWilliam.Krier@Sun.COM static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t); 10411337SWilliam.Krier@Sun.COM static int samr_call_stub(ndr_xa_t *mxa); 10511337SWilliam.Krier@Sun.COM static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *, 10611337SWilliam.Krier@Sun.COM ndr_xa_t *); 10711337SWilliam.Krier@Sun.COM 10811337SWilliam.Krier@Sun.COM static ndr_stub_table_t samr_stub_table[]; 10911337SWilliam.Krier@Sun.COM 11011337SWilliam.Krier@Sun.COM static ndr_service_t samr_service = { 11111337SWilliam.Krier@Sun.COM "SAMR", /* name */ 11211337SWilliam.Krier@Sun.COM "Security Accounts Manager", /* desc */ 11311337SWilliam.Krier@Sun.COM "\\samr", /* endpoint */ 11411337SWilliam.Krier@Sun.COM PIPE_LSASS, /* sec_addr_port */ 11511337SWilliam.Krier@Sun.COM "12345778-1234-abcd-ef00-0123456789ac", 1, /* abstract */ 11611337SWilliam.Krier@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 11711337SWilliam.Krier@Sun.COM 0, /* no bind_instance_size */ 11811337SWilliam.Krier@Sun.COM NULL, /* no bind_req() */ 11911337SWilliam.Krier@Sun.COM NULL, /* no unbind_and_close() */ 12011337SWilliam.Krier@Sun.COM samr_call_stub, /* call_stub() */ 12111337SWilliam.Krier@Sun.COM &TYPEINFO(samr_interface), /* interface ti */ 12211337SWilliam.Krier@Sun.COM samr_stub_table /* stub_table */ 12311337SWilliam.Krier@Sun.COM }; 12411337SWilliam.Krier@Sun.COM 12511337SWilliam.Krier@Sun.COM /* 12611337SWilliam.Krier@Sun.COM * samr_initialize 12711337SWilliam.Krier@Sun.COM * 12811337SWilliam.Krier@Sun.COM * This function registers the SAM RPC interface with the RPC runtime 12911337SWilliam.Krier@Sun.COM * library. It must be called in order to use either the client side 13011337SWilliam.Krier@Sun.COM * or the server side functions. 13111337SWilliam.Krier@Sun.COM */ 13211337SWilliam.Krier@Sun.COM void 13311337SWilliam.Krier@Sun.COM samr_initialize(void) 13411337SWilliam.Krier@Sun.COM { 13511337SWilliam.Krier@Sun.COM (void) ndr_svc_register(&samr_service); 13611337SWilliam.Krier@Sun.COM } 13711337SWilliam.Krier@Sun.COM 13811337SWilliam.Krier@Sun.COM /* 13911337SWilliam.Krier@Sun.COM * Custom call_stub to set the stream string policy. 14011337SWilliam.Krier@Sun.COM */ 14111337SWilliam.Krier@Sun.COM static int 14211337SWilliam.Krier@Sun.COM samr_call_stub(ndr_xa_t *mxa) 14311337SWilliam.Krier@Sun.COM { 14411337SWilliam.Krier@Sun.COM NDS_SETF(&mxa->send_nds, NDS_F_NOTERM); 14511337SWilliam.Krier@Sun.COM NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM); 14611337SWilliam.Krier@Sun.COM 14711337SWilliam.Krier@Sun.COM return (ndr_generic_call_stub(mxa)); 14811337SWilliam.Krier@Sun.COM } 14911337SWilliam.Krier@Sun.COM 15011337SWilliam.Krier@Sun.COM /* 15111337SWilliam.Krier@Sun.COM * Handle allocation wrapper to setup the local context. 15211337SWilliam.Krier@Sun.COM */ 15311337SWilliam.Krier@Sun.COM static ndr_hdid_t * 15411337SWilliam.Krier@Sun.COM samr_hdalloc(ndr_xa_t *mxa, samr_key_t key, smb_domain_type_t domain_type, 15511337SWilliam.Krier@Sun.COM DWORD rid) 15611337SWilliam.Krier@Sun.COM { 15711963SAfshin.Ardakani@Sun.COM ndr_handle_t *hd; 15811963SAfshin.Ardakani@Sun.COM ndr_hdid_t *id; 15911963SAfshin.Ardakani@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 16811963SAfshin.Ardakani@Sun.COM if ((id = ndr_hdalloc(mxa, data)) == NULL) { 16911963SAfshin.Ardakani@Sun.COM free(data); 17011963SAfshin.Ardakani@Sun.COM return (NULL); 17111963SAfshin.Ardakani@Sun.COM } 17211963SAfshin.Ardakani@Sun.COM 17311963SAfshin.Ardakani@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL) 17411963SAfshin.Ardakani@Sun.COM hd->nh_data_free = free; 17511963SAfshin.Ardakani@Sun.COM 17611963SAfshin.Ardakani@Sun.COM return (id); 17711337SWilliam.Krier@Sun.COM } 17811337SWilliam.Krier@Sun.COM 17911337SWilliam.Krier@Sun.COM /* 18011337SWilliam.Krier@Sun.COM * Handle deallocation wrapper to free the local context. 18111337SWilliam.Krier@Sun.COM */ 18211337SWilliam.Krier@Sun.COM static void 18311337SWilliam.Krier@Sun.COM samr_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id) 18411337SWilliam.Krier@Sun.COM { 18511337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 18611337SWilliam.Krier@Sun.COM 18711337SWilliam.Krier@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL) { 18811337SWilliam.Krier@Sun.COM free(hd->nh_data); 18911963SAfshin.Ardakani@Sun.COM hd->nh_data = NULL; 19011337SWilliam.Krier@Sun.COM ndr_hdfree(mxa, id); 19111337SWilliam.Krier@Sun.COM } 19211337SWilliam.Krier@Sun.COM } 19311337SWilliam.Krier@Sun.COM 19411337SWilliam.Krier@Sun.COM /* 19511337SWilliam.Krier@Sun.COM * Handle lookup wrapper to validate the local context. 19611337SWilliam.Krier@Sun.COM */ 19711337SWilliam.Krier@Sun.COM static ndr_handle_t * 19811337SWilliam.Krier@Sun.COM samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key) 19911337SWilliam.Krier@Sun.COM { 20011337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 20111337SWilliam.Krier@Sun.COM samr_keydata_t *data; 20211337SWilliam.Krier@Sun.COM 20311337SWilliam.Krier@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) == NULL) 20411337SWilliam.Krier@Sun.COM return (NULL); 20511337SWilliam.Krier@Sun.COM 20611337SWilliam.Krier@Sun.COM if ((data = (samr_keydata_t *)hd->nh_data) == NULL) 20711337SWilliam.Krier@Sun.COM return (NULL); 20811337SWilliam.Krier@Sun.COM 20911337SWilliam.Krier@Sun.COM if (data->kd_key != key) 21011337SWilliam.Krier@Sun.COM return (NULL); 21111337SWilliam.Krier@Sun.COM 21211337SWilliam.Krier@Sun.COM return (hd); 21311337SWilliam.Krier@Sun.COM } 21411337SWilliam.Krier@Sun.COM 21511337SWilliam.Krier@Sun.COM /* 21611337SWilliam.Krier@Sun.COM * samr_s_ConnectAnon 21711337SWilliam.Krier@Sun.COM * 21811337SWilliam.Krier@Sun.COM * This is a request to connect to the local SAM database. We don't 21911337SWilliam.Krier@Sun.COM * support any form of update request and our database doesn't 22011337SWilliam.Krier@Sun.COM * contain any private information, so there is little point in 22111337SWilliam.Krier@Sun.COM * doing any access access checking here. 22211337SWilliam.Krier@Sun.COM * 22311337SWilliam.Krier@Sun.COM * Return a handle for use with subsequent SAM requests. 22411337SWilliam.Krier@Sun.COM */ 22511337SWilliam.Krier@Sun.COM static int 22611337SWilliam.Krier@Sun.COM samr_s_ConnectAnon(void *arg, ndr_xa_t *mxa) 22711337SWilliam.Krier@Sun.COM { 22811337SWilliam.Krier@Sun.COM struct samr_ConnectAnon *param = arg; 22911337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 23011337SWilliam.Krier@Sun.COM 23111337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 23211337SWilliam.Krier@Sun.COM if (id) { 23311337SWilliam.Krier@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 23411337SWilliam.Krier@Sun.COM param->status = 0; 23511337SWilliam.Krier@Sun.COM } else { 23611337SWilliam.Krier@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 23711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 23811337SWilliam.Krier@Sun.COM } 23911337SWilliam.Krier@Sun.COM 24011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 24111337SWilliam.Krier@Sun.COM } 24211337SWilliam.Krier@Sun.COM 24311337SWilliam.Krier@Sun.COM /* 24411337SWilliam.Krier@Sun.COM * samr_s_CloseHandle 24511337SWilliam.Krier@Sun.COM * 24611337SWilliam.Krier@Sun.COM * Close the SAM interface specified by the handle. 24711337SWilliam.Krier@Sun.COM * Free the handle and zero out the result handle for the client. 24811337SWilliam.Krier@Sun.COM */ 24911337SWilliam.Krier@Sun.COM static int 25011337SWilliam.Krier@Sun.COM samr_s_CloseHandle(void *arg, ndr_xa_t *mxa) 25111337SWilliam.Krier@Sun.COM { 25211337SWilliam.Krier@Sun.COM struct samr_CloseHandle *param = arg; 25311337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 25411337SWilliam.Krier@Sun.COM 25511337SWilliam.Krier@Sun.COM samr_hdfree(mxa, id); 25611337SWilliam.Krier@Sun.COM 25711337SWilliam.Krier@Sun.COM bzero(¶m->result_handle, sizeof (samr_handle_t)); 25811337SWilliam.Krier@Sun.COM param->status = 0; 25911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 26011337SWilliam.Krier@Sun.COM } 26111337SWilliam.Krier@Sun.COM 26211337SWilliam.Krier@Sun.COM /* 26311337SWilliam.Krier@Sun.COM * samr_s_LookupDomain 26411337SWilliam.Krier@Sun.COM * 26511337SWilliam.Krier@Sun.COM * This is a request to map a domain name to a domain SID. We can map 26611337SWilliam.Krier@Sun.COM * the primary domain name, our local domain name (hostname) and the 26711337SWilliam.Krier@Sun.COM * builtin domain names to the appropriate SID. Anything else will be 26811337SWilliam.Krier@Sun.COM * rejected. 26911337SWilliam.Krier@Sun.COM */ 27011337SWilliam.Krier@Sun.COM static int 27111337SWilliam.Krier@Sun.COM samr_s_LookupDomain(void *arg, ndr_xa_t *mxa) 27211337SWilliam.Krier@Sun.COM { 27311337SWilliam.Krier@Sun.COM struct samr_LookupDomain *param = arg; 27411337SWilliam.Krier@Sun.COM char *domain_name; 27511337SWilliam.Krier@Sun.COM smb_domain_t di; 27611337SWilliam.Krier@Sun.COM 27711337SWilliam.Krier@Sun.COM if ((domain_name = (char *)param->domain_name.str) == NULL) { 27811337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 27911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 28011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 28111337SWilliam.Krier@Sun.COM } 28211337SWilliam.Krier@Sun.COM 28311337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_name(domain_name, &di)) { 28411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 28511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_DOMAIN); 28611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 28711337SWilliam.Krier@Sun.COM } 28811337SWilliam.Krier@Sun.COM 28911337SWilliam.Krier@Sun.COM param->sid = (struct samr_sid *)NDR_SIDDUP(mxa, di.di_binsid); 29011337SWilliam.Krier@Sun.COM if (param->sid == NULL) { 29111337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 29211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 29311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 29411337SWilliam.Krier@Sun.COM } 29511337SWilliam.Krier@Sun.COM 29611337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 29711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 29811337SWilliam.Krier@Sun.COM } 29911337SWilliam.Krier@Sun.COM 30011337SWilliam.Krier@Sun.COM /* 30111337SWilliam.Krier@Sun.COM * samr_s_EnumLocalDomains 30211337SWilliam.Krier@Sun.COM * 30311337SWilliam.Krier@Sun.COM * This is a request for the local domains supported by this server. 30411337SWilliam.Krier@Sun.COM * All we do here is validate the handle and set the status. The real 30511337SWilliam.Krier@Sun.COM * work is done in samr_s_enum_local_domains. 30611337SWilliam.Krier@Sun.COM */ 30711337SWilliam.Krier@Sun.COM static int 30811337SWilliam.Krier@Sun.COM samr_s_EnumLocalDomains(void *arg, ndr_xa_t *mxa) 30911337SWilliam.Krier@Sun.COM { 31011337SWilliam.Krier@Sun.COM struct samr_EnumLocalDomain *param = arg; 31111337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 31211337SWilliam.Krier@Sun.COM DWORD status; 31311337SWilliam.Krier@Sun.COM 31411337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) 31511337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 31611337SWilliam.Krier@Sun.COM else 31711337SWilliam.Krier@Sun.COM status = samr_s_enum_local_domains(param, mxa); 31811337SWilliam.Krier@Sun.COM 31911337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) { 32011337SWilliam.Krier@Sun.COM param->enum_context = param->info->entries_read; 32111337SWilliam.Krier@Sun.COM param->total_entries = param->info->entries_read; 32211337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 32311337SWilliam.Krier@Sun.COM } else { 32411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumLocalDomain)); 32511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 32611337SWilliam.Krier@Sun.COM } 32711337SWilliam.Krier@Sun.COM 32811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 32911337SWilliam.Krier@Sun.COM } 33011337SWilliam.Krier@Sun.COM 33111337SWilliam.Krier@Sun.COM 33211337SWilliam.Krier@Sun.COM /* 33311337SWilliam.Krier@Sun.COM * samr_s_enum_local_domains 33411337SWilliam.Krier@Sun.COM * 33511337SWilliam.Krier@Sun.COM * This function should only be called via samr_s_EnumLocalDomains to 33611337SWilliam.Krier@Sun.COM * ensure that the appropriate validation is performed. We will answer 33711337SWilliam.Krier@Sun.COM * queries about two domains: the local domain, synonymous with the 33811337SWilliam.Krier@Sun.COM * local hostname, and the BUILTIN domain. So we return these two 33911337SWilliam.Krier@Sun.COM * strings. 34011337SWilliam.Krier@Sun.COM * 34111337SWilliam.Krier@Sun.COM * Returns NT status values. 34211337SWilliam.Krier@Sun.COM */ 34311337SWilliam.Krier@Sun.COM static DWORD 34411337SWilliam.Krier@Sun.COM samr_s_enum_local_domains(struct samr_EnumLocalDomain *param, 34511337SWilliam.Krier@Sun.COM ndr_xa_t *mxa) 34611337SWilliam.Krier@Sun.COM { 34711337SWilliam.Krier@Sun.COM struct samr_LocalDomainInfo *info; 34811337SWilliam.Krier@Sun.COM struct samr_LocalDomainEntry *entry; 34911337SWilliam.Krier@Sun.COM char *hostname; 35011337SWilliam.Krier@Sun.COM 35111337SWilliam.Krier@Sun.COM hostname = NDR_MALLOC(mxa, NETBIOS_NAME_SZ); 35211337SWilliam.Krier@Sun.COM if (hostname == NULL) 35311337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 35411337SWilliam.Krier@Sun.COM 35511337SWilliam.Krier@Sun.COM if (smb_getnetbiosname(hostname, NETBIOS_NAME_SZ) != 0) 35611337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 35711337SWilliam.Krier@Sun.COM 35811337SWilliam.Krier@Sun.COM entry = NDR_NEWN(mxa, struct samr_LocalDomainEntry, 2); 35911337SWilliam.Krier@Sun.COM if (entry == NULL) 36011337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 36111337SWilliam.Krier@Sun.COM 36211337SWilliam.Krier@Sun.COM bzero(entry, (sizeof (struct samr_LocalDomainEntry) * 2)); 36311337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, hostname, (ndr_mstring_t *)&entry[0].name); 36411337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "Builtin", (ndr_mstring_t *)&entry[1].name); 36511337SWilliam.Krier@Sun.COM 36611337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_LocalDomainInfo); 36711337SWilliam.Krier@Sun.COM if (info == NULL) 36811337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 36911337SWilliam.Krier@Sun.COM 37011337SWilliam.Krier@Sun.COM info->entries_read = 2; 37111337SWilliam.Krier@Sun.COM info->entry = entry; 37211337SWilliam.Krier@Sun.COM param->info = info; 37311337SWilliam.Krier@Sun.COM return (NT_STATUS_SUCCESS); 37411337SWilliam.Krier@Sun.COM } 37511337SWilliam.Krier@Sun.COM 37611337SWilliam.Krier@Sun.COM /* 37711337SWilliam.Krier@Sun.COM * samr_s_OpenDomain 37811337SWilliam.Krier@Sun.COM * 37911337SWilliam.Krier@Sun.COM * This is a request to open a domain within the local SAM database. 38011337SWilliam.Krier@Sun.COM * The caller must supply a valid connect handle. 38111337SWilliam.Krier@Sun.COM * We return a handle to be used to access objects within this domain. 38211337SWilliam.Krier@Sun.COM */ 38311337SWilliam.Krier@Sun.COM static int 38411337SWilliam.Krier@Sun.COM samr_s_OpenDomain(void *arg, ndr_xa_t *mxa) 38511337SWilliam.Krier@Sun.COM { 38611337SWilliam.Krier@Sun.COM struct samr_OpenDomain *param = arg; 38711337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 38811337SWilliam.Krier@Sun.COM smb_domain_t domain; 38911337SWilliam.Krier@Sun.COM 39011337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) { 39111337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 39211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 39311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 39411337SWilliam.Krier@Sun.COM } 39511337SWilliam.Krier@Sun.COM 39611337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_sid((smb_sid_t *)param->sid, &domain)) { 39711337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 39811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 39911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 40011337SWilliam.Krier@Sun.COM } 40111337SWilliam.Krier@Sun.COM 40211337SWilliam.Krier@Sun.COM if ((domain.di_type != SMB_DOMAIN_BUILTIN) && 40311337SWilliam.Krier@Sun.COM (domain.di_type != SMB_DOMAIN_LOCAL)) { 40411337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 40511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 40611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 40711337SWilliam.Krier@Sun.COM } 40811337SWilliam.Krier@Sun.COM 40911337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_DOMAIN, domain.di_type, 0); 41011337SWilliam.Krier@Sun.COM if (id) { 41111337SWilliam.Krier@Sun.COM bcopy(id, ¶m->domain_handle, sizeof (samr_handle_t)); 41211337SWilliam.Krier@Sun.COM param->status = 0; 41311337SWilliam.Krier@Sun.COM } else { 41411337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 41511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 41611337SWilliam.Krier@Sun.COM } 41711337SWilliam.Krier@Sun.COM 41811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 41911337SWilliam.Krier@Sun.COM } 42011337SWilliam.Krier@Sun.COM 42111337SWilliam.Krier@Sun.COM /* 42211337SWilliam.Krier@Sun.COM * samr_s_QueryDomainInfo 42311337SWilliam.Krier@Sun.COM * 42411337SWilliam.Krier@Sun.COM * The caller should pass a domain handle. 42511337SWilliam.Krier@Sun.COM * 42611337SWilliam.Krier@Sun.COM * Windows 95 Server Manager sends requests for levels 6 and 7 when 42711337SWilliam.Krier@Sun.COM * the services menu item is selected. Level 2 is basically for getting 42811337SWilliam.Krier@Sun.COM * number of users, groups, and aliases in a domain. 42911337SWilliam.Krier@Sun.COM * We have no information on what the various information levels mean. 43011337SWilliam.Krier@Sun.COM */ 43111337SWilliam.Krier@Sun.COM static int 43211337SWilliam.Krier@Sun.COM samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa) 43311337SWilliam.Krier@Sun.COM { 43411337SWilliam.Krier@Sun.COM struct samr_QueryDomainInfo *param = arg; 43511337SWilliam.Krier@Sun.COM struct samr_QueryDomainInfoRes *info; 43611337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 43711337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 43811337SWilliam.Krier@Sun.COM samr_keydata_t *data; 43911337SWilliam.Krier@Sun.COM char *domain; 44011337SWilliam.Krier@Sun.COM char hostname[NETBIOS_NAME_SZ]; 44111337SWilliam.Krier@Sun.COM int alias_cnt, user_cnt; 44211337SWilliam.Krier@Sun.COM int rc = 0; 44311337SWilliam.Krier@Sun.COM 44411337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 44511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 44611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 44711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 44811337SWilliam.Krier@Sun.COM } 44911337SWilliam.Krier@Sun.COM 45011337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_QueryDomainInfoRes); 45111337SWilliam.Krier@Sun.COM if (info == NULL) { 45211337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 45311337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 45411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 45511337SWilliam.Krier@Sun.COM } 45611337SWilliam.Krier@Sun.COM info->switch_value = param->info_level; 45711337SWilliam.Krier@Sun.COM param->info = info; 45811337SWilliam.Krier@Sun.COM 45911337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 46011337SWilliam.Krier@Sun.COM 46111337SWilliam.Krier@Sun.COM switch (data->kd_type) { 46211337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 46311337SWilliam.Krier@Sun.COM domain = "BUILTIN"; 46411337SWilliam.Krier@Sun.COM user_cnt = 0; 46511337SWilliam.Krier@Sun.COM alias_cnt = smb_sam_grp_cnt(data->kd_type); 46611337SWilliam.Krier@Sun.COM break; 46711337SWilliam.Krier@Sun.COM 46811337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 46911337SWilliam.Krier@Sun.COM rc = smb_getnetbiosname(hostname, sizeof (hostname)); 47011337SWilliam.Krier@Sun.COM if (rc == 0) { 47111337SWilliam.Krier@Sun.COM domain = hostname; 47211337SWilliam.Krier@Sun.COM user_cnt = smb_sam_usr_cnt(); 47311337SWilliam.Krier@Sun.COM alias_cnt = smb_sam_grp_cnt(data->kd_type); 47411337SWilliam.Krier@Sun.COM } 47511337SWilliam.Krier@Sun.COM break; 47611337SWilliam.Krier@Sun.COM 47711337SWilliam.Krier@Sun.COM default: 47811337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 47911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 48011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 48111337SWilliam.Krier@Sun.COM } 48211337SWilliam.Krier@Sun.COM 48311337SWilliam.Krier@Sun.COM if (rc != 0) { 48411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 48511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); 48611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 48711337SWilliam.Krier@Sun.COM } 48811337SWilliam.Krier@Sun.COM 48911337SWilliam.Krier@Sun.COM switch (param->info_level) { 49011337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_6: 49111337SWilliam.Krier@Sun.COM info->ru.info6.unknown1 = 0x00000000; 49211337SWilliam.Krier@Sun.COM info->ru.info6.unknown2 = 0x00147FB0; 49311337SWilliam.Krier@Sun.COM info->ru.info6.unknown3 = 0x00000000; 49411337SWilliam.Krier@Sun.COM info->ru.info6.unknown4 = 0x00000000; 49511337SWilliam.Krier@Sun.COM info->ru.info6.unknown5 = 0x00000000; 49611337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 49711337SWilliam.Krier@Sun.COM break; 49811337SWilliam.Krier@Sun.COM 49911337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_7: 50011337SWilliam.Krier@Sun.COM info->ru.info7.unknown1 = 0x00000003; 50111337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 50211337SWilliam.Krier@Sun.COM break; 50311337SWilliam.Krier@Sun.COM 50411337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_2: 50511337SWilliam.Krier@Sun.COM info->ru.info2.unknown1 = 0x00000000; 50611337SWilliam.Krier@Sun.COM info->ru.info2.unknown2 = 0x80000000; 50711337SWilliam.Krier@Sun.COM 50811337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "", 50911337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.s1)); 51011337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, domain, 51111337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.domain)); 51211337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "", 51311337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.s2)); 51411337SWilliam.Krier@Sun.COM 51511337SWilliam.Krier@Sun.COM info->ru.info2.sequence_num = 0x0000002B; 51611337SWilliam.Krier@Sun.COM info->ru.info2.unknown3 = 0x00000000; 51711337SWilliam.Krier@Sun.COM info->ru.info2.unknown4 = 0x00000001; 51811337SWilliam.Krier@Sun.COM info->ru.info2.unknown5 = 0x00000003; 51911337SWilliam.Krier@Sun.COM info->ru.info2.unknown6 = 0x00000001; 52011337SWilliam.Krier@Sun.COM info->ru.info2.num_users = user_cnt; 52111337SWilliam.Krier@Sun.COM info->ru.info2.num_groups = 0; 52211337SWilliam.Krier@Sun.COM info->ru.info2.num_aliases = alias_cnt; 52311337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 52411337SWilliam.Krier@Sun.COM break; 52511337SWilliam.Krier@Sun.COM 52611337SWilliam.Krier@Sun.COM default: 52711337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 52811337SWilliam.Krier@Sun.COM return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 52911337SWilliam.Krier@Sun.COM }; 53011337SWilliam.Krier@Sun.COM 53111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 53211337SWilliam.Krier@Sun.COM } 53311337SWilliam.Krier@Sun.COM 53411337SWilliam.Krier@Sun.COM /* 53511447Samw@Sun.COM * QueryInfoDomain2: Identical to QueryDomainInfo. 53611447Samw@Sun.COM */ 53711447Samw@Sun.COM static int 53811447Samw@Sun.COM samr_s_QueryInfoDomain2(void *arg, ndr_xa_t *mxa) 53911447Samw@Sun.COM { 54011447Samw@Sun.COM return (samr_s_QueryDomainInfo(arg, mxa)); 54111447Samw@Sun.COM } 54211447Samw@Sun.COM 54311447Samw@Sun.COM /* 54411337SWilliam.Krier@Sun.COM * Looks up the given name in the specified domain which could 54511337SWilliam.Krier@Sun.COM * be either the built-in or local domain. 54611337SWilliam.Krier@Sun.COM * 54711337SWilliam.Krier@Sun.COM * CAVEAT: this function should be able to handle a list of 54811337SWilliam.Krier@Sun.COM * names but currently it can only handle one name at a time. 54911337SWilliam.Krier@Sun.COM */ 55011337SWilliam.Krier@Sun.COM static int 55111337SWilliam.Krier@Sun.COM samr_s_LookupNames(void *arg, ndr_xa_t *mxa) 55211337SWilliam.Krier@Sun.COM { 55311337SWilliam.Krier@Sun.COM struct samr_LookupNames *param = arg; 55411337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 55511337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 55611337SWilliam.Krier@Sun.COM samr_keydata_t *data; 55711337SWilliam.Krier@Sun.COM smb_account_t account; 55811337SWilliam.Krier@Sun.COM smb_wka_t *wka; 55911337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 56011337SWilliam.Krier@Sun.COM 56111337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) 56211337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 56311337SWilliam.Krier@Sun.COM 56411337SWilliam.Krier@Sun.COM if (param->n_entry != 1) 56511337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 56611337SWilliam.Krier@Sun.COM 56711337SWilliam.Krier@Sun.COM if (param->name.str == NULL) { 56811337SWilliam.Krier@Sun.COM /* 56911337SWilliam.Krier@Sun.COM * Windows NT returns NT_STATUS_NONE_MAPPED. 57011337SWilliam.Krier@Sun.COM * Windows 2000 returns STATUS_INVALID_ACCOUNT_NAME. 57111337SWilliam.Krier@Sun.COM */ 57211337SWilliam.Krier@Sun.COM status = NT_STATUS_NONE_MAPPED; 57311337SWilliam.Krier@Sun.COM } 57411337SWilliam.Krier@Sun.COM 57511337SWilliam.Krier@Sun.COM if (status != NT_STATUS_SUCCESS) { 57611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupNames)); 57711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 57811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 57911337SWilliam.Krier@Sun.COM } 58011337SWilliam.Krier@Sun.COM 58111337SWilliam.Krier@Sun.COM param->rids.rid = NDR_NEW(mxa, DWORD); 58211337SWilliam.Krier@Sun.COM param->rid_types.rid_type = NDR_NEW(mxa, DWORD); 58311337SWilliam.Krier@Sun.COM 58411337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 58511337SWilliam.Krier@Sun.COM 58611337SWilliam.Krier@Sun.COM switch (data->kd_type) { 58711337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 58811447Samw@Sun.COM wka = smb_wka_lookup_builtin((char *)param->name.str); 58911337SWilliam.Krier@Sun.COM if (wka != NULL) { 59011337SWilliam.Krier@Sun.COM param->rids.n_entry = 1; 59111337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(wka->wka_binsid, 59211337SWilliam.Krier@Sun.COM ¶m->rids.rid[0]); 59311337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 1; 59411337SWilliam.Krier@Sun.COM param->rid_types.rid_type[0] = wka->wka_type; 59511337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 59611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 59711337SWilliam.Krier@Sun.COM } 59811337SWilliam.Krier@Sun.COM break; 59911337SWilliam.Krier@Sun.COM 60011337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 60111337SWilliam.Krier@Sun.COM status = smb_sam_lookup_name(NULL, (char *)param->name.str, 60211337SWilliam.Krier@Sun.COM SidTypeUnknown, &account); 60311337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) { 60411337SWilliam.Krier@Sun.COM param->rids.n_entry = 1; 60511337SWilliam.Krier@Sun.COM param->rids.rid[0] = account.a_rid; 60611337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 1; 60711337SWilliam.Krier@Sun.COM param->rid_types.rid_type[0] = account.a_type; 60811337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 60911337SWilliam.Krier@Sun.COM smb_account_free(&account); 61011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 61111337SWilliam.Krier@Sun.COM } 61211337SWilliam.Krier@Sun.COM break; 61311337SWilliam.Krier@Sun.COM 61411337SWilliam.Krier@Sun.COM default: 61511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupNames)); 61611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 61711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 61811337SWilliam.Krier@Sun.COM } 61911337SWilliam.Krier@Sun.COM 62011337SWilliam.Krier@Sun.COM param->rids.n_entry = 0; 62111337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 0; 62211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NONE_MAPPED); 62311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 62411337SWilliam.Krier@Sun.COM } 62511337SWilliam.Krier@Sun.COM 62611337SWilliam.Krier@Sun.COM /* 62711337SWilliam.Krier@Sun.COM * samr_s_OpenUser 62811337SWilliam.Krier@Sun.COM * 62911337SWilliam.Krier@Sun.COM * This is a request to open a user within a specified domain in the 63011337SWilliam.Krier@Sun.COM * local SAM database. The caller must supply a valid domain handle, 63111337SWilliam.Krier@Sun.COM * obtained via a successful domain open request. The user is 63211337SWilliam.Krier@Sun.COM * specified by the rid in the request. 63311337SWilliam.Krier@Sun.COM */ 63411337SWilliam.Krier@Sun.COM static int 63511337SWilliam.Krier@Sun.COM samr_s_OpenUser(void *arg, ndr_xa_t *mxa) 63611337SWilliam.Krier@Sun.COM { 63711337SWilliam.Krier@Sun.COM struct samr_OpenUser *param = arg; 63811337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 63911337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 64011337SWilliam.Krier@Sun.COM samr_keydata_t *data; 64111337SWilliam.Krier@Sun.COM 64211337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 64311337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 64411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 64511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 64611337SWilliam.Krier@Sun.COM } 64711337SWilliam.Krier@Sun.COM 64811337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 64911337SWilliam.Krier@Sun.COM 65011337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_USER, data->kd_type, param->rid); 65111337SWilliam.Krier@Sun.COM if (id == NULL) { 65211337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 65311337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 65411337SWilliam.Krier@Sun.COM } else { 65511337SWilliam.Krier@Sun.COM bcopy(id, ¶m->user_handle, sizeof (samr_handle_t)); 65611337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 65711337SWilliam.Krier@Sun.COM } 65811337SWilliam.Krier@Sun.COM 65911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 66011337SWilliam.Krier@Sun.COM } 66111337SWilliam.Krier@Sun.COM 66211337SWilliam.Krier@Sun.COM /* 66311337SWilliam.Krier@Sun.COM * samr_s_DeleteUser 66411337SWilliam.Krier@Sun.COM * 66511337SWilliam.Krier@Sun.COM * Request to delete a user within a specified domain in the local 66611337SWilliam.Krier@Sun.COM * SAM database. The caller should supply a valid user handle. 66711337SWilliam.Krier@Sun.COM */ 66811337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 66911337SWilliam.Krier@Sun.COM static int 67011337SWilliam.Krier@Sun.COM samr_s_DeleteUser(void *arg, ndr_xa_t *mxa) 67111337SWilliam.Krier@Sun.COM { 67211337SWilliam.Krier@Sun.COM struct samr_DeleteUser *param = arg; 67311337SWilliam.Krier@Sun.COM 67411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteUser)); 67511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 67611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 67711337SWilliam.Krier@Sun.COM } 67811337SWilliam.Krier@Sun.COM 67911337SWilliam.Krier@Sun.COM /* 68011337SWilliam.Krier@Sun.COM * samr_s_QueryUserInfo 68111337SWilliam.Krier@Sun.COM * 68211337SWilliam.Krier@Sun.COM * Returns: 68311337SWilliam.Krier@Sun.COM * NT_STATUS_SUCCESS 68411337SWilliam.Krier@Sun.COM * NT_STATUS_ACCESS_DENIED 68511337SWilliam.Krier@Sun.COM * NT_STATUS_INVALID_INFO_CLASS 68611337SWilliam.Krier@Sun.COM */ 68711337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 68811337SWilliam.Krier@Sun.COM static int 68911337SWilliam.Krier@Sun.COM samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa) 69011337SWilliam.Krier@Sun.COM { 69111337SWilliam.Krier@Sun.COM static uint16_t owf_buf[8]; 69211337SWilliam.Krier@Sun.COM static uint8_t hour_buf[SAMR_SET_USER_HOURS_SZ]; 69311337SWilliam.Krier@Sun.COM struct samr_QueryUserInfo *param = arg; 69411337SWilliam.Krier@Sun.COM struct samr_QueryUserInfo21 *all_info; 69511337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 69611337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 69711337SWilliam.Krier@Sun.COM samr_keydata_t *data; 69811337SWilliam.Krier@Sun.COM smb_domain_t di; 69911337SWilliam.Krier@Sun.COM smb_account_t account; 70011337SWilliam.Krier@Sun.COM smb_sid_t *sid; 70111337SWilliam.Krier@Sun.COM uint32_t status; 70211337SWilliam.Krier@Sun.COM 70311337SWilliam.Krier@Sun.COM id = (ndr_hdid_t *)¶m->user_handle; 70411337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) { 70511337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 70611337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 70711337SWilliam.Krier@Sun.COM } 70811337SWilliam.Krier@Sun.COM 70911337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 71011337SWilliam.Krier@Sun.COM 71111337SWilliam.Krier@Sun.COM if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) { 71211337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 71311337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 71411337SWilliam.Krier@Sun.COM } 71511337SWilliam.Krier@Sun.COM 71611337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) { 71711337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 71811337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 71911337SWilliam.Krier@Sun.COM } 72011337SWilliam.Krier@Sun.COM 72111337SWilliam.Krier@Sun.COM if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) { 72211337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 72311337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 72411337SWilliam.Krier@Sun.COM } 72511337SWilliam.Krier@Sun.COM 72611337SWilliam.Krier@Sun.COM if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) { 72711337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 72811337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 72911337SWilliam.Krier@Sun.COM } 73011337SWilliam.Krier@Sun.COM 73111337SWilliam.Krier@Sun.COM all_info = ¶m->ru.info21; 73211337SWilliam.Krier@Sun.COM bzero(all_info, sizeof (struct samr_QueryUserInfo21)); 73311337SWilliam.Krier@Sun.COM 73411337SWilliam.Krier@Sun.COM all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID; 73511337SWilliam.Krier@Sun.COM 73611337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, account.a_name, 73711337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&all_info->UserName); 73811337SWilliam.Krier@Sun.COM all_info->UserId = data->kd_rid; 73911337SWilliam.Krier@Sun.COM 74011337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.length = 16; 74111337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.maxlen = 16; 74211337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.buf = owf_buf; 74311337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.length = 16; 74411337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.maxlen = 16; 74511337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.buf = owf_buf; 74611337SWilliam.Krier@Sun.COM all_info->LogonHours.units_per_week = SAMR_HOURS_PER_WEEK; 74711337SWilliam.Krier@Sun.COM all_info->LogonHours.hours = hour_buf; 74811337SWilliam.Krier@Sun.COM 74911337SWilliam.Krier@Sun.COM param->address = 1; 75011337SWilliam.Krier@Sun.COM param->switch_index = SAMR_QUERY_USER_ALL_INFO; 75111337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 75211963SAfshin.Ardakani@Sun.COM smb_account_free(&account); 75311963SAfshin.Ardakani@Sun.COM smb_sid_free(sid); 75411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 75511337SWilliam.Krier@Sun.COM 75611337SWilliam.Krier@Sun.COM QueryUserInfoError: 75711963SAfshin.Ardakani@Sun.COM smb_sid_free(sid); 75811337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryUserInfo)); 75911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 76011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 76111337SWilliam.Krier@Sun.COM } 76211337SWilliam.Krier@Sun.COM 76311337SWilliam.Krier@Sun.COM /* 76411337SWilliam.Krier@Sun.COM * samr_s_QueryUserGroups 76511337SWilliam.Krier@Sun.COM * 76611337SWilliam.Krier@Sun.COM * Request the list of groups of which a user is a member. 76711337SWilliam.Krier@Sun.COM * The user is identified from the handle, which contains an 76811337SWilliam.Krier@Sun.COM * rid in the discriminator field. Note that this is a local user. 76911337SWilliam.Krier@Sun.COM */ 77011337SWilliam.Krier@Sun.COM static int 77111337SWilliam.Krier@Sun.COM samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa) 77211337SWilliam.Krier@Sun.COM { 77311337SWilliam.Krier@Sun.COM struct samr_QueryUserGroups *param = arg; 77411337SWilliam.Krier@Sun.COM struct samr_UserGroupInfo *info; 77511337SWilliam.Krier@Sun.COM struct samr_UserGroups *group; 77611337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->user_handle; 77711337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 77811337SWilliam.Krier@Sun.COM samr_keydata_t *data; 77911337SWilliam.Krier@Sun.COM smb_sid_t *user_sid = NULL; 78011337SWilliam.Krier@Sun.COM smb_group_t grp; 78111337SWilliam.Krier@Sun.COM smb_giter_t gi; 78211337SWilliam.Krier@Sun.COM smb_domain_t di; 78311337SWilliam.Krier@Sun.COM uint32_t status; 78411337SWilliam.Krier@Sun.COM int size; 78511337SWilliam.Krier@Sun.COM int ngrp_max; 78611337SWilliam.Krier@Sun.COM 78711337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) { 78811337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 78911337SWilliam.Krier@Sun.COM goto query_error; 79011337SWilliam.Krier@Sun.COM } 79111337SWilliam.Krier@Sun.COM 79211337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 79311337SWilliam.Krier@Sun.COM switch (data->kd_type) { 79411337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 79511337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 79611337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_type(data->kd_type, &di)) { 79711337SWilliam.Krier@Sun.COM status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 79811337SWilliam.Krier@Sun.COM goto query_error; 79911337SWilliam.Krier@Sun.COM } 80011337SWilliam.Krier@Sun.COM break; 80111337SWilliam.Krier@Sun.COM default: 80211337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 80311337SWilliam.Krier@Sun.COM goto query_error; 80411337SWilliam.Krier@Sun.COM } 80511337SWilliam.Krier@Sun.COM 80611337SWilliam.Krier@Sun.COM user_sid = smb_sid_splice(di.di_binsid, data->kd_rid); 80711337SWilliam.Krier@Sun.COM if (user_sid == NULL) { 80811337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 80911337SWilliam.Krier@Sun.COM goto query_error; 81011337SWilliam.Krier@Sun.COM } 81111337SWilliam.Krier@Sun.COM 81211337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_UserGroupInfo); 81311337SWilliam.Krier@Sun.COM if (info == NULL) { 81411337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 81511337SWilliam.Krier@Sun.COM goto query_error; 81611337SWilliam.Krier@Sun.COM } 81711337SWilliam.Krier@Sun.COM bzero(info, sizeof (struct samr_UserGroupInfo)); 81811337SWilliam.Krier@Sun.COM 81911337SWilliam.Krier@Sun.COM size = 32 * 1024; 82011337SWilliam.Krier@Sun.COM info->groups = NDR_MALLOC(mxa, size); 82111337SWilliam.Krier@Sun.COM if (info->groups == NULL) { 82211337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 82311337SWilliam.Krier@Sun.COM goto query_error; 82411337SWilliam.Krier@Sun.COM } 82511337SWilliam.Krier@Sun.COM ngrp_max = size / sizeof (struct samr_UserGroups); 82611337SWilliam.Krier@Sun.COM 82711337SWilliam.Krier@Sun.COM if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 82811337SWilliam.Krier@Sun.COM status = NT_STATUS_INTERNAL_ERROR; 82911337SWilliam.Krier@Sun.COM goto query_error; 83011337SWilliam.Krier@Sun.COM } 83111337SWilliam.Krier@Sun.COM 83211337SWilliam.Krier@Sun.COM info->n_entry = 0; 83311337SWilliam.Krier@Sun.COM group = info->groups; 83411337SWilliam.Krier@Sun.COM while ((info->n_entry < ngrp_max) && 83511337SWilliam.Krier@Sun.COM (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS)) { 83611337SWilliam.Krier@Sun.COM if (smb_lgrp_is_member(&grp, user_sid)) { 83711337SWilliam.Krier@Sun.COM group->rid = grp.sg_rid; 83811337SWilliam.Krier@Sun.COM group->attr = grp.sg_attr; 83911337SWilliam.Krier@Sun.COM group++; 84011337SWilliam.Krier@Sun.COM info->n_entry++; 84111337SWilliam.Krier@Sun.COM } 84211337SWilliam.Krier@Sun.COM smb_lgrp_free(&grp); 84311337SWilliam.Krier@Sun.COM } 84411337SWilliam.Krier@Sun.COM smb_lgrp_iterclose(&gi); 84511337SWilliam.Krier@Sun.COM 84611337SWilliam.Krier@Sun.COM free(user_sid); 84711337SWilliam.Krier@Sun.COM param->info = info; 84811337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 84911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 85011337SWilliam.Krier@Sun.COM 85111337SWilliam.Krier@Sun.COM query_error: 85211337SWilliam.Krier@Sun.COM free(user_sid); 85311337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryUserGroups)); 85411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 85511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 85611337SWilliam.Krier@Sun.COM } 85711337SWilliam.Krier@Sun.COM 85811337SWilliam.Krier@Sun.COM /* 85911337SWilliam.Krier@Sun.COM * samr_s_OpenGroup 86011337SWilliam.Krier@Sun.COM * 86111337SWilliam.Krier@Sun.COM * This is a request to open a group within the specified domain in the 86211337SWilliam.Krier@Sun.COM * local SAM database. The caller must supply a valid domain handle, 86311337SWilliam.Krier@Sun.COM * obtained via a successful domain open request. The group is 86411337SWilliam.Krier@Sun.COM * specified by the rid in the request. If this is a local RID it 86511337SWilliam.Krier@Sun.COM * should already be encoded with type information. 86611337SWilliam.Krier@Sun.COM * 86711337SWilliam.Krier@Sun.COM * We return a handle to be used to access information about this group. 86811337SWilliam.Krier@Sun.COM */ 86911337SWilliam.Krier@Sun.COM static int 87011337SWilliam.Krier@Sun.COM samr_s_OpenGroup(void *arg, ndr_xa_t *mxa) 87111337SWilliam.Krier@Sun.COM { 87211337SWilliam.Krier@Sun.COM struct samr_OpenGroup *param = arg; 87311337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 87411337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 87511337SWilliam.Krier@Sun.COM samr_keydata_t *data; 87611337SWilliam.Krier@Sun.COM 87711337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 87811337SWilliam.Krier@Sun.COM bzero(¶m->group_handle, sizeof (samr_handle_t)); 87911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 88011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 88111337SWilliam.Krier@Sun.COM } 88211337SWilliam.Krier@Sun.COM 88311337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 88411337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_GROUP, data->kd_type, param->rid); 88511337SWilliam.Krier@Sun.COM 88611337SWilliam.Krier@Sun.COM if (id) { 88711337SWilliam.Krier@Sun.COM bcopy(id, ¶m->group_handle, sizeof (samr_handle_t)); 88811337SWilliam.Krier@Sun.COM param->status = 0; 88911337SWilliam.Krier@Sun.COM } else { 89011337SWilliam.Krier@Sun.COM bzero(¶m->group_handle, sizeof (samr_handle_t)); 89111337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 89211337SWilliam.Krier@Sun.COM } 89311337SWilliam.Krier@Sun.COM 89411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 89511337SWilliam.Krier@Sun.COM } 89611337SWilliam.Krier@Sun.COM 89711337SWilliam.Krier@Sun.COM /* 89812065SKeyur.Desai@Sun.COM * samr_s_AddAliasMember 89912065SKeyur.Desai@Sun.COM * 90012065SKeyur.Desai@Sun.COM * Add a member to a local SAM group. 90112065SKeyur.Desai@Sun.COM * The caller must supply a valid group handle. 90212065SKeyur.Desai@Sun.COM * The member is specified by the sid in the request. 90312065SKeyur.Desai@Sun.COM */ 90412065SKeyur.Desai@Sun.COM static int 90512065SKeyur.Desai@Sun.COM samr_s_AddAliasMember(void *arg, ndr_xa_t *mxa) 90612065SKeyur.Desai@Sun.COM { 90712065SKeyur.Desai@Sun.COM struct samr_AddAliasMember *param = arg; 90812065SKeyur.Desai@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 90912065SKeyur.Desai@Sun.COM ndr_handle_t *hd; 91012065SKeyur.Desai@Sun.COM samr_keydata_t *data; 91112065SKeyur.Desai@Sun.COM smb_group_t grp; 91212065SKeyur.Desai@Sun.COM uint32_t rc; 91312065SKeyur.Desai@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 91412065SKeyur.Desai@Sun.COM 91512065SKeyur.Desai@Sun.COM if (param->sid == NULL) { 91612065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_AddAliasMember)); 91712065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 91812065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 91912065SKeyur.Desai@Sun.COM } 92012065SKeyur.Desai@Sun.COM 92112065SKeyur.Desai@Sun.COM if (!ndr_is_admin(mxa)) { 92212065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_AddAliasMember)); 92312065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 92412065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 92512065SKeyur.Desai@Sun.COM } 92612065SKeyur.Desai@Sun.COM 92712065SKeyur.Desai@Sun.COM 92812065SKeyur.Desai@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 92912065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_AddAliasMember)); 93012065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 93112065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 93212065SKeyur.Desai@Sun.COM } 93312065SKeyur.Desai@Sun.COM 93412065SKeyur.Desai@Sun.COM data = (samr_keydata_t *)hd->nh_data; 93512065SKeyur.Desai@Sun.COM rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp); 93612065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 93712065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_AddAliasMember)); 93812065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 93912065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 94012065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 94112065SKeyur.Desai@Sun.COM } 94212065SKeyur.Desai@Sun.COM 94312065SKeyur.Desai@Sun.COM rc = smb_lgrp_add_member(grp.sg_name, 94412065SKeyur.Desai@Sun.COM (smb_sid_t *)param->sid, SidTypeUser); 94512065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 94612065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_AddAliasMember)); 94712065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 94812065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 94912065SKeyur.Desai@Sun.COM } 95012065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 95112065SKeyur.Desai@Sun.COM 95212065SKeyur.Desai@Sun.COM param->status = status; 95312065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 95412065SKeyur.Desai@Sun.COM } 95512065SKeyur.Desai@Sun.COM 95612065SKeyur.Desai@Sun.COM /* 95712065SKeyur.Desai@Sun.COM * samr_s_DeleteAliasMember 95812065SKeyur.Desai@Sun.COM * 95912065SKeyur.Desai@Sun.COM * Delete a member from a local SAM group. 96012065SKeyur.Desai@Sun.COM * The caller must supply a valid group handle. 96112065SKeyur.Desai@Sun.COM * The member is specified by the sid in the request. 96212065SKeyur.Desai@Sun.COM */ 96312065SKeyur.Desai@Sun.COM static int 96412065SKeyur.Desai@Sun.COM samr_s_DeleteAliasMember(void *arg, ndr_xa_t *mxa) 96512065SKeyur.Desai@Sun.COM { 96612065SKeyur.Desai@Sun.COM struct samr_DeleteAliasMember *param = arg; 96712065SKeyur.Desai@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 96812065SKeyur.Desai@Sun.COM ndr_handle_t *hd; 96912065SKeyur.Desai@Sun.COM samr_keydata_t *data; 97012065SKeyur.Desai@Sun.COM smb_group_t grp; 97112065SKeyur.Desai@Sun.COM uint32_t rc; 97212065SKeyur.Desai@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 97312065SKeyur.Desai@Sun.COM 97412065SKeyur.Desai@Sun.COM if (param->sid == NULL) { 97512065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteAliasMember)); 97612065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 97712065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 97812065SKeyur.Desai@Sun.COM } 97912065SKeyur.Desai@Sun.COM 98012065SKeyur.Desai@Sun.COM if (!ndr_is_admin(mxa)) { 98112065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteAliasMember)); 98212065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 98312065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 98412065SKeyur.Desai@Sun.COM } 98512065SKeyur.Desai@Sun.COM 98612065SKeyur.Desai@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 98712065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteAliasMember)); 98812065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 98912065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 99012065SKeyur.Desai@Sun.COM } 99112065SKeyur.Desai@Sun.COM 99212065SKeyur.Desai@Sun.COM data = (samr_keydata_t *)hd->nh_data; 99312065SKeyur.Desai@Sun.COM rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp); 99412065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 99512065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteAliasMember)); 99612065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 99712065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 99812065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 99912065SKeyur.Desai@Sun.COM } 100012065SKeyur.Desai@Sun.COM 100112065SKeyur.Desai@Sun.COM rc = smb_lgrp_del_member(grp.sg_name, 100212065SKeyur.Desai@Sun.COM (smb_sid_t *)param->sid, SidTypeUser); 100312065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 100412065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteAliasMember)); 100512065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 100612065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 100712065SKeyur.Desai@Sun.COM } 100812065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 100912065SKeyur.Desai@Sun.COM 101012065SKeyur.Desai@Sun.COM param->status = status; 101112065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 101212065SKeyur.Desai@Sun.COM } 101312065SKeyur.Desai@Sun.COM 101412065SKeyur.Desai@Sun.COM /* 101512065SKeyur.Desai@Sun.COM * samr_s_ListAliasMembers 101612065SKeyur.Desai@Sun.COM * 101712065SKeyur.Desai@Sun.COM * List members from a local SAM group. 101812065SKeyur.Desai@Sun.COM * The caller must supply a valid group handle. 101912065SKeyur.Desai@Sun.COM * A list of user SIDs in the specified group is returned to the caller. 102012065SKeyur.Desai@Sun.COM */ 102112065SKeyur.Desai@Sun.COM static int 102212065SKeyur.Desai@Sun.COM samr_s_ListAliasMembers(void *arg, ndr_xa_t *mxa) 102312065SKeyur.Desai@Sun.COM { 102412065SKeyur.Desai@Sun.COM struct samr_ListAliasMembers *param = arg; 102512065SKeyur.Desai@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 102612065SKeyur.Desai@Sun.COM ndr_handle_t *hd; 102712065SKeyur.Desai@Sun.COM samr_keydata_t *data; 102812065SKeyur.Desai@Sun.COM smb_group_t grp; 102912065SKeyur.Desai@Sun.COM smb_gsid_t *members; 103012065SKeyur.Desai@Sun.COM struct samr_SidInfo info; 103112065SKeyur.Desai@Sun.COM struct samr_SidList *user; 103212065SKeyur.Desai@Sun.COM uint32_t num = 0, size; 103312065SKeyur.Desai@Sun.COM int i; 103412065SKeyur.Desai@Sun.COM uint32_t rc; 103512065SKeyur.Desai@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 103612065SKeyur.Desai@Sun.COM 103712065SKeyur.Desai@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 103812065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_ListAliasMembers)); 103912065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 104012065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 104112065SKeyur.Desai@Sun.COM } 104212065SKeyur.Desai@Sun.COM 104312065SKeyur.Desai@Sun.COM bzero(&info, sizeof (struct samr_SidInfo)); 104412065SKeyur.Desai@Sun.COM data = (samr_keydata_t *)hd->nh_data; 104512065SKeyur.Desai@Sun.COM rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp); 104612065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 104712065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_ListAliasMembers)); 104812065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 104912065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 105012065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 105112065SKeyur.Desai@Sun.COM } 105212065SKeyur.Desai@Sun.COM 105312065SKeyur.Desai@Sun.COM num = grp.sg_nmembers; 105412065SKeyur.Desai@Sun.COM members = grp.sg_members; 105512065SKeyur.Desai@Sun.COM size = num * sizeof (struct samr_SidList); 105612065SKeyur.Desai@Sun.COM info.sidlist = NDR_MALLOC(mxa, size); 105712065SKeyur.Desai@Sun.COM if (info.sidlist == NULL) { 105812065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_ListAliasMembers)); 105912065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 106012065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 106112065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 106212065SKeyur.Desai@Sun.COM } 106312065SKeyur.Desai@Sun.COM 106412065SKeyur.Desai@Sun.COM info.n_entry = num; 106512065SKeyur.Desai@Sun.COM user = info.sidlist; 106612065SKeyur.Desai@Sun.COM for (i = 0; i < num; i++) { 106712065SKeyur.Desai@Sun.COM user->sid = (struct samr_sid *)NDR_SIDDUP(mxa, 106812065SKeyur.Desai@Sun.COM members[i].gs_sid); 106912065SKeyur.Desai@Sun.COM if (user->sid == NULL) { 107012065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_ListAliasMembers)); 107112065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 107212065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 107312065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 107412065SKeyur.Desai@Sun.COM } 107512065SKeyur.Desai@Sun.COM user++; 107612065SKeyur.Desai@Sun.COM } 107712065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 107812065SKeyur.Desai@Sun.COM 107912065SKeyur.Desai@Sun.COM param->info = info; 108012065SKeyur.Desai@Sun.COM param->status = status; 108112065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 108212065SKeyur.Desai@Sun.COM } 108312065SKeyur.Desai@Sun.COM 108412065SKeyur.Desai@Sun.COM /* 108511337SWilliam.Krier@Sun.COM * samr_s_Connect 108611337SWilliam.Krier@Sun.COM * 108711337SWilliam.Krier@Sun.COM * This is a request to connect to the local SAM database. 108811337SWilliam.Krier@Sun.COM * We don't support any form of update request and our database doesn't 108911337SWilliam.Krier@Sun.COM * contain any private information, so there is little point in doing 109011337SWilliam.Krier@Sun.COM * any access access checking here. 109111337SWilliam.Krier@Sun.COM * 109211337SWilliam.Krier@Sun.COM * Return a handle for use with subsequent SAM requests. 109311337SWilliam.Krier@Sun.COM */ 109411337SWilliam.Krier@Sun.COM static int 109511337SWilliam.Krier@Sun.COM samr_s_Connect(void *arg, ndr_xa_t *mxa) 109611337SWilliam.Krier@Sun.COM { 109711337SWilliam.Krier@Sun.COM struct samr_Connect *param = arg; 109811337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 109911337SWilliam.Krier@Sun.COM 110011337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 110111337SWilliam.Krier@Sun.COM if (id) { 110211337SWilliam.Krier@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 110311337SWilliam.Krier@Sun.COM param->status = 0; 110411337SWilliam.Krier@Sun.COM } else { 110511337SWilliam.Krier@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 110611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 110711337SWilliam.Krier@Sun.COM } 110811337SWilliam.Krier@Sun.COM 110911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 111011337SWilliam.Krier@Sun.COM } 111111337SWilliam.Krier@Sun.COM 111211337SWilliam.Krier@Sun.COM /* 111311337SWilliam.Krier@Sun.COM * samr_s_GetUserPwInfo 111411337SWilliam.Krier@Sun.COM * 111511447Samw@Sun.COM * Request for a user's password policy information. 111611337SWilliam.Krier@Sun.COM */ 111711337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 111811337SWilliam.Krier@Sun.COM static int 111911337SWilliam.Krier@Sun.COM samr_s_GetUserPwInfo(void *arg, ndr_xa_t *mxa) 112011337SWilliam.Krier@Sun.COM { 112111447Samw@Sun.COM static samr_password_info_t pwinfo; 112211447Samw@Sun.COM struct samr_GetUserPwInfo *param = arg; 112311337SWilliam.Krier@Sun.COM 112411447Samw@Sun.COM param->pwinfo = &pwinfo; 112511447Samw@Sun.COM param->status = NT_STATUS_SUCCESS; 112611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 112711337SWilliam.Krier@Sun.COM } 112811337SWilliam.Krier@Sun.COM 112911337SWilliam.Krier@Sun.COM /* 113011337SWilliam.Krier@Sun.COM * samr_s_CreateUser 113111337SWilliam.Krier@Sun.COM */ 113211337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 113311337SWilliam.Krier@Sun.COM static int 113411337SWilliam.Krier@Sun.COM samr_s_CreateUser(void *arg, ndr_xa_t *mxa) 113511337SWilliam.Krier@Sun.COM { 113611337SWilliam.Krier@Sun.COM struct samr_CreateUser *param = arg; 113711337SWilliam.Krier@Sun.COM 113811337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 113911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 114011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 114111337SWilliam.Krier@Sun.COM } 114211337SWilliam.Krier@Sun.COM 114311337SWilliam.Krier@Sun.COM /* 114411337SWilliam.Krier@Sun.COM * samr_s_ChangeUserPasswd 114511337SWilliam.Krier@Sun.COM */ 114611337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 114711337SWilliam.Krier@Sun.COM static int 114811337SWilliam.Krier@Sun.COM samr_s_ChangeUserPasswd(void *arg, ndr_xa_t *mxa) 114911337SWilliam.Krier@Sun.COM { 115011337SWilliam.Krier@Sun.COM struct samr_ChangeUserPasswd *param = arg; 115111337SWilliam.Krier@Sun.COM 115211337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_ChangeUserPasswd)); 115311337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 115411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 115511337SWilliam.Krier@Sun.COM } 115611337SWilliam.Krier@Sun.COM 115711337SWilliam.Krier@Sun.COM /* 115811337SWilliam.Krier@Sun.COM * samr_s_GetDomainPwInfo 115911447Samw@Sun.COM * 116011447Samw@Sun.COM * Request for the domain password policy information. 116111337SWilliam.Krier@Sun.COM */ 116211337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 116311337SWilliam.Krier@Sun.COM static int 116411337SWilliam.Krier@Sun.COM samr_s_GetDomainPwInfo(void *arg, ndr_xa_t *mxa) 116511337SWilliam.Krier@Sun.COM { 116611447Samw@Sun.COM static samr_password_info_t pwinfo; 116711447Samw@Sun.COM struct samr_GetDomainPwInfo *param = arg; 116811337SWilliam.Krier@Sun.COM 116911447Samw@Sun.COM param->pwinfo = &pwinfo; 117011447Samw@Sun.COM param->status = NT_STATUS_SUCCESS; 117111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 117211337SWilliam.Krier@Sun.COM } 117311337SWilliam.Krier@Sun.COM 117411337SWilliam.Krier@Sun.COM /* 117511337SWilliam.Krier@Sun.COM * samr_s_SetUserInfo 117611337SWilliam.Krier@Sun.COM */ 117711337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 117811337SWilliam.Krier@Sun.COM static int 117911337SWilliam.Krier@Sun.COM samr_s_SetUserInfo(void *arg, ndr_xa_t *mxa) 118011337SWilliam.Krier@Sun.COM { 118111337SWilliam.Krier@Sun.COM struct samr_SetUserInfo *param = arg; 118211337SWilliam.Krier@Sun.COM 118311337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_SetUserInfo)); 118411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 118511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 118611337SWilliam.Krier@Sun.COM } 118711337SWilliam.Krier@Sun.COM 118811337SWilliam.Krier@Sun.COM /* 118911337SWilliam.Krier@Sun.COM * samr_s_QueryDispInfo 119011337SWilliam.Krier@Sun.COM * 119111337SWilliam.Krier@Sun.COM * This function currently return local users' information only. 119211337SWilliam.Krier@Sun.COM * This RPC is called repeatedly until all the users info are 119311337SWilliam.Krier@Sun.COM * retrieved. 119411337SWilliam.Krier@Sun.COM * 119511337SWilliam.Krier@Sun.COM * The total count and the returned count are returned as total size 119611337SWilliam.Krier@Sun.COM * and returned size. The client doesn't seem to care. 119711337SWilliam.Krier@Sun.COM */ 119811337SWilliam.Krier@Sun.COM static int 119911337SWilliam.Krier@Sun.COM samr_s_QueryDispInfo(void *arg, ndr_xa_t *mxa) 120011337SWilliam.Krier@Sun.COM { 120111337SWilliam.Krier@Sun.COM struct samr_QueryDispInfo *param = arg; 120211337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 120311337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 120411337SWilliam.Krier@Sun.COM samr_keydata_t *data; 120511337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 120611337SWilliam.Krier@Sun.COM struct user_acct_info *user; 120711337SWilliam.Krier@Sun.COM smb_pwditer_t pwi; 120811337SWilliam.Krier@Sun.COM smb_luser_t *uinfo; 120911337SWilliam.Krier@Sun.COM int num_users; 121011337SWilliam.Krier@Sun.COM int start_idx; 121111337SWilliam.Krier@Sun.COM int max_retcnt, retcnt; 121211337SWilliam.Krier@Sun.COM int skip; 121311337SWilliam.Krier@Sun.COM 121411337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 121511337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 121611337SWilliam.Krier@Sun.COM goto error; 121711337SWilliam.Krier@Sun.COM } 121811337SWilliam.Krier@Sun.COM 121911337SWilliam.Krier@Sun.COM if (!SAMR_VALID_DISPLEVEL(param->level)) { 122011337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_INFO_CLASS; 122111337SWilliam.Krier@Sun.COM goto error; 122211337SWilliam.Krier@Sun.COM } 122311337SWilliam.Krier@Sun.COM 122411337SWilliam.Krier@Sun.COM if (!SAMR_SUPPORTED_DISPLEVEL(param->level)) { 122511337SWilliam.Krier@Sun.COM status = NT_STATUS_NOT_IMPLEMENTED; 122611337SWilliam.Krier@Sun.COM goto error; 122711337SWilliam.Krier@Sun.COM } 122811337SWilliam.Krier@Sun.COM 122911337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 123011337SWilliam.Krier@Sun.COM 123111337SWilliam.Krier@Sun.COM switch (data->kd_type) { 123211337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 123311337SWilliam.Krier@Sun.COM goto no_info; 123411337SWilliam.Krier@Sun.COM 123511337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 123611337SWilliam.Krier@Sun.COM num_users = smb_sam_usr_cnt(); 123711337SWilliam.Krier@Sun.COM start_idx = param->start_idx; 123811337SWilliam.Krier@Sun.COM if ((num_users == 0) || (start_idx >= num_users)) 123911337SWilliam.Krier@Sun.COM goto no_info; 124011337SWilliam.Krier@Sun.COM 124111337SWilliam.Krier@Sun.COM max_retcnt = num_users - start_idx; 124211337SWilliam.Krier@Sun.COM if (max_retcnt > param->max_entries) 124311337SWilliam.Krier@Sun.COM max_retcnt = param->max_entries; 124411337SWilliam.Krier@Sun.COM param->users.acct = NDR_MALLOC(mxa, 124511337SWilliam.Krier@Sun.COM max_retcnt * sizeof (struct user_acct_info)); 124611337SWilliam.Krier@Sun.COM user = param->users.acct; 124711337SWilliam.Krier@Sun.COM if (user == NULL) { 124811337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 124911337SWilliam.Krier@Sun.COM goto error; 125011337SWilliam.Krier@Sun.COM } 125111337SWilliam.Krier@Sun.COM bzero(user, max_retcnt * sizeof (struct user_acct_info)); 125211337SWilliam.Krier@Sun.COM 125311337SWilliam.Krier@Sun.COM if (smb_pwd_iteropen(&pwi) != SMB_PWE_SUCCESS) 125411337SWilliam.Krier@Sun.COM goto no_info; 125511337SWilliam.Krier@Sun.COM 125611337SWilliam.Krier@Sun.COM skip = retcnt = 0; 125711337SWilliam.Krier@Sun.COM while ((uinfo = smb_pwd_iterate(&pwi)) != NULL) { 125811337SWilliam.Krier@Sun.COM if (skip++ < start_idx) 125911337SWilliam.Krier@Sun.COM continue; 126011337SWilliam.Krier@Sun.COM 126111337SWilliam.Krier@Sun.COM if (retcnt++ >= max_retcnt) 126211337SWilliam.Krier@Sun.COM break; 126311337SWilliam.Krier@Sun.COM 126411337SWilliam.Krier@Sun.COM assert(uinfo->su_name != NULL); 126511337SWilliam.Krier@Sun.COM 126611337SWilliam.Krier@Sun.COM user->index = start_idx + retcnt; 126711337SWilliam.Krier@Sun.COM user->rid = uinfo->su_rid; 126811337SWilliam.Krier@Sun.COM user->ctrl = ACF_NORMUSER | ACF_PWDNOEXP; 126911337SWilliam.Krier@Sun.COM if (uinfo->su_ctrl & SMB_PWF_DISABLE) 127011337SWilliam.Krier@Sun.COM user->ctrl |= ACF_DISABLED; 127111337SWilliam.Krier@Sun.COM if (NDR_MSTRING(mxa, uinfo->su_name, 127211337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->name) == -1) { 127311337SWilliam.Krier@Sun.COM smb_pwd_iterclose(&pwi); 127411337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 127511337SWilliam.Krier@Sun.COM goto error; 127611337SWilliam.Krier@Sun.COM } 127711337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, uinfo->su_fullname, 127811337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->fullname); 127911337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, uinfo->su_desc, 128011337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->desc); 128111337SWilliam.Krier@Sun.COM user++; 128211337SWilliam.Krier@Sun.COM } 128311337SWilliam.Krier@Sun.COM smb_pwd_iterclose(&pwi); 128411337SWilliam.Krier@Sun.COM 128511337SWilliam.Krier@Sun.COM if (retcnt >= max_retcnt) { 128611337SWilliam.Krier@Sun.COM retcnt = max_retcnt; 128711337SWilliam.Krier@Sun.COM param->status = status; 128811337SWilliam.Krier@Sun.COM } else { 1289*12508Samw@Sun.COM param->status = NT_STATUS_MORE_ENTRIES; 129011337SWilliam.Krier@Sun.COM } 129111337SWilliam.Krier@Sun.COM 129211337SWilliam.Krier@Sun.COM param->users.total_size = num_users; 129311337SWilliam.Krier@Sun.COM param->users.returned_size = retcnt; 129411337SWilliam.Krier@Sun.COM param->users.switch_value = param->level; 129511337SWilliam.Krier@Sun.COM param->users.count = retcnt; 129611337SWilliam.Krier@Sun.COM 129711337SWilliam.Krier@Sun.COM break; 129811337SWilliam.Krier@Sun.COM 129911337SWilliam.Krier@Sun.COM default: 130011337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 130111337SWilliam.Krier@Sun.COM goto error; 130211337SWilliam.Krier@Sun.COM } 130311337SWilliam.Krier@Sun.COM 130411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 130511337SWilliam.Krier@Sun.COM 130611337SWilliam.Krier@Sun.COM no_info: 130711337SWilliam.Krier@Sun.COM param->users.total_size = 0; 130811337SWilliam.Krier@Sun.COM param->users.returned_size = 0; 130911337SWilliam.Krier@Sun.COM param->users.switch_value = param->level; 131011337SWilliam.Krier@Sun.COM param->users.count = 0; 131111337SWilliam.Krier@Sun.COM param->users.acct = NULL; 131211337SWilliam.Krier@Sun.COM param->status = status; 131311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 131411337SWilliam.Krier@Sun.COM 131511337SWilliam.Krier@Sun.COM error: 131611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDispInfo)); 131711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 131811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 131911337SWilliam.Krier@Sun.COM } 132011337SWilliam.Krier@Sun.COM 132111337SWilliam.Krier@Sun.COM /* 132211337SWilliam.Krier@Sun.COM * samr_s_EnumDomainGroups 132311337SWilliam.Krier@Sun.COM * 132411337SWilliam.Krier@Sun.COM * 132511337SWilliam.Krier@Sun.COM * This function is supposed to return local group information. 132611337SWilliam.Krier@Sun.COM * As we don't support local users, this function dosen't send 132711337SWilliam.Krier@Sun.COM * back any information. 132811337SWilliam.Krier@Sun.COM * 132911337SWilliam.Krier@Sun.COM * Added template that returns information for a domain group as None. 133011337SWilliam.Krier@Sun.COM * All information is hard-coded from packet captures. 133111337SWilliam.Krier@Sun.COM */ 133211337SWilliam.Krier@Sun.COM static int 133311337SWilliam.Krier@Sun.COM samr_s_EnumDomainGroups(void *arg, ndr_xa_t *mxa) 133411337SWilliam.Krier@Sun.COM { 133511337SWilliam.Krier@Sun.COM struct samr_EnumDomainGroups *param = arg; 133611337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 133711337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 133811337SWilliam.Krier@Sun.COM 133911337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) 134011337SWilliam.Krier@Sun.COM status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 134111337SWilliam.Krier@Sun.COM 134211337SWilliam.Krier@Sun.COM param->total_size = 0; 134311337SWilliam.Krier@Sun.COM param->returned_size = 0; 134411337SWilliam.Krier@Sun.COM param->switch_value = 3; 134511337SWilliam.Krier@Sun.COM param->count = 0; 134611337SWilliam.Krier@Sun.COM param->groups = 0; 134711337SWilliam.Krier@Sun.COM param->status = status; 134811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 134911337SWilliam.Krier@Sun.COM 135011337SWilliam.Krier@Sun.COM #ifdef SAMR_SUPPORT_GROUPS 135111337SWilliam.Krier@Sun.COM if ((desc->discrim != SAMR_LOCAL_DOMAIN) || (param->start_idx != 0)) { 135211337SWilliam.Krier@Sun.COM param->total_size = 0; 135311337SWilliam.Krier@Sun.COM param->returned_size = 0; 135411337SWilliam.Krier@Sun.COM param->switch_value = 3; 135511337SWilliam.Krier@Sun.COM param->count = 0; 135611337SWilliam.Krier@Sun.COM param->groups = 0; 135711337SWilliam.Krier@Sun.COM } else { 135811337SWilliam.Krier@Sun.COM param->total_size = 64; 135911337SWilliam.Krier@Sun.COM param->returned_size = 64; 136011337SWilliam.Krier@Sun.COM param->switch_value = 3; 136111337SWilliam.Krier@Sun.COM param->count = 1; 136211337SWilliam.Krier@Sun.COM param->groups = (struct group_disp_info *)NDR_MALLOC( 136311337SWilliam.Krier@Sun.COM mxa, sizeof (struct group_disp_info)); 136411337SWilliam.Krier@Sun.COM 136511337SWilliam.Krier@Sun.COM param->groups->count = 1; 136611337SWilliam.Krier@Sun.COM param->groups->acct[0].index = 1; 136711337SWilliam.Krier@Sun.COM param->groups->acct[0].rid = 513; 136811337SWilliam.Krier@Sun.COM param->groups->acct[0].ctrl = 0x7; 136911337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "None", 137011337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->groups->acct[0].name); 137111337SWilliam.Krier@Sun.COM 137211337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "Ordinary users", 137311337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->groups->acct[0].desc); 137411337SWilliam.Krier@Sun.COM } 137511337SWilliam.Krier@Sun.COM 137611337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 137711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 137811337SWilliam.Krier@Sun.COM #endif 137911337SWilliam.Krier@Sun.COM } 138011337SWilliam.Krier@Sun.COM 138111337SWilliam.Krier@Sun.COM /* 138211337SWilliam.Krier@Sun.COM * samr_s_OpenAlias 138311337SWilliam.Krier@Sun.COM * 138411337SWilliam.Krier@Sun.COM * Lookup for requested alias, if it exists return a handle 138511337SWilliam.Krier@Sun.COM * for that alias. The alias domain sid should match with 138611337SWilliam.Krier@Sun.COM * the passed domain handle. 138711337SWilliam.Krier@Sun.COM */ 138811337SWilliam.Krier@Sun.COM static int 138911337SWilliam.Krier@Sun.COM samr_s_OpenAlias(void *arg, ndr_xa_t *mxa) 139011337SWilliam.Krier@Sun.COM { 139111337SWilliam.Krier@Sun.COM struct samr_OpenAlias *param = arg; 139211447Samw@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 139311447Samw@Sun.COM ndr_handle_t *hd; 139411447Samw@Sun.COM samr_keydata_t *data; 139511963SAfshin.Ardakani@Sun.COM smb_domain_type_t gd_type; 139611447Samw@Sun.COM smb_sid_t *sid; 139711447Samw@Sun.COM smb_wka_t *wka; 139811447Samw@Sun.COM char sidstr[SMB_SID_STRSZ]; 139911447Samw@Sun.COM uint32_t rid; 140011447Samw@Sun.COM uint32_t status; 140111447Samw@Sun.COM int rc; 140211337SWilliam.Krier@Sun.COM 140311337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 140411337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 140511337SWilliam.Krier@Sun.COM goto open_alias_err; 140611337SWilliam.Krier@Sun.COM } 140711337SWilliam.Krier@Sun.COM 140812065SKeyur.Desai@Sun.COM if ((param->access_mask & SAMR_ALIAS_ACCESS_ALL_ACCESS) == 0) { 140911337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 141011337SWilliam.Krier@Sun.COM goto open_alias_err; 141111337SWilliam.Krier@Sun.COM } 141211337SWilliam.Krier@Sun.COM 141311337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 141411963SAfshin.Ardakani@Sun.COM gd_type = (smb_domain_type_t)data->kd_type; 141511447Samw@Sun.COM rid = param->rid; 141611447Samw@Sun.COM 141711447Samw@Sun.COM switch (gd_type) { 141811963SAfshin.Ardakani@Sun.COM case SMB_DOMAIN_BUILTIN: 141911447Samw@Sun.COM (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d", 142011447Samw@Sun.COM NT_BUILTIN_DOMAIN_SIDSTR, rid); 142111447Samw@Sun.COM if ((sid = smb_sid_fromstr(sidstr)) == NULL) { 142211447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 142311447Samw@Sun.COM goto open_alias_err; 142411447Samw@Sun.COM } 142511447Samw@Sun.COM 142611447Samw@Sun.COM wka = smb_wka_lookup_sid(sid); 142711447Samw@Sun.COM smb_sid_free(sid); 142811447Samw@Sun.COM 142911447Samw@Sun.COM if (wka == NULL) { 143011447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 143111447Samw@Sun.COM goto open_alias_err; 143211447Samw@Sun.COM } 143311447Samw@Sun.COM break; 143411447Samw@Sun.COM 143511963SAfshin.Ardakani@Sun.COM case SMB_DOMAIN_LOCAL: 143611447Samw@Sun.COM rc = smb_lgrp_getbyrid(rid, gd_type, NULL); 143711447Samw@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 143811447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 143911447Samw@Sun.COM goto open_alias_err; 144011447Samw@Sun.COM } 144111447Samw@Sun.COM break; 144211447Samw@Sun.COM 144311447Samw@Sun.COM default: 144411337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 144511337SWilliam.Krier@Sun.COM goto open_alias_err; 144611337SWilliam.Krier@Sun.COM } 144711337SWilliam.Krier@Sun.COM 144811337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, data->kd_type, param->rid); 144911337SWilliam.Krier@Sun.COM if (id) { 145011337SWilliam.Krier@Sun.COM bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t)); 145111337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 145211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 145311337SWilliam.Krier@Sun.COM } 145411337SWilliam.Krier@Sun.COM 145511337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 145611337SWilliam.Krier@Sun.COM 145711337SWilliam.Krier@Sun.COM open_alias_err: 145811337SWilliam.Krier@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 145911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 146011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 146111337SWilliam.Krier@Sun.COM } 146211337SWilliam.Krier@Sun.COM 146311337SWilliam.Krier@Sun.COM /* 146411337SWilliam.Krier@Sun.COM * samr_s_CreateDomainAlias 146511337SWilliam.Krier@Sun.COM * 146612065SKeyur.Desai@Sun.COM * Create a local group in the security accounts manager (SAM) database. 146712065SKeyur.Desai@Sun.COM * A local SAM group can only be added if a Solaris group already exists 146812065SKeyur.Desai@Sun.COM * with the same name. On success, a valid group handle is returned. 146912065SKeyur.Desai@Sun.COM * 147012065SKeyur.Desai@Sun.COM * The caller must have administrator rights to execute this function. 147111337SWilliam.Krier@Sun.COM */ 147211337SWilliam.Krier@Sun.COM static int 147311337SWilliam.Krier@Sun.COM samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa) 147411337SWilliam.Krier@Sun.COM { 147511337SWilliam.Krier@Sun.COM struct samr_CreateDomainAlias *param = arg; 147611337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 147712065SKeyur.Desai@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 147812065SKeyur.Desai@Sun.COM smb_group_t grp; 147912065SKeyur.Desai@Sun.COM uint32_t rc; 148012065SKeyur.Desai@Sun.COM char *gname; 148111337SWilliam.Krier@Sun.COM 148212065SKeyur.Desai@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) != NULL) { 148311337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_CreateDomainAlias)); 148411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 148511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 148611337SWilliam.Krier@Sun.COM } 148711337SWilliam.Krier@Sun.COM 148812065SKeyur.Desai@Sun.COM gname = (char *)param->alias_name.str; 148912065SKeyur.Desai@Sun.COM if (gname == NULL) { 149012065SKeyur.Desai@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 149112065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 149212065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 149312065SKeyur.Desai@Sun.COM } 149411337SWilliam.Krier@Sun.COM 149512065SKeyur.Desai@Sun.COM if ((!ndr_is_admin(mxa)) || 149612065SKeyur.Desai@Sun.COM ((param->access_mask & SAMR_ALIAS_ACCESS_WRITE_ACCOUNT) == 0)) { 149712065SKeyur.Desai@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 149812065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 149912065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 150012065SKeyur.Desai@Sun.COM } 150111337SWilliam.Krier@Sun.COM 150212065SKeyur.Desai@Sun.COM rc = smb_lgrp_add(gname, ""); 150312065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 150412065SKeyur.Desai@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 150512065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 150612065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 150712065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 150811337SWilliam.Krier@Sun.COM } 150911337SWilliam.Krier@Sun.COM 151012065SKeyur.Desai@Sun.COM rc = smb_lgrp_getbyname((char *)gname, &grp); 151112065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 151212065SKeyur.Desai@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 151312065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 151412065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 151512065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 151612065SKeyur.Desai@Sun.COM } 151711337SWilliam.Krier@Sun.COM 151812065SKeyur.Desai@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, SMB_DOMAIN_LOCAL, grp.sg_rid); 151912065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 152012065SKeyur.Desai@Sun.COM if (id) { 152112065SKeyur.Desai@Sun.COM bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t)); 152212065SKeyur.Desai@Sun.COM param->status = status; 152312065SKeyur.Desai@Sun.COM } else { 152412065SKeyur.Desai@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 152512065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 152612065SKeyur.Desai@Sun.COM } 152711337SWilliam.Krier@Sun.COM 152811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 152911337SWilliam.Krier@Sun.COM } 153011337SWilliam.Krier@Sun.COM 153111337SWilliam.Krier@Sun.COM /* 153211337SWilliam.Krier@Sun.COM * samr_s_SetAliasInfo 153311337SWilliam.Krier@Sun.COM * 153411337SWilliam.Krier@Sun.COM * Similar to NetLocalGroupSetInfo. 153511337SWilliam.Krier@Sun.COM */ 153611337SWilliam.Krier@Sun.COM static int 153711337SWilliam.Krier@Sun.COM samr_s_SetAliasInfo(void *arg, ndr_xa_t *mxa) 153811337SWilliam.Krier@Sun.COM { 153911337SWilliam.Krier@Sun.COM struct samr_SetAliasInfo *param = arg; 154011337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 154111337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 154211337SWilliam.Krier@Sun.COM 154311337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) 154411337SWilliam.Krier@Sun.COM status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 154511337SWilliam.Krier@Sun.COM 154611337SWilliam.Krier@Sun.COM param->status = status; 154711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 154811337SWilliam.Krier@Sun.COM } 154911337SWilliam.Krier@Sun.COM 155011337SWilliam.Krier@Sun.COM /* 155111337SWilliam.Krier@Sun.COM * samr_s_QueryAliasInfo 155211337SWilliam.Krier@Sun.COM * 155311337SWilliam.Krier@Sun.COM * Retrieves information about the specified local group account 155411337SWilliam.Krier@Sun.COM * by given handle. 155511337SWilliam.Krier@Sun.COM */ 155611337SWilliam.Krier@Sun.COM static int 155711337SWilliam.Krier@Sun.COM samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa) 155811337SWilliam.Krier@Sun.COM { 155911337SWilliam.Krier@Sun.COM struct samr_QueryAliasInfo *param = arg; 156011447Samw@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 156111447Samw@Sun.COM ndr_handle_t *hd; 156211447Samw@Sun.COM samr_keydata_t *data; 156311447Samw@Sun.COM smb_group_t grp; 156411963SAfshin.Ardakani@Sun.COM smb_domain_type_t gd_type; 156511447Samw@Sun.COM smb_sid_t *sid; 156611447Samw@Sun.COM smb_wka_t *wka; 156711447Samw@Sun.COM char sidstr[SMB_SID_STRSZ]; 156811447Samw@Sun.COM char *name; 156911447Samw@Sun.COM char *desc; 157011447Samw@Sun.COM uint32_t rid; 157111447Samw@Sun.COM uint32_t status; 157211447Samw@Sun.COM int rc; 157311337SWilliam.Krier@Sun.COM 157411337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 157511337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 157611337SWilliam.Krier@Sun.COM goto query_alias_err; 157711337SWilliam.Krier@Sun.COM } 157811337SWilliam.Krier@Sun.COM 157911337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 158011963SAfshin.Ardakani@Sun.COM gd_type = (smb_domain_type_t)data->kd_type; 158111447Samw@Sun.COM rid = data->kd_rid; 158211447Samw@Sun.COM 158311447Samw@Sun.COM switch (gd_type) { 158411963SAfshin.Ardakani@Sun.COM case SMB_DOMAIN_BUILTIN: 158511447Samw@Sun.COM (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d", 158611447Samw@Sun.COM NT_BUILTIN_DOMAIN_SIDSTR, rid); 158711447Samw@Sun.COM if ((sid = smb_sid_fromstr(sidstr)) == NULL) { 158811447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 158911447Samw@Sun.COM goto query_alias_err; 159011447Samw@Sun.COM } 159111447Samw@Sun.COM 159211447Samw@Sun.COM wka = smb_wka_lookup_sid(sid); 159311447Samw@Sun.COM smb_sid_free(sid); 159411447Samw@Sun.COM 159511447Samw@Sun.COM if (wka == NULL) { 159611447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 159711447Samw@Sun.COM goto query_alias_err; 159811447Samw@Sun.COM } 159911447Samw@Sun.COM 160011447Samw@Sun.COM name = wka->wka_name; 160111447Samw@Sun.COM desc = (wka->wka_desc != NULL) ? wka->wka_desc : ""; 160211447Samw@Sun.COM break; 160311447Samw@Sun.COM 160411963SAfshin.Ardakani@Sun.COM case SMB_DOMAIN_LOCAL: 160511447Samw@Sun.COM rc = smb_lgrp_getbyrid(rid, gd_type, &grp); 160611447Samw@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 160711447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 160811447Samw@Sun.COM goto query_alias_err; 160911447Samw@Sun.COM } 161011447Samw@Sun.COM name = grp.sg_name; 161111447Samw@Sun.COM desc = grp.sg_cmnt; 161211447Samw@Sun.COM break; 161311447Samw@Sun.COM 161411447Samw@Sun.COM default: 161511337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 161611337SWilliam.Krier@Sun.COM goto query_alias_err; 161711337SWilliam.Krier@Sun.COM } 161811337SWilliam.Krier@Sun.COM 161911337SWilliam.Krier@Sun.COM switch (param->level) { 162011337SWilliam.Krier@Sun.COM case SAMR_QUERY_ALIAS_INFO_1: 162111337SWilliam.Krier@Sun.COM param->ru.info1.level = param->level; 162211447Samw@Sun.COM (void) NDR_MSTRING(mxa, name, 162311337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info1.name); 162411337SWilliam.Krier@Sun.COM 162511447Samw@Sun.COM (void) NDR_MSTRING(mxa, desc, 162611337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info1.desc); 162711337SWilliam.Krier@Sun.COM 162811337SWilliam.Krier@Sun.COM param->ru.info1.unknown = 1; 162911337SWilliam.Krier@Sun.COM break; 163011337SWilliam.Krier@Sun.COM 163111337SWilliam.Krier@Sun.COM case SAMR_QUERY_ALIAS_INFO_3: 163211337SWilliam.Krier@Sun.COM param->ru.info3.level = param->level; 163311447Samw@Sun.COM (void) NDR_MSTRING(mxa, desc, 163411337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info3.desc); 163511337SWilliam.Krier@Sun.COM break; 163611337SWilliam.Krier@Sun.COM 163711337SWilliam.Krier@Sun.COM default: 163811963SAfshin.Ardakani@Sun.COM if (gd_type == SMB_DOMAIN_LOCAL) 163911447Samw@Sun.COM smb_lgrp_free(&grp); 164011337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_INFO_CLASS; 164111337SWilliam.Krier@Sun.COM goto query_alias_err; 164211337SWilliam.Krier@Sun.COM }; 164311337SWilliam.Krier@Sun.COM 164411963SAfshin.Ardakani@Sun.COM if (gd_type == SMB_DOMAIN_LOCAL) 164511447Samw@Sun.COM smb_lgrp_free(&grp); 164611337SWilliam.Krier@Sun.COM param->address = (DWORD)(uintptr_t)¶m->ru; 164711337SWilliam.Krier@Sun.COM param->status = 0; 164811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 164911337SWilliam.Krier@Sun.COM 165011337SWilliam.Krier@Sun.COM query_alias_err: 165111337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 165211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 165311337SWilliam.Krier@Sun.COM } 165411337SWilliam.Krier@Sun.COM 165511337SWilliam.Krier@Sun.COM /* 165611337SWilliam.Krier@Sun.COM * samr_s_DeleteDomainAlias 165711337SWilliam.Krier@Sun.COM * 165812065SKeyur.Desai@Sun.COM * Deletes a local group in the security database, which is the 165912065SKeyur.Desai@Sun.COM * security accounts manager (SAM). A valid group handle is returned 166012065SKeyur.Desai@Sun.COM * to the caller upon success. 166111337SWilliam.Krier@Sun.COM * 166212065SKeyur.Desai@Sun.COM * The caller must have administrator rights to execute this function. 166311337SWilliam.Krier@Sun.COM */ 166411337SWilliam.Krier@Sun.COM static int 166511337SWilliam.Krier@Sun.COM samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa) 166611337SWilliam.Krier@Sun.COM { 166711337SWilliam.Krier@Sun.COM struct samr_DeleteDomainAlias *param = arg; 166811337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 166912065SKeyur.Desai@Sun.COM ndr_handle_t *hd; 167012065SKeyur.Desai@Sun.COM smb_group_t grp; 167112065SKeyur.Desai@Sun.COM samr_keydata_t *data; 167212065SKeyur.Desai@Sun.COM smb_domain_type_t gd_type; 167312065SKeyur.Desai@Sun.COM uint32_t rid; 167412065SKeyur.Desai@Sun.COM uint32_t rc; 167512065SKeyur.Desai@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 167611337SWilliam.Krier@Sun.COM 167712065SKeyur.Desai@Sun.COM if (!ndr_is_admin(mxa)) { 167812065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 167912065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 168012065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 168112065SKeyur.Desai@Sun.COM } 168212065SKeyur.Desai@Sun.COM 168312065SKeyur.Desai@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 168411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 168511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 168611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 168711337SWilliam.Krier@Sun.COM } 168811337SWilliam.Krier@Sun.COM 168912065SKeyur.Desai@Sun.COM data = (samr_keydata_t *)hd->nh_data; 169012065SKeyur.Desai@Sun.COM gd_type = (smb_domain_type_t)data->kd_type; 169112065SKeyur.Desai@Sun.COM rid = data->kd_rid; 169212065SKeyur.Desai@Sun.COM 169312065SKeyur.Desai@Sun.COM switch (gd_type) { 169412065SKeyur.Desai@Sun.COM case SMB_DOMAIN_BUILTIN: 169512065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 169612065SKeyur.Desai@Sun.COM status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED); 169712065SKeyur.Desai@Sun.COM break; 169811337SWilliam.Krier@Sun.COM 169912065SKeyur.Desai@Sun.COM case SMB_DOMAIN_LOCAL: 170012065SKeyur.Desai@Sun.COM rc = smb_lgrp_getbyrid(rid, gd_type, &grp); 170112065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 170212065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 170312065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 170412065SKeyur.Desai@Sun.COM status = NT_SC_ERROR(status); 170512065SKeyur.Desai@Sun.COM break; 170612065SKeyur.Desai@Sun.COM } 170711337SWilliam.Krier@Sun.COM 170812065SKeyur.Desai@Sun.COM rc = smb_lgrp_delete(grp.sg_name); 170912065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 171012065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 171112065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 171212065SKeyur.Desai@Sun.COM status = NT_SC_ERROR(status); 171312065SKeyur.Desai@Sun.COM } 171412065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 171512065SKeyur.Desai@Sun.COM break; 171612065SKeyur.Desai@Sun.COM 171712065SKeyur.Desai@Sun.COM default: 171812065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 171912065SKeyur.Desai@Sun.COM status = NT_SC_ERROR(NT_STATUS_NO_SUCH_ALIAS); 172011337SWilliam.Krier@Sun.COM } 172111337SWilliam.Krier@Sun.COM 172212065SKeyur.Desai@Sun.COM param->status = status; 172311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 172411337SWilliam.Krier@Sun.COM } 172511337SWilliam.Krier@Sun.COM 172611337SWilliam.Krier@Sun.COM /* 172711337SWilliam.Krier@Sun.COM * samr_s_EnumDomainAliases 172811337SWilliam.Krier@Sun.COM * 172911337SWilliam.Krier@Sun.COM * This function sends back a list which contains all local groups' name. 173011337SWilliam.Krier@Sun.COM */ 173111337SWilliam.Krier@Sun.COM static int 173211337SWilliam.Krier@Sun.COM samr_s_EnumDomainAliases(void *arg, ndr_xa_t *mxa) 173311337SWilliam.Krier@Sun.COM { 173411337SWilliam.Krier@Sun.COM struct samr_EnumDomainAliases *param = arg; 173511337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 173611337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 173711337SWilliam.Krier@Sun.COM samr_keydata_t *data; 173811337SWilliam.Krier@Sun.COM smb_group_t grp; 173911337SWilliam.Krier@Sun.COM smb_giter_t gi; 174011337SWilliam.Krier@Sun.COM int cnt, skip, i; 174111337SWilliam.Krier@Sun.COM struct name_rid *info; 174211337SWilliam.Krier@Sun.COM 174311337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 174411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 174511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 174611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 174711337SWilliam.Krier@Sun.COM } 174811337SWilliam.Krier@Sun.COM 174911337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 175011337SWilliam.Krier@Sun.COM 175111337SWilliam.Krier@Sun.COM cnt = smb_sam_grp_cnt(data->kd_type); 175211337SWilliam.Krier@Sun.COM if (cnt <= param->resume_handle) { 175311337SWilliam.Krier@Sun.COM param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, 175411337SWilliam.Krier@Sun.COM sizeof (struct aliases_info)); 175511337SWilliam.Krier@Sun.COM 175611337SWilliam.Krier@Sun.COM if (param->aliases == NULL) { 175711337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 175811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 175911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 176011337SWilliam.Krier@Sun.COM } 176111337SWilliam.Krier@Sun.COM 176211337SWilliam.Krier@Sun.COM bzero(param->aliases, sizeof (struct aliases_info)); 176311337SWilliam.Krier@Sun.COM param->out_resume = 0; 176411337SWilliam.Krier@Sun.COM param->entries = 0; 176511337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 176611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 176711337SWilliam.Krier@Sun.COM } 176811337SWilliam.Krier@Sun.COM 176911337SWilliam.Krier@Sun.COM cnt -= param->resume_handle; 177011337SWilliam.Krier@Sun.COM param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, 177111337SWilliam.Krier@Sun.COM sizeof (struct aliases_info) + (cnt-1) * sizeof (struct name_rid)); 177211337SWilliam.Krier@Sun.COM 177311337SWilliam.Krier@Sun.COM if (param->aliases == NULL) { 177411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 177511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 177611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 177711337SWilliam.Krier@Sun.COM } 177811337SWilliam.Krier@Sun.COM 177911337SWilliam.Krier@Sun.COM if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 178011337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 178111337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); 178211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 178311337SWilliam.Krier@Sun.COM } 178411337SWilliam.Krier@Sun.COM 178511337SWilliam.Krier@Sun.COM skip = i = 0; 178611337SWilliam.Krier@Sun.COM info = param->aliases->info; 178711337SWilliam.Krier@Sun.COM while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) { 178811337SWilliam.Krier@Sun.COM if ((skip++ >= param->resume_handle) && 178911337SWilliam.Krier@Sun.COM (grp.sg_domain == data->kd_type) && (i++ < cnt)) { 179011337SWilliam.Krier@Sun.COM info->rid = grp.sg_rid; 179111337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, grp.sg_name, 179211337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&info->name); 179311337SWilliam.Krier@Sun.COM 179411337SWilliam.Krier@Sun.COM info++; 179511337SWilliam.Krier@Sun.COM } 179611337SWilliam.Krier@Sun.COM smb_lgrp_free(&grp); 179711337SWilliam.Krier@Sun.COM } 179811337SWilliam.Krier@Sun.COM smb_lgrp_iterclose(&gi); 179911337SWilliam.Krier@Sun.COM 180011337SWilliam.Krier@Sun.COM param->aliases->count = i; 180111337SWilliam.Krier@Sun.COM param->aliases->address = i; 180211337SWilliam.Krier@Sun.COM 180311337SWilliam.Krier@Sun.COM param->out_resume = i; 180411337SWilliam.Krier@Sun.COM param->entries = i; 180511337SWilliam.Krier@Sun.COM param->status = 0; 180611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 180711337SWilliam.Krier@Sun.COM } 180811337SWilliam.Krier@Sun.COM 180911337SWilliam.Krier@Sun.COM /* 181011337SWilliam.Krier@Sun.COM * samr_s_Connect3 181111337SWilliam.Krier@Sun.COM */ 181211337SWilliam.Krier@Sun.COM static int 181311337SWilliam.Krier@Sun.COM samr_s_Connect3(void *arg, ndr_xa_t *mxa) 181411337SWilliam.Krier@Sun.COM { 181511447Samw@Sun.COM struct samr_Connect3 *param = arg; 181611447Samw@Sun.COM ndr_hdid_t *id; 181711337SWilliam.Krier@Sun.COM 181811447Samw@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 181911447Samw@Sun.COM if (id) { 182011447Samw@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 182111447Samw@Sun.COM param->status = 0; 182211447Samw@Sun.COM } else { 182311447Samw@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 182411447Samw@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 182511447Samw@Sun.COM } 182611447Samw@Sun.COM 182711447Samw@Sun.COM return (NDR_DRC_OK); 182811337SWilliam.Krier@Sun.COM } 182911337SWilliam.Krier@Sun.COM 183011337SWilliam.Krier@Sun.COM /* 183111337SWilliam.Krier@Sun.COM * samr_s_Connect4 183211337SWilliam.Krier@Sun.COM * 183311337SWilliam.Krier@Sun.COM * This is the connect4 form of the connect request used by Windows XP. 183411337SWilliam.Krier@Sun.COM * Returns an RPC fault for now. 183511337SWilliam.Krier@Sun.COM */ 183611337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 183711337SWilliam.Krier@Sun.COM static int 183811337SWilliam.Krier@Sun.COM samr_s_Connect4(void *arg, ndr_xa_t *mxa) 183911337SWilliam.Krier@Sun.COM { 184011337SWilliam.Krier@Sun.COM struct samr_Connect4 *param = arg; 184111337SWilliam.Krier@Sun.COM 184211337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_Connect4)); 184311337SWilliam.Krier@Sun.COM return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 184411337SWilliam.Krier@Sun.COM } 184511337SWilliam.Krier@Sun.COM 184611337SWilliam.Krier@Sun.COM static ndr_stub_table_t samr_stub_table[] = { 184711337SWilliam.Krier@Sun.COM { samr_s_ConnectAnon, SAMR_OPNUM_ConnectAnon }, 184811337SWilliam.Krier@Sun.COM { samr_s_CloseHandle, SAMR_OPNUM_CloseHandle }, 184911337SWilliam.Krier@Sun.COM { samr_s_LookupDomain, SAMR_OPNUM_LookupDomain }, 185011337SWilliam.Krier@Sun.COM { samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains }, 185111337SWilliam.Krier@Sun.COM { samr_s_OpenDomain, SAMR_OPNUM_OpenDomain }, 185211337SWilliam.Krier@Sun.COM { samr_s_QueryDomainInfo, SAMR_OPNUM_QueryDomainInfo }, 185311447Samw@Sun.COM { samr_s_QueryInfoDomain2, SAMR_OPNUM_QueryInfoDomain2 }, 185411337SWilliam.Krier@Sun.COM { samr_s_LookupNames, SAMR_OPNUM_LookupNames }, 185511337SWilliam.Krier@Sun.COM { samr_s_OpenUser, SAMR_OPNUM_OpenUser }, 185611337SWilliam.Krier@Sun.COM { samr_s_DeleteUser, SAMR_OPNUM_DeleteUser }, 185711337SWilliam.Krier@Sun.COM { samr_s_QueryUserInfo, SAMR_OPNUM_QueryUserInfo }, 185811337SWilliam.Krier@Sun.COM { samr_s_QueryUserGroups, SAMR_OPNUM_QueryUserGroups }, 185911337SWilliam.Krier@Sun.COM { samr_s_OpenGroup, SAMR_OPNUM_OpenGroup }, 186011337SWilliam.Krier@Sun.COM { samr_s_Connect, SAMR_OPNUM_Connect }, 186111337SWilliam.Krier@Sun.COM { samr_s_GetUserPwInfo, SAMR_OPNUM_GetUserPwInfo }, 186211337SWilliam.Krier@Sun.COM { samr_s_CreateUser, SAMR_OPNUM_CreateUser }, 186311337SWilliam.Krier@Sun.COM { samr_s_ChangeUserPasswd, SAMR_OPNUM_ChangeUserPasswd }, 186411337SWilliam.Krier@Sun.COM { samr_s_GetDomainPwInfo, SAMR_OPNUM_GetDomainPwInfo }, 186511337SWilliam.Krier@Sun.COM { samr_s_SetUserInfo, SAMR_OPNUM_SetUserInfo }, 186611337SWilliam.Krier@Sun.COM { samr_s_Connect3, SAMR_OPNUM_Connect3 }, 186711337SWilliam.Krier@Sun.COM { samr_s_Connect4, SAMR_OPNUM_Connect4 }, 186811337SWilliam.Krier@Sun.COM { samr_s_QueryDispInfo, SAMR_OPNUM_QueryDispInfo }, 186911337SWilliam.Krier@Sun.COM { samr_s_OpenAlias, SAMR_OPNUM_OpenAlias }, 187011337SWilliam.Krier@Sun.COM { samr_s_CreateDomainAlias, SAMR_OPNUM_CreateDomainAlias }, 187111337SWilliam.Krier@Sun.COM { samr_s_SetAliasInfo, SAMR_OPNUM_SetAliasInfo }, 187211337SWilliam.Krier@Sun.COM { samr_s_QueryAliasInfo, SAMR_OPNUM_QueryAliasInfo }, 187311337SWilliam.Krier@Sun.COM { samr_s_DeleteDomainAlias, SAMR_OPNUM_DeleteDomainAlias }, 187411337SWilliam.Krier@Sun.COM { samr_s_EnumDomainAliases, SAMR_OPNUM_EnumDomainAliases }, 187511337SWilliam.Krier@Sun.COM { samr_s_EnumDomainGroups, SAMR_OPNUM_EnumDomainGroups }, 187612065SKeyur.Desai@Sun.COM { samr_s_AddAliasMember, SAMR_OPNUM_AddAliasMember }, 187712065SKeyur.Desai@Sun.COM { samr_s_DeleteAliasMember, SAMR_OPNUM_DeleteAliasMember }, 187812065SKeyur.Desai@Sun.COM { samr_s_ListAliasMembers, SAMR_OPNUM_ListAliasMembers }, 187911337SWilliam.Krier@Sun.COM {0} 188011337SWilliam.Krier@Sun.COM }; 188111337SWilliam.Krier@Sun.COM 188211337SWilliam.Krier@Sun.COM /* 188311337SWilliam.Krier@Sun.COM * There is a bug in the way that midl and the marshalling code handles 188411337SWilliam.Krier@Sun.COM * unions so we need to fix some of the data offsets at runtime. The 188511337SWilliam.Krier@Sun.COM * following macros and the fixup functions handle the corrections. 188611337SWilliam.Krier@Sun.COM */ 188711337SWilliam.Krier@Sun.COM 188811337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfo_ru); 188911337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfoRes); 189011337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfo); 189111337SWilliam.Krier@Sun.COM 189211337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(QueryUserInfo_result_u); 189311337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(QueryUserInfo_result); 189411337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryUserInfo); 189511337SWilliam.Krier@Sun.COM 189611337SWilliam.Krier@Sun.COM void 189711337SWilliam.Krier@Sun.COM fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo *val) 189811337SWilliam.Krier@Sun.COM { 189911337SWilliam.Krier@Sun.COM unsigned short size1 = 0; 190011337SWilliam.Krier@Sun.COM unsigned short size2 = 0; 190111337SWilliam.Krier@Sun.COM unsigned short size3 = 0; 190211337SWilliam.Krier@Sun.COM 190311337SWilliam.Krier@Sun.COM switch (val->level) { 190411337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryAliasInfo, 1); 190511337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryAliasInfo, 3); 190611337SWilliam.Krier@Sun.COM 190711337SWilliam.Krier@Sun.COM default: 190811337SWilliam.Krier@Sun.COM return; 190911337SWilliam.Krier@Sun.COM }; 191011337SWilliam.Krier@Sun.COM 191111337SWilliam.Krier@Sun.COM size2 = size1 + (2 * sizeof (DWORD)); 191211337SWilliam.Krier@Sun.COM size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 191311337SWilliam.Krier@Sun.COM 191411337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfo_ru, size1); 191511337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfoRes, size2); 191611337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfo, size3); 191711337SWilliam.Krier@Sun.COM } 191811337SWilliam.Krier@Sun.COM 191911337SWilliam.Krier@Sun.COM void 192011337SWilliam.Krier@Sun.COM fixup_samr_QueryUserInfo(struct samr_QueryUserInfo *val) 192111337SWilliam.Krier@Sun.COM { 192211337SWilliam.Krier@Sun.COM unsigned short size1 = 0; 192311337SWilliam.Krier@Sun.COM unsigned short size2 = 0; 192411337SWilliam.Krier@Sun.COM unsigned short size3 = 0; 192511337SWilliam.Krier@Sun.COM 192611337SWilliam.Krier@Sun.COM switch (val->switch_index) { 192711337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 1); 192811337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 6); 192911337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 7); 193011337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 8); 193111337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 9); 193211337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 16); 193311337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 21); 193411337SWilliam.Krier@Sun.COM 193511337SWilliam.Krier@Sun.COM default: 193611337SWilliam.Krier@Sun.COM return; 193711337SWilliam.Krier@Sun.COM }; 193811337SWilliam.Krier@Sun.COM 193911337SWilliam.Krier@Sun.COM size2 = size1 + (2 * sizeof (DWORD)); 194011337SWilliam.Krier@Sun.COM size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 194111337SWilliam.Krier@Sun.COM 194211337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(QueryUserInfo_result_u, size1); 194311337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(QueryUserInfo_result, size2); 194411337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryUserInfo, size3); 194511337SWilliam.Krier@Sun.COM } 194611337SWilliam.Krier@Sun.COM 194711337SWilliam.Krier@Sun.COM /* 194811337SWilliam.Krier@Sun.COM * As long as there is only one entry in the union, there is no need 194911337SWilliam.Krier@Sun.COM * to patch anything. 195011337SWilliam.Krier@Sun.COM */ 195111337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 195211337SWilliam.Krier@Sun.COM void 195311337SWilliam.Krier@Sun.COM fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo *val) 195411337SWilliam.Krier@Sun.COM { 195511337SWilliam.Krier@Sun.COM } 1956