111337SWilliam.Krier@Sun.COM /* 211337SWilliam.Krier@Sun.COM * CDDL HEADER START 311337SWilliam.Krier@Sun.COM * 411337SWilliam.Krier@Sun.COM * The contents of this file are subject to the terms of the 511337SWilliam.Krier@Sun.COM * Common Development and Distribution License (the "License"). 611337SWilliam.Krier@Sun.COM * You may not use this file except in compliance with the License. 711337SWilliam.Krier@Sun.COM * 811337SWilliam.Krier@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 911337SWilliam.Krier@Sun.COM * or http://www.opensolaris.org/os/licensing. 1011337SWilliam.Krier@Sun.COM * See the License for the specific language governing permissions 1111337SWilliam.Krier@Sun.COM * and limitations under the License. 1211337SWilliam.Krier@Sun.COM * 1311337SWilliam.Krier@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 1411337SWilliam.Krier@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1511337SWilliam.Krier@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 1611337SWilliam.Krier@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 1711337SWilliam.Krier@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 1811337SWilliam.Krier@Sun.COM * 1911337SWilliam.Krier@Sun.COM * CDDL HEADER END 2011337SWilliam.Krier@Sun.COM */ 2111337SWilliam.Krier@Sun.COM /* 22*12065SKeyur.Desai@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 2311337SWilliam.Krier@Sun.COM */ 2411337SWilliam.Krier@Sun.COM 2511337SWilliam.Krier@Sun.COM /* 2611337SWilliam.Krier@Sun.COM * Security Accounts Manager RPC (SAMR) server-side interface. 2711337SWilliam.Krier@Sun.COM * 2811337SWilliam.Krier@Sun.COM * The SAM is a hierarchical database: 2911337SWilliam.Krier@Sun.COM * - If you want to talk to the SAM you need a SAM handle. 3011337SWilliam.Krier@Sun.COM * - If you want to work with a domain, use the SAM handle. 3111337SWilliam.Krier@Sun.COM * to obtain a domain handle. 3211337SWilliam.Krier@Sun.COM * - Use domain handles to obtain user handles etc. 3311337SWilliam.Krier@Sun.COM */ 3411337SWilliam.Krier@Sun.COM 3511337SWilliam.Krier@Sun.COM #include <strings.h> 3611337SWilliam.Krier@Sun.COM #include <unistd.h> 3711337SWilliam.Krier@Sun.COM #include <netdb.h> 3811337SWilliam.Krier@Sun.COM #include <assert.h> 39*12065SKeyur.Desai@Sun.COM #include <grp.h> 4011337SWilliam.Krier@Sun.COM #include <smbsrv/libsmb.h> 4111337SWilliam.Krier@Sun.COM #include <smbsrv/libmlrpc.h> 4211337SWilliam.Krier@Sun.COM #include <smbsrv/libmlsvc.h> 4311337SWilliam.Krier@Sun.COM #include <smbsrv/ntstatus.h> 4411337SWilliam.Krier@Sun.COM #include <smbsrv/nterror.h> 4511337SWilliam.Krier@Sun.COM #include <smbsrv/smbinfo.h> 4611337SWilliam.Krier@Sun.COM #include <smbsrv/nmpipes.h> 4711337SWilliam.Krier@Sun.COM #include <smbsrv/ndl/samrpc.ndl> 4811337SWilliam.Krier@Sun.COM #include <samlib.h> 4911337SWilliam.Krier@Sun.COM 5011337SWilliam.Krier@Sun.COM /* 5111337SWilliam.Krier@Sun.COM * The keys associated with the various handles dispensed by the SAMR 5211337SWilliam.Krier@Sun.COM * server. These keys can be used to validate client activity. 5311337SWilliam.Krier@Sun.COM * These values are never passed over the wire so security shouldn't 5411337SWilliam.Krier@Sun.COM * be an issue. 5511337SWilliam.Krier@Sun.COM */ 5611337SWilliam.Krier@Sun.COM typedef enum { 5711337SWilliam.Krier@Sun.COM SAMR_KEY_NULL = 0, 5811337SWilliam.Krier@Sun.COM SAMR_KEY_CONNECT, 5911337SWilliam.Krier@Sun.COM SAMR_KEY_DOMAIN, 6011337SWilliam.Krier@Sun.COM SAMR_KEY_USER, 6111337SWilliam.Krier@Sun.COM SAMR_KEY_GROUP, 6211337SWilliam.Krier@Sun.COM SAMR_KEY_ALIAS 6311337SWilliam.Krier@Sun.COM } samr_key_t; 6411337SWilliam.Krier@Sun.COM 6511337SWilliam.Krier@Sun.COM typedef struct samr_keydata { 6611337SWilliam.Krier@Sun.COM samr_key_t kd_key; 6711337SWilliam.Krier@Sun.COM smb_domain_type_t kd_type; 6811337SWilliam.Krier@Sun.COM DWORD kd_rid; 6911337SWilliam.Krier@Sun.COM } samr_keydata_t; 7011337SWilliam.Krier@Sun.COM 7111337SWilliam.Krier@Sun.COM /* 7211337SWilliam.Krier@Sun.COM * DomainDisplayUser All user objects (or those derived from user) with 7311337SWilliam.Krier@Sun.COM * userAccountControl containing the UF_NORMAL_ACCOUNT bit. 7411337SWilliam.Krier@Sun.COM * 7511337SWilliam.Krier@Sun.COM * DomainDisplayMachine All user objects (or those derived from user) with 7611337SWilliam.Krier@Sun.COM * userAccountControl containing the 7711337SWilliam.Krier@Sun.COM * UF_WORKSTATION_TRUST_ACCOUNT or UF_SERVER_TRUST_ACCOUNT 7811337SWilliam.Krier@Sun.COM * bit. 7911337SWilliam.Krier@Sun.COM * 8011337SWilliam.Krier@Sun.COM * DomainDisplayGroup All group objects (or those derived from group) with 8111337SWilliam.Krier@Sun.COM * groupType equal to GROUP_TYPE_SECURITY_UNIVERSAL or 8211337SWilliam.Krier@Sun.COM * GROUP_TYPE_SECURITY_ACCOUNT. 8311337SWilliam.Krier@Sun.COM * 8411337SWilliam.Krier@Sun.COM * DomainDisplayOemUser Same as DomainDisplayUser with OEM strings 8511337SWilliam.Krier@Sun.COM * 8611337SWilliam.Krier@Sun.COM * DomainDisplayOemGroup Same as DomainDisplayGroup with OEM strings 8711337SWilliam.Krier@Sun.COM */ 8811337SWilliam.Krier@Sun.COM typedef enum { 8911337SWilliam.Krier@Sun.COM DomainDisplayUser = 1, 9011337SWilliam.Krier@Sun.COM DomainDisplayMachine, 9111337SWilliam.Krier@Sun.COM DomainDispalyGroup, 9211337SWilliam.Krier@Sun.COM DomainDisplayOemUser, 9311337SWilliam.Krier@Sun.COM DomainDisplayOemGroup 9411337SWilliam.Krier@Sun.COM } samr_displvl_t; 9511337SWilliam.Krier@Sun.COM 9611337SWilliam.Krier@Sun.COM #define SAMR_VALID_DISPLEVEL(lvl) \ 9711337SWilliam.Krier@Sun.COM (((lvl) >= DomainDisplayUser) && ((lvl) <= DomainDisplayOemGroup)) 9811337SWilliam.Krier@Sun.COM 9911337SWilliam.Krier@Sun.COM #define SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser) 10011337SWilliam.Krier@Sun.COM 10111337SWilliam.Krier@Sun.COM static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t, 10211337SWilliam.Krier@Sun.COM DWORD); 10311337SWilliam.Krier@Sun.COM static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *); 10411337SWilliam.Krier@Sun.COM static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t); 10511337SWilliam.Krier@Sun.COM static int samr_call_stub(ndr_xa_t *mxa); 10611337SWilliam.Krier@Sun.COM static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *, 10711337SWilliam.Krier@Sun.COM ndr_xa_t *); 10811337SWilliam.Krier@Sun.COM 10911337SWilliam.Krier@Sun.COM static ndr_stub_table_t samr_stub_table[]; 11011337SWilliam.Krier@Sun.COM 11111337SWilliam.Krier@Sun.COM static ndr_service_t samr_service = { 11211337SWilliam.Krier@Sun.COM "SAMR", /* name */ 11311337SWilliam.Krier@Sun.COM "Security Accounts Manager", /* desc */ 11411337SWilliam.Krier@Sun.COM "\\samr", /* endpoint */ 11511337SWilliam.Krier@Sun.COM PIPE_LSASS, /* sec_addr_port */ 11611337SWilliam.Krier@Sun.COM "12345778-1234-abcd-ef00-0123456789ac", 1, /* abstract */ 11711337SWilliam.Krier@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 11811337SWilliam.Krier@Sun.COM 0, /* no bind_instance_size */ 11911337SWilliam.Krier@Sun.COM NULL, /* no bind_req() */ 12011337SWilliam.Krier@Sun.COM NULL, /* no unbind_and_close() */ 12111337SWilliam.Krier@Sun.COM samr_call_stub, /* call_stub() */ 12211337SWilliam.Krier@Sun.COM &TYPEINFO(samr_interface), /* interface ti */ 12311337SWilliam.Krier@Sun.COM samr_stub_table /* stub_table */ 12411337SWilliam.Krier@Sun.COM }; 12511337SWilliam.Krier@Sun.COM 12611337SWilliam.Krier@Sun.COM /* 12711337SWilliam.Krier@Sun.COM * samr_initialize 12811337SWilliam.Krier@Sun.COM * 12911337SWilliam.Krier@Sun.COM * This function registers the SAM RPC interface with the RPC runtime 13011337SWilliam.Krier@Sun.COM * library. It must be called in order to use either the client side 13111337SWilliam.Krier@Sun.COM * or the server side functions. 13211337SWilliam.Krier@Sun.COM */ 13311337SWilliam.Krier@Sun.COM void 13411337SWilliam.Krier@Sun.COM samr_initialize(void) 13511337SWilliam.Krier@Sun.COM { 13611337SWilliam.Krier@Sun.COM (void) ndr_svc_register(&samr_service); 13711337SWilliam.Krier@Sun.COM } 13811337SWilliam.Krier@Sun.COM 13911337SWilliam.Krier@Sun.COM /* 14011337SWilliam.Krier@Sun.COM * Custom call_stub to set the stream string policy. 14111337SWilliam.Krier@Sun.COM */ 14211337SWilliam.Krier@Sun.COM static int 14311337SWilliam.Krier@Sun.COM samr_call_stub(ndr_xa_t *mxa) 14411337SWilliam.Krier@Sun.COM { 14511337SWilliam.Krier@Sun.COM NDS_SETF(&mxa->send_nds, NDS_F_NOTERM); 14611337SWilliam.Krier@Sun.COM NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM); 14711337SWilliam.Krier@Sun.COM 14811337SWilliam.Krier@Sun.COM return (ndr_generic_call_stub(mxa)); 14911337SWilliam.Krier@Sun.COM } 15011337SWilliam.Krier@Sun.COM 15111337SWilliam.Krier@Sun.COM /* 15211337SWilliam.Krier@Sun.COM * Handle allocation wrapper to setup the local context. 15311337SWilliam.Krier@Sun.COM */ 15411337SWilliam.Krier@Sun.COM static ndr_hdid_t * 15511337SWilliam.Krier@Sun.COM samr_hdalloc(ndr_xa_t *mxa, samr_key_t key, smb_domain_type_t domain_type, 15611337SWilliam.Krier@Sun.COM DWORD rid) 15711337SWilliam.Krier@Sun.COM { 15811963SAfshin.Ardakani@Sun.COM ndr_handle_t *hd; 15911963SAfshin.Ardakani@Sun.COM ndr_hdid_t *id; 16011963SAfshin.Ardakani@Sun.COM samr_keydata_t *data; 16111337SWilliam.Krier@Sun.COM 16211337SWilliam.Krier@Sun.COM if ((data = malloc(sizeof (samr_keydata_t))) == NULL) 16311337SWilliam.Krier@Sun.COM return (NULL); 16411337SWilliam.Krier@Sun.COM 16511337SWilliam.Krier@Sun.COM data->kd_key = key; 16611337SWilliam.Krier@Sun.COM data->kd_type = domain_type; 16711337SWilliam.Krier@Sun.COM data->kd_rid = rid; 16811337SWilliam.Krier@Sun.COM 16911963SAfshin.Ardakani@Sun.COM if ((id = ndr_hdalloc(mxa, data)) == NULL) { 17011963SAfshin.Ardakani@Sun.COM free(data); 17111963SAfshin.Ardakani@Sun.COM return (NULL); 17211963SAfshin.Ardakani@Sun.COM } 17311963SAfshin.Ardakani@Sun.COM 17411963SAfshin.Ardakani@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL) 17511963SAfshin.Ardakani@Sun.COM hd->nh_data_free = free; 17611963SAfshin.Ardakani@Sun.COM 17711963SAfshin.Ardakani@Sun.COM return (id); 17811337SWilliam.Krier@Sun.COM } 17911337SWilliam.Krier@Sun.COM 18011337SWilliam.Krier@Sun.COM /* 18111337SWilliam.Krier@Sun.COM * Handle deallocation wrapper to free the local context. 18211337SWilliam.Krier@Sun.COM */ 18311337SWilliam.Krier@Sun.COM static void 18411337SWilliam.Krier@Sun.COM samr_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id) 18511337SWilliam.Krier@Sun.COM { 18611337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 18711337SWilliam.Krier@Sun.COM 18811337SWilliam.Krier@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL) { 18911337SWilliam.Krier@Sun.COM free(hd->nh_data); 19011963SAfshin.Ardakani@Sun.COM hd->nh_data = NULL; 19111337SWilliam.Krier@Sun.COM ndr_hdfree(mxa, id); 19211337SWilliam.Krier@Sun.COM } 19311337SWilliam.Krier@Sun.COM } 19411337SWilliam.Krier@Sun.COM 19511337SWilliam.Krier@Sun.COM /* 19611337SWilliam.Krier@Sun.COM * Handle lookup wrapper to validate the local context. 19711337SWilliam.Krier@Sun.COM */ 19811337SWilliam.Krier@Sun.COM static ndr_handle_t * 19911337SWilliam.Krier@Sun.COM samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key) 20011337SWilliam.Krier@Sun.COM { 20111337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 20211337SWilliam.Krier@Sun.COM samr_keydata_t *data; 20311337SWilliam.Krier@Sun.COM 20411337SWilliam.Krier@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) == NULL) 20511337SWilliam.Krier@Sun.COM return (NULL); 20611337SWilliam.Krier@Sun.COM 20711337SWilliam.Krier@Sun.COM if ((data = (samr_keydata_t *)hd->nh_data) == NULL) 20811337SWilliam.Krier@Sun.COM return (NULL); 20911337SWilliam.Krier@Sun.COM 21011337SWilliam.Krier@Sun.COM if (data->kd_key != key) 21111337SWilliam.Krier@Sun.COM return (NULL); 21211337SWilliam.Krier@Sun.COM 21311337SWilliam.Krier@Sun.COM return (hd); 21411337SWilliam.Krier@Sun.COM } 21511337SWilliam.Krier@Sun.COM 21611337SWilliam.Krier@Sun.COM /* 21711337SWilliam.Krier@Sun.COM * samr_s_ConnectAnon 21811337SWilliam.Krier@Sun.COM * 21911337SWilliam.Krier@Sun.COM * This is a request to connect to the local SAM database. We don't 22011337SWilliam.Krier@Sun.COM * support any form of update request and our database doesn't 22111337SWilliam.Krier@Sun.COM * contain any private information, so there is little point in 22211337SWilliam.Krier@Sun.COM * doing any access access checking here. 22311337SWilliam.Krier@Sun.COM * 22411337SWilliam.Krier@Sun.COM * Return a handle for use with subsequent SAM requests. 22511337SWilliam.Krier@Sun.COM */ 22611337SWilliam.Krier@Sun.COM static int 22711337SWilliam.Krier@Sun.COM samr_s_ConnectAnon(void *arg, ndr_xa_t *mxa) 22811337SWilliam.Krier@Sun.COM { 22911337SWilliam.Krier@Sun.COM struct samr_ConnectAnon *param = arg; 23011337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 23111337SWilliam.Krier@Sun.COM 23211337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 23311337SWilliam.Krier@Sun.COM if (id) { 23411337SWilliam.Krier@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 23511337SWilliam.Krier@Sun.COM param->status = 0; 23611337SWilliam.Krier@Sun.COM } else { 23711337SWilliam.Krier@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 23811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 23911337SWilliam.Krier@Sun.COM } 24011337SWilliam.Krier@Sun.COM 24111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 24211337SWilliam.Krier@Sun.COM } 24311337SWilliam.Krier@Sun.COM 24411337SWilliam.Krier@Sun.COM /* 24511337SWilliam.Krier@Sun.COM * samr_s_CloseHandle 24611337SWilliam.Krier@Sun.COM * 24711337SWilliam.Krier@Sun.COM * Close the SAM interface specified by the handle. 24811337SWilliam.Krier@Sun.COM * Free the handle and zero out the result handle for the client. 24911337SWilliam.Krier@Sun.COM */ 25011337SWilliam.Krier@Sun.COM static int 25111337SWilliam.Krier@Sun.COM samr_s_CloseHandle(void *arg, ndr_xa_t *mxa) 25211337SWilliam.Krier@Sun.COM { 25311337SWilliam.Krier@Sun.COM struct samr_CloseHandle *param = arg; 25411337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 25511337SWilliam.Krier@Sun.COM 25611337SWilliam.Krier@Sun.COM samr_hdfree(mxa, id); 25711337SWilliam.Krier@Sun.COM 25811337SWilliam.Krier@Sun.COM bzero(¶m->result_handle, sizeof (samr_handle_t)); 25911337SWilliam.Krier@Sun.COM param->status = 0; 26011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 26111337SWilliam.Krier@Sun.COM } 26211337SWilliam.Krier@Sun.COM 26311337SWilliam.Krier@Sun.COM /* 26411337SWilliam.Krier@Sun.COM * samr_s_LookupDomain 26511337SWilliam.Krier@Sun.COM * 26611337SWilliam.Krier@Sun.COM * This is a request to map a domain name to a domain SID. We can map 26711337SWilliam.Krier@Sun.COM * the primary domain name, our local domain name (hostname) and the 26811337SWilliam.Krier@Sun.COM * builtin domain names to the appropriate SID. Anything else will be 26911337SWilliam.Krier@Sun.COM * rejected. 27011337SWilliam.Krier@Sun.COM */ 27111337SWilliam.Krier@Sun.COM static int 27211337SWilliam.Krier@Sun.COM samr_s_LookupDomain(void *arg, ndr_xa_t *mxa) 27311337SWilliam.Krier@Sun.COM { 27411337SWilliam.Krier@Sun.COM struct samr_LookupDomain *param = arg; 27511337SWilliam.Krier@Sun.COM char *domain_name; 27611337SWilliam.Krier@Sun.COM smb_domain_t di; 27711337SWilliam.Krier@Sun.COM 27811337SWilliam.Krier@Sun.COM if ((domain_name = (char *)param->domain_name.str) == NULL) { 27911337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 28011337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 28111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 28211337SWilliam.Krier@Sun.COM } 28311337SWilliam.Krier@Sun.COM 28411337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_name(domain_name, &di)) { 28511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 28611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_DOMAIN); 28711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 28811337SWilliam.Krier@Sun.COM } 28911337SWilliam.Krier@Sun.COM 29011337SWilliam.Krier@Sun.COM param->sid = (struct samr_sid *)NDR_SIDDUP(mxa, di.di_binsid); 29111337SWilliam.Krier@Sun.COM if (param->sid == NULL) { 29211337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 29311337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 29411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 29511337SWilliam.Krier@Sun.COM } 29611337SWilliam.Krier@Sun.COM 29711337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 29811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 29911337SWilliam.Krier@Sun.COM } 30011337SWilliam.Krier@Sun.COM 30111337SWilliam.Krier@Sun.COM /* 30211337SWilliam.Krier@Sun.COM * samr_s_EnumLocalDomains 30311337SWilliam.Krier@Sun.COM * 30411337SWilliam.Krier@Sun.COM * This is a request for the local domains supported by this server. 30511337SWilliam.Krier@Sun.COM * All we do here is validate the handle and set the status. The real 30611337SWilliam.Krier@Sun.COM * work is done in samr_s_enum_local_domains. 30711337SWilliam.Krier@Sun.COM */ 30811337SWilliam.Krier@Sun.COM static int 30911337SWilliam.Krier@Sun.COM samr_s_EnumLocalDomains(void *arg, ndr_xa_t *mxa) 31011337SWilliam.Krier@Sun.COM { 31111337SWilliam.Krier@Sun.COM struct samr_EnumLocalDomain *param = arg; 31211337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 31311337SWilliam.Krier@Sun.COM DWORD status; 31411337SWilliam.Krier@Sun.COM 31511337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) 31611337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 31711337SWilliam.Krier@Sun.COM else 31811337SWilliam.Krier@Sun.COM status = samr_s_enum_local_domains(param, mxa); 31911337SWilliam.Krier@Sun.COM 32011337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) { 32111337SWilliam.Krier@Sun.COM param->enum_context = param->info->entries_read; 32211337SWilliam.Krier@Sun.COM param->total_entries = param->info->entries_read; 32311337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 32411337SWilliam.Krier@Sun.COM } else { 32511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumLocalDomain)); 32611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 32711337SWilliam.Krier@Sun.COM } 32811337SWilliam.Krier@Sun.COM 32911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 33011337SWilliam.Krier@Sun.COM } 33111337SWilliam.Krier@Sun.COM 33211337SWilliam.Krier@Sun.COM 33311337SWilliam.Krier@Sun.COM /* 33411337SWilliam.Krier@Sun.COM * samr_s_enum_local_domains 33511337SWilliam.Krier@Sun.COM * 33611337SWilliam.Krier@Sun.COM * This function should only be called via samr_s_EnumLocalDomains to 33711337SWilliam.Krier@Sun.COM * ensure that the appropriate validation is performed. We will answer 33811337SWilliam.Krier@Sun.COM * queries about two domains: the local domain, synonymous with the 33911337SWilliam.Krier@Sun.COM * local hostname, and the BUILTIN domain. So we return these two 34011337SWilliam.Krier@Sun.COM * strings. 34111337SWilliam.Krier@Sun.COM * 34211337SWilliam.Krier@Sun.COM * Returns NT status values. 34311337SWilliam.Krier@Sun.COM */ 34411337SWilliam.Krier@Sun.COM static DWORD 34511337SWilliam.Krier@Sun.COM samr_s_enum_local_domains(struct samr_EnumLocalDomain *param, 34611337SWilliam.Krier@Sun.COM ndr_xa_t *mxa) 34711337SWilliam.Krier@Sun.COM { 34811337SWilliam.Krier@Sun.COM struct samr_LocalDomainInfo *info; 34911337SWilliam.Krier@Sun.COM struct samr_LocalDomainEntry *entry; 35011337SWilliam.Krier@Sun.COM char *hostname; 35111337SWilliam.Krier@Sun.COM 35211337SWilliam.Krier@Sun.COM hostname = NDR_MALLOC(mxa, NETBIOS_NAME_SZ); 35311337SWilliam.Krier@Sun.COM if (hostname == NULL) 35411337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 35511337SWilliam.Krier@Sun.COM 35611337SWilliam.Krier@Sun.COM if (smb_getnetbiosname(hostname, NETBIOS_NAME_SZ) != 0) 35711337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 35811337SWilliam.Krier@Sun.COM 35911337SWilliam.Krier@Sun.COM entry = NDR_NEWN(mxa, struct samr_LocalDomainEntry, 2); 36011337SWilliam.Krier@Sun.COM if (entry == NULL) 36111337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 36211337SWilliam.Krier@Sun.COM 36311337SWilliam.Krier@Sun.COM bzero(entry, (sizeof (struct samr_LocalDomainEntry) * 2)); 36411337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, hostname, (ndr_mstring_t *)&entry[0].name); 36511337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "Builtin", (ndr_mstring_t *)&entry[1].name); 36611337SWilliam.Krier@Sun.COM 36711337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_LocalDomainInfo); 36811337SWilliam.Krier@Sun.COM if (info == NULL) 36911337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 37011337SWilliam.Krier@Sun.COM 37111337SWilliam.Krier@Sun.COM info->entries_read = 2; 37211337SWilliam.Krier@Sun.COM info->entry = entry; 37311337SWilliam.Krier@Sun.COM param->info = info; 37411337SWilliam.Krier@Sun.COM return (NT_STATUS_SUCCESS); 37511337SWilliam.Krier@Sun.COM } 37611337SWilliam.Krier@Sun.COM 37711337SWilliam.Krier@Sun.COM /* 37811337SWilliam.Krier@Sun.COM * samr_s_OpenDomain 37911337SWilliam.Krier@Sun.COM * 38011337SWilliam.Krier@Sun.COM * This is a request to open a domain within the local SAM database. 38111337SWilliam.Krier@Sun.COM * The caller must supply a valid connect handle. 38211337SWilliam.Krier@Sun.COM * We return a handle to be used to access objects within this domain. 38311337SWilliam.Krier@Sun.COM */ 38411337SWilliam.Krier@Sun.COM static int 38511337SWilliam.Krier@Sun.COM samr_s_OpenDomain(void *arg, ndr_xa_t *mxa) 38611337SWilliam.Krier@Sun.COM { 38711337SWilliam.Krier@Sun.COM struct samr_OpenDomain *param = arg; 38811337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 38911337SWilliam.Krier@Sun.COM smb_domain_t domain; 39011337SWilliam.Krier@Sun.COM 39111337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) { 39211337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 39311337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 39411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 39511337SWilliam.Krier@Sun.COM } 39611337SWilliam.Krier@Sun.COM 39711337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_sid((smb_sid_t *)param->sid, &domain)) { 39811337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 39911337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 40011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 40111337SWilliam.Krier@Sun.COM } 40211337SWilliam.Krier@Sun.COM 40311337SWilliam.Krier@Sun.COM if ((domain.di_type != SMB_DOMAIN_BUILTIN) && 40411337SWilliam.Krier@Sun.COM (domain.di_type != SMB_DOMAIN_LOCAL)) { 40511337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 40611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 40711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 40811337SWilliam.Krier@Sun.COM } 40911337SWilliam.Krier@Sun.COM 41011337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_DOMAIN, domain.di_type, 0); 41111337SWilliam.Krier@Sun.COM if (id) { 41211337SWilliam.Krier@Sun.COM bcopy(id, ¶m->domain_handle, sizeof (samr_handle_t)); 41311337SWilliam.Krier@Sun.COM param->status = 0; 41411337SWilliam.Krier@Sun.COM } else { 41511337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 41611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 41711337SWilliam.Krier@Sun.COM } 41811337SWilliam.Krier@Sun.COM 41911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 42011337SWilliam.Krier@Sun.COM } 42111337SWilliam.Krier@Sun.COM 42211337SWilliam.Krier@Sun.COM /* 42311337SWilliam.Krier@Sun.COM * samr_s_QueryDomainInfo 42411337SWilliam.Krier@Sun.COM * 42511337SWilliam.Krier@Sun.COM * The caller should pass a domain handle. 42611337SWilliam.Krier@Sun.COM * 42711337SWilliam.Krier@Sun.COM * Windows 95 Server Manager sends requests for levels 6 and 7 when 42811337SWilliam.Krier@Sun.COM * the services menu item is selected. Level 2 is basically for getting 42911337SWilliam.Krier@Sun.COM * number of users, groups, and aliases in a domain. 43011337SWilliam.Krier@Sun.COM * We have no information on what the various information levels mean. 43111337SWilliam.Krier@Sun.COM */ 43211337SWilliam.Krier@Sun.COM static int 43311337SWilliam.Krier@Sun.COM samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa) 43411337SWilliam.Krier@Sun.COM { 43511337SWilliam.Krier@Sun.COM struct samr_QueryDomainInfo *param = arg; 43611337SWilliam.Krier@Sun.COM struct samr_QueryDomainInfoRes *info; 43711337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 43811337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 43911337SWilliam.Krier@Sun.COM samr_keydata_t *data; 44011337SWilliam.Krier@Sun.COM char *domain; 44111337SWilliam.Krier@Sun.COM char hostname[NETBIOS_NAME_SZ]; 44211337SWilliam.Krier@Sun.COM int alias_cnt, user_cnt; 44311337SWilliam.Krier@Sun.COM int rc = 0; 44411337SWilliam.Krier@Sun.COM 44511337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 44611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 44711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 44811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 44911337SWilliam.Krier@Sun.COM } 45011337SWilliam.Krier@Sun.COM 45111337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_QueryDomainInfoRes); 45211337SWilliam.Krier@Sun.COM if (info == NULL) { 45311337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 45411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 45511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 45611337SWilliam.Krier@Sun.COM } 45711337SWilliam.Krier@Sun.COM info->switch_value = param->info_level; 45811337SWilliam.Krier@Sun.COM param->info = info; 45911337SWilliam.Krier@Sun.COM 46011337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 46111337SWilliam.Krier@Sun.COM 46211337SWilliam.Krier@Sun.COM switch (data->kd_type) { 46311337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 46411337SWilliam.Krier@Sun.COM domain = "BUILTIN"; 46511337SWilliam.Krier@Sun.COM user_cnt = 0; 46611337SWilliam.Krier@Sun.COM alias_cnt = smb_sam_grp_cnt(data->kd_type); 46711337SWilliam.Krier@Sun.COM break; 46811337SWilliam.Krier@Sun.COM 46911337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 47011337SWilliam.Krier@Sun.COM rc = smb_getnetbiosname(hostname, sizeof (hostname)); 47111337SWilliam.Krier@Sun.COM if (rc == 0) { 47211337SWilliam.Krier@Sun.COM domain = hostname; 47311337SWilliam.Krier@Sun.COM user_cnt = smb_sam_usr_cnt(); 47411337SWilliam.Krier@Sun.COM alias_cnt = smb_sam_grp_cnt(data->kd_type); 47511337SWilliam.Krier@Sun.COM } 47611337SWilliam.Krier@Sun.COM break; 47711337SWilliam.Krier@Sun.COM 47811337SWilliam.Krier@Sun.COM default: 47911337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 48011337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 48111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 48211337SWilliam.Krier@Sun.COM } 48311337SWilliam.Krier@Sun.COM 48411337SWilliam.Krier@Sun.COM if (rc != 0) { 48511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 48611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); 48711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 48811337SWilliam.Krier@Sun.COM } 48911337SWilliam.Krier@Sun.COM 49011337SWilliam.Krier@Sun.COM switch (param->info_level) { 49111337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_6: 49211337SWilliam.Krier@Sun.COM info->ru.info6.unknown1 = 0x00000000; 49311337SWilliam.Krier@Sun.COM info->ru.info6.unknown2 = 0x00147FB0; 49411337SWilliam.Krier@Sun.COM info->ru.info6.unknown3 = 0x00000000; 49511337SWilliam.Krier@Sun.COM info->ru.info6.unknown4 = 0x00000000; 49611337SWilliam.Krier@Sun.COM info->ru.info6.unknown5 = 0x00000000; 49711337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 49811337SWilliam.Krier@Sun.COM break; 49911337SWilliam.Krier@Sun.COM 50011337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_7: 50111337SWilliam.Krier@Sun.COM info->ru.info7.unknown1 = 0x00000003; 50211337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 50311337SWilliam.Krier@Sun.COM break; 50411337SWilliam.Krier@Sun.COM 50511337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_2: 50611337SWilliam.Krier@Sun.COM info->ru.info2.unknown1 = 0x00000000; 50711337SWilliam.Krier@Sun.COM info->ru.info2.unknown2 = 0x80000000; 50811337SWilliam.Krier@Sun.COM 50911337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "", 51011337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.s1)); 51111337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, domain, 51211337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.domain)); 51311337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "", 51411337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.s2)); 51511337SWilliam.Krier@Sun.COM 51611337SWilliam.Krier@Sun.COM info->ru.info2.sequence_num = 0x0000002B; 51711337SWilliam.Krier@Sun.COM info->ru.info2.unknown3 = 0x00000000; 51811337SWilliam.Krier@Sun.COM info->ru.info2.unknown4 = 0x00000001; 51911337SWilliam.Krier@Sun.COM info->ru.info2.unknown5 = 0x00000003; 52011337SWilliam.Krier@Sun.COM info->ru.info2.unknown6 = 0x00000001; 52111337SWilliam.Krier@Sun.COM info->ru.info2.num_users = user_cnt; 52211337SWilliam.Krier@Sun.COM info->ru.info2.num_groups = 0; 52311337SWilliam.Krier@Sun.COM info->ru.info2.num_aliases = alias_cnt; 52411337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 52511337SWilliam.Krier@Sun.COM break; 52611337SWilliam.Krier@Sun.COM 52711337SWilliam.Krier@Sun.COM default: 52811337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 52911337SWilliam.Krier@Sun.COM return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 53011337SWilliam.Krier@Sun.COM }; 53111337SWilliam.Krier@Sun.COM 53211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 53311337SWilliam.Krier@Sun.COM } 53411337SWilliam.Krier@Sun.COM 53511337SWilliam.Krier@Sun.COM /* 53611447Samw@Sun.COM * QueryInfoDomain2: Identical to QueryDomainInfo. 53711447Samw@Sun.COM */ 53811447Samw@Sun.COM static int 53911447Samw@Sun.COM samr_s_QueryInfoDomain2(void *arg, ndr_xa_t *mxa) 54011447Samw@Sun.COM { 54111447Samw@Sun.COM return (samr_s_QueryDomainInfo(arg, mxa)); 54211447Samw@Sun.COM } 54311447Samw@Sun.COM 54411447Samw@Sun.COM /* 54511337SWilliam.Krier@Sun.COM * Looks up the given name in the specified domain which could 54611337SWilliam.Krier@Sun.COM * be either the built-in or local domain. 54711337SWilliam.Krier@Sun.COM * 54811337SWilliam.Krier@Sun.COM * CAVEAT: this function should be able to handle a list of 54911337SWilliam.Krier@Sun.COM * names but currently it can only handle one name at a time. 55011337SWilliam.Krier@Sun.COM */ 55111337SWilliam.Krier@Sun.COM static int 55211337SWilliam.Krier@Sun.COM samr_s_LookupNames(void *arg, ndr_xa_t *mxa) 55311337SWilliam.Krier@Sun.COM { 55411337SWilliam.Krier@Sun.COM struct samr_LookupNames *param = arg; 55511337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 55611337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 55711337SWilliam.Krier@Sun.COM samr_keydata_t *data; 55811337SWilliam.Krier@Sun.COM smb_account_t account; 55911337SWilliam.Krier@Sun.COM smb_wka_t *wka; 56011337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 56111337SWilliam.Krier@Sun.COM 56211337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) 56311337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 56411337SWilliam.Krier@Sun.COM 56511337SWilliam.Krier@Sun.COM if (param->n_entry != 1) 56611337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 56711337SWilliam.Krier@Sun.COM 56811337SWilliam.Krier@Sun.COM if (param->name.str == NULL) { 56911337SWilliam.Krier@Sun.COM /* 57011337SWilliam.Krier@Sun.COM * Windows NT returns NT_STATUS_NONE_MAPPED. 57111337SWilliam.Krier@Sun.COM * Windows 2000 returns STATUS_INVALID_ACCOUNT_NAME. 57211337SWilliam.Krier@Sun.COM */ 57311337SWilliam.Krier@Sun.COM status = NT_STATUS_NONE_MAPPED; 57411337SWilliam.Krier@Sun.COM } 57511337SWilliam.Krier@Sun.COM 57611337SWilliam.Krier@Sun.COM if (status != NT_STATUS_SUCCESS) { 57711337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupNames)); 57811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 57911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 58011337SWilliam.Krier@Sun.COM } 58111337SWilliam.Krier@Sun.COM 58211337SWilliam.Krier@Sun.COM param->rids.rid = NDR_NEW(mxa, DWORD); 58311337SWilliam.Krier@Sun.COM param->rid_types.rid_type = NDR_NEW(mxa, DWORD); 58411337SWilliam.Krier@Sun.COM 58511337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 58611337SWilliam.Krier@Sun.COM 58711337SWilliam.Krier@Sun.COM switch (data->kd_type) { 58811337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 58911447Samw@Sun.COM wka = smb_wka_lookup_builtin((char *)param->name.str); 59011337SWilliam.Krier@Sun.COM if (wka != NULL) { 59111337SWilliam.Krier@Sun.COM param->rids.n_entry = 1; 59211337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(wka->wka_binsid, 59311337SWilliam.Krier@Sun.COM ¶m->rids.rid[0]); 59411337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 1; 59511337SWilliam.Krier@Sun.COM param->rid_types.rid_type[0] = wka->wka_type; 59611337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 59711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 59811337SWilliam.Krier@Sun.COM } 59911337SWilliam.Krier@Sun.COM break; 60011337SWilliam.Krier@Sun.COM 60111337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 60211337SWilliam.Krier@Sun.COM status = smb_sam_lookup_name(NULL, (char *)param->name.str, 60311337SWilliam.Krier@Sun.COM SidTypeUnknown, &account); 60411337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) { 60511337SWilliam.Krier@Sun.COM param->rids.n_entry = 1; 60611337SWilliam.Krier@Sun.COM param->rids.rid[0] = account.a_rid; 60711337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 1; 60811337SWilliam.Krier@Sun.COM param->rid_types.rid_type[0] = account.a_type; 60911337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 61011337SWilliam.Krier@Sun.COM smb_account_free(&account); 61111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 61211337SWilliam.Krier@Sun.COM } 61311337SWilliam.Krier@Sun.COM break; 61411337SWilliam.Krier@Sun.COM 61511337SWilliam.Krier@Sun.COM default: 61611337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupNames)); 61711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 61811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 61911337SWilliam.Krier@Sun.COM } 62011337SWilliam.Krier@Sun.COM 62111337SWilliam.Krier@Sun.COM param->rids.n_entry = 0; 62211337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 0; 62311337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NONE_MAPPED); 62411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 62511337SWilliam.Krier@Sun.COM } 62611337SWilliam.Krier@Sun.COM 62711337SWilliam.Krier@Sun.COM /* 62811337SWilliam.Krier@Sun.COM * samr_s_OpenUser 62911337SWilliam.Krier@Sun.COM * 63011337SWilliam.Krier@Sun.COM * This is a request to open a user within a specified domain in the 63111337SWilliam.Krier@Sun.COM * local SAM database. The caller must supply a valid domain handle, 63211337SWilliam.Krier@Sun.COM * obtained via a successful domain open request. The user is 63311337SWilliam.Krier@Sun.COM * specified by the rid in the request. 63411337SWilliam.Krier@Sun.COM */ 63511337SWilliam.Krier@Sun.COM static int 63611337SWilliam.Krier@Sun.COM samr_s_OpenUser(void *arg, ndr_xa_t *mxa) 63711337SWilliam.Krier@Sun.COM { 63811337SWilliam.Krier@Sun.COM struct samr_OpenUser *param = arg; 63911337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 64011337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 64111337SWilliam.Krier@Sun.COM samr_keydata_t *data; 64211337SWilliam.Krier@Sun.COM 64311337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 64411337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 64511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 64611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 64711337SWilliam.Krier@Sun.COM } 64811337SWilliam.Krier@Sun.COM 64911337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 65011337SWilliam.Krier@Sun.COM 65111337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_USER, data->kd_type, param->rid); 65211337SWilliam.Krier@Sun.COM if (id == NULL) { 65311337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 65411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 65511337SWilliam.Krier@Sun.COM } else { 65611337SWilliam.Krier@Sun.COM bcopy(id, ¶m->user_handle, sizeof (samr_handle_t)); 65711337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 65811337SWilliam.Krier@Sun.COM } 65911337SWilliam.Krier@Sun.COM 66011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 66111337SWilliam.Krier@Sun.COM } 66211337SWilliam.Krier@Sun.COM 66311337SWilliam.Krier@Sun.COM /* 66411337SWilliam.Krier@Sun.COM * samr_s_DeleteUser 66511337SWilliam.Krier@Sun.COM * 66611337SWilliam.Krier@Sun.COM * Request to delete a user within a specified domain in the local 66711337SWilliam.Krier@Sun.COM * SAM database. The caller should supply a valid user handle. 66811337SWilliam.Krier@Sun.COM */ 66911337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 67011337SWilliam.Krier@Sun.COM static int 67111337SWilliam.Krier@Sun.COM samr_s_DeleteUser(void *arg, ndr_xa_t *mxa) 67211337SWilliam.Krier@Sun.COM { 67311337SWilliam.Krier@Sun.COM struct samr_DeleteUser *param = arg; 67411337SWilliam.Krier@Sun.COM 67511337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteUser)); 67611337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 67711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 67811337SWilliam.Krier@Sun.COM } 67911337SWilliam.Krier@Sun.COM 68011337SWilliam.Krier@Sun.COM /* 68111337SWilliam.Krier@Sun.COM * samr_s_QueryUserInfo 68211337SWilliam.Krier@Sun.COM * 68311337SWilliam.Krier@Sun.COM * Returns: 68411337SWilliam.Krier@Sun.COM * NT_STATUS_SUCCESS 68511337SWilliam.Krier@Sun.COM * NT_STATUS_ACCESS_DENIED 68611337SWilliam.Krier@Sun.COM * NT_STATUS_INVALID_INFO_CLASS 68711337SWilliam.Krier@Sun.COM */ 68811337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 68911337SWilliam.Krier@Sun.COM static int 69011337SWilliam.Krier@Sun.COM samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa) 69111337SWilliam.Krier@Sun.COM { 69211337SWilliam.Krier@Sun.COM static uint16_t owf_buf[8]; 69311337SWilliam.Krier@Sun.COM static uint8_t hour_buf[SAMR_SET_USER_HOURS_SZ]; 69411337SWilliam.Krier@Sun.COM struct samr_QueryUserInfo *param = arg; 69511337SWilliam.Krier@Sun.COM struct samr_QueryUserInfo21 *all_info; 69611337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 69711337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 69811337SWilliam.Krier@Sun.COM samr_keydata_t *data; 69911337SWilliam.Krier@Sun.COM smb_domain_t di; 70011337SWilliam.Krier@Sun.COM smb_account_t account; 70111337SWilliam.Krier@Sun.COM smb_sid_t *sid; 70211337SWilliam.Krier@Sun.COM uint32_t status; 70311337SWilliam.Krier@Sun.COM 70411337SWilliam.Krier@Sun.COM id = (ndr_hdid_t *)¶m->user_handle; 70511337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) { 70611337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 70711337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 70811337SWilliam.Krier@Sun.COM } 70911337SWilliam.Krier@Sun.COM 71011337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 71111337SWilliam.Krier@Sun.COM 71211337SWilliam.Krier@Sun.COM if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) { 71311337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 71411337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 71511337SWilliam.Krier@Sun.COM } 71611337SWilliam.Krier@Sun.COM 71711337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) { 71811337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 71911337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 72011337SWilliam.Krier@Sun.COM } 72111337SWilliam.Krier@Sun.COM 72211337SWilliam.Krier@Sun.COM if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) { 72311337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 72411337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 72511337SWilliam.Krier@Sun.COM } 72611337SWilliam.Krier@Sun.COM 72711337SWilliam.Krier@Sun.COM if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) { 72811337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 72911337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 73011337SWilliam.Krier@Sun.COM } 73111337SWilliam.Krier@Sun.COM 73211337SWilliam.Krier@Sun.COM all_info = ¶m->ru.info21; 73311337SWilliam.Krier@Sun.COM bzero(all_info, sizeof (struct samr_QueryUserInfo21)); 73411337SWilliam.Krier@Sun.COM 73511337SWilliam.Krier@Sun.COM all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID; 73611337SWilliam.Krier@Sun.COM 73711337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, account.a_name, 73811337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&all_info->UserName); 73911337SWilliam.Krier@Sun.COM all_info->UserId = data->kd_rid; 74011337SWilliam.Krier@Sun.COM 74111337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.length = 16; 74211337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.maxlen = 16; 74311337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.buf = owf_buf; 74411337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.length = 16; 74511337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.maxlen = 16; 74611337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.buf = owf_buf; 74711337SWilliam.Krier@Sun.COM all_info->LogonHours.units_per_week = SAMR_HOURS_PER_WEEK; 74811337SWilliam.Krier@Sun.COM all_info->LogonHours.hours = hour_buf; 74911337SWilliam.Krier@Sun.COM 75011337SWilliam.Krier@Sun.COM param->address = 1; 75111337SWilliam.Krier@Sun.COM param->switch_index = SAMR_QUERY_USER_ALL_INFO; 75211337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 75311963SAfshin.Ardakani@Sun.COM smb_account_free(&account); 75411963SAfshin.Ardakani@Sun.COM smb_sid_free(sid); 75511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 75611337SWilliam.Krier@Sun.COM 75711337SWilliam.Krier@Sun.COM QueryUserInfoError: 75811963SAfshin.Ardakani@Sun.COM smb_sid_free(sid); 75911337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryUserInfo)); 76011337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 76111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 76211337SWilliam.Krier@Sun.COM } 76311337SWilliam.Krier@Sun.COM 76411337SWilliam.Krier@Sun.COM /* 76511337SWilliam.Krier@Sun.COM * samr_s_QueryUserGroups 76611337SWilliam.Krier@Sun.COM * 76711337SWilliam.Krier@Sun.COM * Request the list of groups of which a user is a member. 76811337SWilliam.Krier@Sun.COM * The user is identified from the handle, which contains an 76911337SWilliam.Krier@Sun.COM * rid in the discriminator field. Note that this is a local user. 77011337SWilliam.Krier@Sun.COM */ 77111337SWilliam.Krier@Sun.COM static int 77211337SWilliam.Krier@Sun.COM samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa) 77311337SWilliam.Krier@Sun.COM { 77411337SWilliam.Krier@Sun.COM struct samr_QueryUserGroups *param = arg; 77511337SWilliam.Krier@Sun.COM struct samr_UserGroupInfo *info; 77611337SWilliam.Krier@Sun.COM struct samr_UserGroups *group; 77711337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->user_handle; 77811337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 77911337SWilliam.Krier@Sun.COM samr_keydata_t *data; 78011337SWilliam.Krier@Sun.COM smb_sid_t *user_sid = NULL; 78111337SWilliam.Krier@Sun.COM smb_group_t grp; 78211337SWilliam.Krier@Sun.COM smb_giter_t gi; 78311337SWilliam.Krier@Sun.COM smb_domain_t di; 78411337SWilliam.Krier@Sun.COM uint32_t status; 78511337SWilliam.Krier@Sun.COM int size; 78611337SWilliam.Krier@Sun.COM int ngrp_max; 78711337SWilliam.Krier@Sun.COM 78811337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) { 78911337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 79011337SWilliam.Krier@Sun.COM goto query_error; 79111337SWilliam.Krier@Sun.COM } 79211337SWilliam.Krier@Sun.COM 79311337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 79411337SWilliam.Krier@Sun.COM switch (data->kd_type) { 79511337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 79611337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 79711337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_type(data->kd_type, &di)) { 79811337SWilliam.Krier@Sun.COM status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 79911337SWilliam.Krier@Sun.COM goto query_error; 80011337SWilliam.Krier@Sun.COM } 80111337SWilliam.Krier@Sun.COM break; 80211337SWilliam.Krier@Sun.COM default: 80311337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 80411337SWilliam.Krier@Sun.COM goto query_error; 80511337SWilliam.Krier@Sun.COM } 80611337SWilliam.Krier@Sun.COM 80711337SWilliam.Krier@Sun.COM user_sid = smb_sid_splice(di.di_binsid, data->kd_rid); 80811337SWilliam.Krier@Sun.COM if (user_sid == NULL) { 80911337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 81011337SWilliam.Krier@Sun.COM goto query_error; 81111337SWilliam.Krier@Sun.COM } 81211337SWilliam.Krier@Sun.COM 81311337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_UserGroupInfo); 81411337SWilliam.Krier@Sun.COM if (info == NULL) { 81511337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 81611337SWilliam.Krier@Sun.COM goto query_error; 81711337SWilliam.Krier@Sun.COM } 81811337SWilliam.Krier@Sun.COM bzero(info, sizeof (struct samr_UserGroupInfo)); 81911337SWilliam.Krier@Sun.COM 82011337SWilliam.Krier@Sun.COM size = 32 * 1024; 82111337SWilliam.Krier@Sun.COM info->groups = NDR_MALLOC(mxa, size); 82211337SWilliam.Krier@Sun.COM if (info->groups == NULL) { 82311337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 82411337SWilliam.Krier@Sun.COM goto query_error; 82511337SWilliam.Krier@Sun.COM } 82611337SWilliam.Krier@Sun.COM ngrp_max = size / sizeof (struct samr_UserGroups); 82711337SWilliam.Krier@Sun.COM 82811337SWilliam.Krier@Sun.COM if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 82911337SWilliam.Krier@Sun.COM status = NT_STATUS_INTERNAL_ERROR; 83011337SWilliam.Krier@Sun.COM goto query_error; 83111337SWilliam.Krier@Sun.COM } 83211337SWilliam.Krier@Sun.COM 83311337SWilliam.Krier@Sun.COM info->n_entry = 0; 83411337SWilliam.Krier@Sun.COM group = info->groups; 83511337SWilliam.Krier@Sun.COM while ((info->n_entry < ngrp_max) && 83611337SWilliam.Krier@Sun.COM (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS)) { 83711337SWilliam.Krier@Sun.COM if (smb_lgrp_is_member(&grp, user_sid)) { 83811337SWilliam.Krier@Sun.COM group->rid = grp.sg_rid; 83911337SWilliam.Krier@Sun.COM group->attr = grp.sg_attr; 84011337SWilliam.Krier@Sun.COM group++; 84111337SWilliam.Krier@Sun.COM info->n_entry++; 84211337SWilliam.Krier@Sun.COM } 84311337SWilliam.Krier@Sun.COM smb_lgrp_free(&grp); 84411337SWilliam.Krier@Sun.COM } 84511337SWilliam.Krier@Sun.COM smb_lgrp_iterclose(&gi); 84611337SWilliam.Krier@Sun.COM 84711337SWilliam.Krier@Sun.COM free(user_sid); 84811337SWilliam.Krier@Sun.COM param->info = info; 84911337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 85011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 85111337SWilliam.Krier@Sun.COM 85211337SWilliam.Krier@Sun.COM query_error: 85311337SWilliam.Krier@Sun.COM free(user_sid); 85411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryUserGroups)); 85511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 85611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 85711337SWilliam.Krier@Sun.COM } 85811337SWilliam.Krier@Sun.COM 85911337SWilliam.Krier@Sun.COM /* 86011337SWilliam.Krier@Sun.COM * samr_s_OpenGroup 86111337SWilliam.Krier@Sun.COM * 86211337SWilliam.Krier@Sun.COM * This is a request to open a group within the specified domain in the 86311337SWilliam.Krier@Sun.COM * local SAM database. The caller must supply a valid domain handle, 86411337SWilliam.Krier@Sun.COM * obtained via a successful domain open request. The group is 86511337SWilliam.Krier@Sun.COM * specified by the rid in the request. If this is a local RID it 86611337SWilliam.Krier@Sun.COM * should already be encoded with type information. 86711337SWilliam.Krier@Sun.COM * 86811337SWilliam.Krier@Sun.COM * We return a handle to be used to access information about this group. 86911337SWilliam.Krier@Sun.COM */ 87011337SWilliam.Krier@Sun.COM static int 87111337SWilliam.Krier@Sun.COM samr_s_OpenGroup(void *arg, ndr_xa_t *mxa) 87211337SWilliam.Krier@Sun.COM { 87311337SWilliam.Krier@Sun.COM struct samr_OpenGroup *param = arg; 87411337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 87511337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 87611337SWilliam.Krier@Sun.COM samr_keydata_t *data; 87711337SWilliam.Krier@Sun.COM 87811337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 87911337SWilliam.Krier@Sun.COM bzero(¶m->group_handle, sizeof (samr_handle_t)); 88011337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 88111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 88211337SWilliam.Krier@Sun.COM } 88311337SWilliam.Krier@Sun.COM 88411337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 88511337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_GROUP, data->kd_type, param->rid); 88611337SWilliam.Krier@Sun.COM 88711337SWilliam.Krier@Sun.COM if (id) { 88811337SWilliam.Krier@Sun.COM bcopy(id, ¶m->group_handle, sizeof (samr_handle_t)); 88911337SWilliam.Krier@Sun.COM param->status = 0; 89011337SWilliam.Krier@Sun.COM } else { 89111337SWilliam.Krier@Sun.COM bzero(¶m->group_handle, sizeof (samr_handle_t)); 89211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 89311337SWilliam.Krier@Sun.COM } 89411337SWilliam.Krier@Sun.COM 89511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 89611337SWilliam.Krier@Sun.COM } 89711337SWilliam.Krier@Sun.COM 89811337SWilliam.Krier@Sun.COM /* 899*12065SKeyur.Desai@Sun.COM * samr_s_AddAliasMember 900*12065SKeyur.Desai@Sun.COM * 901*12065SKeyur.Desai@Sun.COM * Add a member to a local SAM group. 902*12065SKeyur.Desai@Sun.COM * The caller must supply a valid group handle. 903*12065SKeyur.Desai@Sun.COM * The member is specified by the sid in the request. 904*12065SKeyur.Desai@Sun.COM */ 905*12065SKeyur.Desai@Sun.COM static int 906*12065SKeyur.Desai@Sun.COM samr_s_AddAliasMember(void *arg, ndr_xa_t *mxa) 907*12065SKeyur.Desai@Sun.COM { 908*12065SKeyur.Desai@Sun.COM struct samr_AddAliasMember *param = arg; 909*12065SKeyur.Desai@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 910*12065SKeyur.Desai@Sun.COM ndr_handle_t *hd; 911*12065SKeyur.Desai@Sun.COM samr_keydata_t *data; 912*12065SKeyur.Desai@Sun.COM smb_group_t grp; 913*12065SKeyur.Desai@Sun.COM uint32_t rc; 914*12065SKeyur.Desai@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 915*12065SKeyur.Desai@Sun.COM 916*12065SKeyur.Desai@Sun.COM if (param->sid == NULL) { 917*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_AddAliasMember)); 918*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 919*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 920*12065SKeyur.Desai@Sun.COM } 921*12065SKeyur.Desai@Sun.COM 922*12065SKeyur.Desai@Sun.COM if (!ndr_is_admin(mxa)) { 923*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_AddAliasMember)); 924*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 925*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 926*12065SKeyur.Desai@Sun.COM } 927*12065SKeyur.Desai@Sun.COM 928*12065SKeyur.Desai@Sun.COM 929*12065SKeyur.Desai@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 930*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_AddAliasMember)); 931*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 932*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 933*12065SKeyur.Desai@Sun.COM } 934*12065SKeyur.Desai@Sun.COM 935*12065SKeyur.Desai@Sun.COM data = (samr_keydata_t *)hd->nh_data; 936*12065SKeyur.Desai@Sun.COM rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp); 937*12065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 938*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_AddAliasMember)); 939*12065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 940*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 941*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 942*12065SKeyur.Desai@Sun.COM } 943*12065SKeyur.Desai@Sun.COM 944*12065SKeyur.Desai@Sun.COM rc = smb_lgrp_add_member(grp.sg_name, 945*12065SKeyur.Desai@Sun.COM (smb_sid_t *)param->sid, SidTypeUser); 946*12065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 947*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_AddAliasMember)); 948*12065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 949*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 950*12065SKeyur.Desai@Sun.COM } 951*12065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 952*12065SKeyur.Desai@Sun.COM 953*12065SKeyur.Desai@Sun.COM param->status = status; 954*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 955*12065SKeyur.Desai@Sun.COM } 956*12065SKeyur.Desai@Sun.COM 957*12065SKeyur.Desai@Sun.COM /* 958*12065SKeyur.Desai@Sun.COM * samr_s_DeleteAliasMember 959*12065SKeyur.Desai@Sun.COM * 960*12065SKeyur.Desai@Sun.COM * Delete a member from a local SAM group. 961*12065SKeyur.Desai@Sun.COM * The caller must supply a valid group handle. 962*12065SKeyur.Desai@Sun.COM * The member is specified by the sid in the request. 963*12065SKeyur.Desai@Sun.COM */ 964*12065SKeyur.Desai@Sun.COM static int 965*12065SKeyur.Desai@Sun.COM samr_s_DeleteAliasMember(void *arg, ndr_xa_t *mxa) 966*12065SKeyur.Desai@Sun.COM { 967*12065SKeyur.Desai@Sun.COM struct samr_DeleteAliasMember *param = arg; 968*12065SKeyur.Desai@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 969*12065SKeyur.Desai@Sun.COM ndr_handle_t *hd; 970*12065SKeyur.Desai@Sun.COM samr_keydata_t *data; 971*12065SKeyur.Desai@Sun.COM smb_group_t grp; 972*12065SKeyur.Desai@Sun.COM uint32_t rc; 973*12065SKeyur.Desai@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 974*12065SKeyur.Desai@Sun.COM 975*12065SKeyur.Desai@Sun.COM if (param->sid == NULL) { 976*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteAliasMember)); 977*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 978*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 979*12065SKeyur.Desai@Sun.COM } 980*12065SKeyur.Desai@Sun.COM 981*12065SKeyur.Desai@Sun.COM if (!ndr_is_admin(mxa)) { 982*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteAliasMember)); 983*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 984*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 985*12065SKeyur.Desai@Sun.COM } 986*12065SKeyur.Desai@Sun.COM 987*12065SKeyur.Desai@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 988*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteAliasMember)); 989*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 990*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 991*12065SKeyur.Desai@Sun.COM } 992*12065SKeyur.Desai@Sun.COM 993*12065SKeyur.Desai@Sun.COM data = (samr_keydata_t *)hd->nh_data; 994*12065SKeyur.Desai@Sun.COM rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp); 995*12065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 996*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteAliasMember)); 997*12065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 998*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 999*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 1000*12065SKeyur.Desai@Sun.COM } 1001*12065SKeyur.Desai@Sun.COM 1002*12065SKeyur.Desai@Sun.COM rc = smb_lgrp_del_member(grp.sg_name, 1003*12065SKeyur.Desai@Sun.COM (smb_sid_t *)param->sid, SidTypeUser); 1004*12065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 1005*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteAliasMember)); 1006*12065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 1007*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 1008*12065SKeyur.Desai@Sun.COM } 1009*12065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 1010*12065SKeyur.Desai@Sun.COM 1011*12065SKeyur.Desai@Sun.COM param->status = status; 1012*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 1013*12065SKeyur.Desai@Sun.COM } 1014*12065SKeyur.Desai@Sun.COM 1015*12065SKeyur.Desai@Sun.COM /* 1016*12065SKeyur.Desai@Sun.COM * samr_s_ListAliasMembers 1017*12065SKeyur.Desai@Sun.COM * 1018*12065SKeyur.Desai@Sun.COM * List members from a local SAM group. 1019*12065SKeyur.Desai@Sun.COM * The caller must supply a valid group handle. 1020*12065SKeyur.Desai@Sun.COM * A list of user SIDs in the specified group is returned to the caller. 1021*12065SKeyur.Desai@Sun.COM */ 1022*12065SKeyur.Desai@Sun.COM static int 1023*12065SKeyur.Desai@Sun.COM samr_s_ListAliasMembers(void *arg, ndr_xa_t *mxa) 1024*12065SKeyur.Desai@Sun.COM { 1025*12065SKeyur.Desai@Sun.COM struct samr_ListAliasMembers *param = arg; 1026*12065SKeyur.Desai@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1027*12065SKeyur.Desai@Sun.COM ndr_handle_t *hd; 1028*12065SKeyur.Desai@Sun.COM samr_keydata_t *data; 1029*12065SKeyur.Desai@Sun.COM smb_group_t grp; 1030*12065SKeyur.Desai@Sun.COM smb_gsid_t *members; 1031*12065SKeyur.Desai@Sun.COM struct samr_SidInfo info; 1032*12065SKeyur.Desai@Sun.COM struct samr_SidList *user; 1033*12065SKeyur.Desai@Sun.COM uint32_t num = 0, size; 1034*12065SKeyur.Desai@Sun.COM int i; 1035*12065SKeyur.Desai@Sun.COM uint32_t rc; 1036*12065SKeyur.Desai@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 1037*12065SKeyur.Desai@Sun.COM 1038*12065SKeyur.Desai@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 1039*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_ListAliasMembers)); 1040*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 1041*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 1042*12065SKeyur.Desai@Sun.COM } 1043*12065SKeyur.Desai@Sun.COM 1044*12065SKeyur.Desai@Sun.COM bzero(&info, sizeof (struct samr_SidInfo)); 1045*12065SKeyur.Desai@Sun.COM data = (samr_keydata_t *)hd->nh_data; 1046*12065SKeyur.Desai@Sun.COM rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp); 1047*12065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 1048*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_ListAliasMembers)); 1049*12065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 1050*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 1051*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 1052*12065SKeyur.Desai@Sun.COM } 1053*12065SKeyur.Desai@Sun.COM 1054*12065SKeyur.Desai@Sun.COM num = grp.sg_nmembers; 1055*12065SKeyur.Desai@Sun.COM members = grp.sg_members; 1056*12065SKeyur.Desai@Sun.COM size = num * sizeof (struct samr_SidList); 1057*12065SKeyur.Desai@Sun.COM info.sidlist = NDR_MALLOC(mxa, size); 1058*12065SKeyur.Desai@Sun.COM if (info.sidlist == NULL) { 1059*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_ListAliasMembers)); 1060*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1061*12065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 1062*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 1063*12065SKeyur.Desai@Sun.COM } 1064*12065SKeyur.Desai@Sun.COM 1065*12065SKeyur.Desai@Sun.COM info.n_entry = num; 1066*12065SKeyur.Desai@Sun.COM user = info.sidlist; 1067*12065SKeyur.Desai@Sun.COM for (i = 0; i < num; i++) { 1068*12065SKeyur.Desai@Sun.COM user->sid = (struct samr_sid *)NDR_SIDDUP(mxa, 1069*12065SKeyur.Desai@Sun.COM members[i].gs_sid); 1070*12065SKeyur.Desai@Sun.COM if (user->sid == NULL) { 1071*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_ListAliasMembers)); 1072*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1073*12065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 1074*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 1075*12065SKeyur.Desai@Sun.COM } 1076*12065SKeyur.Desai@Sun.COM user++; 1077*12065SKeyur.Desai@Sun.COM } 1078*12065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 1079*12065SKeyur.Desai@Sun.COM 1080*12065SKeyur.Desai@Sun.COM param->info = info; 1081*12065SKeyur.Desai@Sun.COM param->status = status; 1082*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 1083*12065SKeyur.Desai@Sun.COM } 1084*12065SKeyur.Desai@Sun.COM 1085*12065SKeyur.Desai@Sun.COM /* 108611337SWilliam.Krier@Sun.COM * samr_s_Connect 108711337SWilliam.Krier@Sun.COM * 108811337SWilliam.Krier@Sun.COM * This is a request to connect to the local SAM database. 108911337SWilliam.Krier@Sun.COM * We don't support any form of update request and our database doesn't 109011337SWilliam.Krier@Sun.COM * contain any private information, so there is little point in doing 109111337SWilliam.Krier@Sun.COM * any access access checking here. 109211337SWilliam.Krier@Sun.COM * 109311337SWilliam.Krier@Sun.COM * Return a handle for use with subsequent SAM requests. 109411337SWilliam.Krier@Sun.COM */ 109511337SWilliam.Krier@Sun.COM static int 109611337SWilliam.Krier@Sun.COM samr_s_Connect(void *arg, ndr_xa_t *mxa) 109711337SWilliam.Krier@Sun.COM { 109811337SWilliam.Krier@Sun.COM struct samr_Connect *param = arg; 109911337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 110011337SWilliam.Krier@Sun.COM 110111337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 110211337SWilliam.Krier@Sun.COM if (id) { 110311337SWilliam.Krier@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 110411337SWilliam.Krier@Sun.COM param->status = 0; 110511337SWilliam.Krier@Sun.COM } else { 110611337SWilliam.Krier@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 110711337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 110811337SWilliam.Krier@Sun.COM } 110911337SWilliam.Krier@Sun.COM 111011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 111111337SWilliam.Krier@Sun.COM } 111211337SWilliam.Krier@Sun.COM 111311337SWilliam.Krier@Sun.COM /* 111411337SWilliam.Krier@Sun.COM * samr_s_GetUserPwInfo 111511337SWilliam.Krier@Sun.COM * 111611447Samw@Sun.COM * Request for a user's password policy information. 111711337SWilliam.Krier@Sun.COM */ 111811337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 111911337SWilliam.Krier@Sun.COM static int 112011337SWilliam.Krier@Sun.COM samr_s_GetUserPwInfo(void *arg, ndr_xa_t *mxa) 112111337SWilliam.Krier@Sun.COM { 112211447Samw@Sun.COM static samr_password_info_t pwinfo; 112311447Samw@Sun.COM struct samr_GetUserPwInfo *param = arg; 112411337SWilliam.Krier@Sun.COM 112511447Samw@Sun.COM param->pwinfo = &pwinfo; 112611447Samw@Sun.COM param->status = NT_STATUS_SUCCESS; 112711337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 112811337SWilliam.Krier@Sun.COM } 112911337SWilliam.Krier@Sun.COM 113011337SWilliam.Krier@Sun.COM /* 113111337SWilliam.Krier@Sun.COM * samr_s_CreateUser 113211337SWilliam.Krier@Sun.COM */ 113311337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 113411337SWilliam.Krier@Sun.COM static int 113511337SWilliam.Krier@Sun.COM samr_s_CreateUser(void *arg, ndr_xa_t *mxa) 113611337SWilliam.Krier@Sun.COM { 113711337SWilliam.Krier@Sun.COM struct samr_CreateUser *param = arg; 113811337SWilliam.Krier@Sun.COM 113911337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 114011337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 114111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 114211337SWilliam.Krier@Sun.COM } 114311337SWilliam.Krier@Sun.COM 114411337SWilliam.Krier@Sun.COM /* 114511337SWilliam.Krier@Sun.COM * samr_s_ChangeUserPasswd 114611337SWilliam.Krier@Sun.COM */ 114711337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 114811337SWilliam.Krier@Sun.COM static int 114911337SWilliam.Krier@Sun.COM samr_s_ChangeUserPasswd(void *arg, ndr_xa_t *mxa) 115011337SWilliam.Krier@Sun.COM { 115111337SWilliam.Krier@Sun.COM struct samr_ChangeUserPasswd *param = arg; 115211337SWilliam.Krier@Sun.COM 115311337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_ChangeUserPasswd)); 115411337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 115511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 115611337SWilliam.Krier@Sun.COM } 115711337SWilliam.Krier@Sun.COM 115811337SWilliam.Krier@Sun.COM /* 115911337SWilliam.Krier@Sun.COM * samr_s_GetDomainPwInfo 116011447Samw@Sun.COM * 116111447Samw@Sun.COM * Request for the domain password policy information. 116211337SWilliam.Krier@Sun.COM */ 116311337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 116411337SWilliam.Krier@Sun.COM static int 116511337SWilliam.Krier@Sun.COM samr_s_GetDomainPwInfo(void *arg, ndr_xa_t *mxa) 116611337SWilliam.Krier@Sun.COM { 116711447Samw@Sun.COM static samr_password_info_t pwinfo; 116811447Samw@Sun.COM struct samr_GetDomainPwInfo *param = arg; 116911337SWilliam.Krier@Sun.COM 117011447Samw@Sun.COM param->pwinfo = &pwinfo; 117111447Samw@Sun.COM param->status = NT_STATUS_SUCCESS; 117211337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 117311337SWilliam.Krier@Sun.COM } 117411337SWilliam.Krier@Sun.COM 117511337SWilliam.Krier@Sun.COM /* 117611337SWilliam.Krier@Sun.COM * samr_s_SetUserInfo 117711337SWilliam.Krier@Sun.COM */ 117811337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 117911337SWilliam.Krier@Sun.COM static int 118011337SWilliam.Krier@Sun.COM samr_s_SetUserInfo(void *arg, ndr_xa_t *mxa) 118111337SWilliam.Krier@Sun.COM { 118211337SWilliam.Krier@Sun.COM struct samr_SetUserInfo *param = arg; 118311337SWilliam.Krier@Sun.COM 118411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_SetUserInfo)); 118511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 118611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 118711337SWilliam.Krier@Sun.COM } 118811337SWilliam.Krier@Sun.COM 118911337SWilliam.Krier@Sun.COM /* 119011337SWilliam.Krier@Sun.COM * samr_s_QueryDispInfo 119111337SWilliam.Krier@Sun.COM * 119211337SWilliam.Krier@Sun.COM * This function currently return local users' information only. 119311337SWilliam.Krier@Sun.COM * This RPC is called repeatedly until all the users info are 119411337SWilliam.Krier@Sun.COM * retrieved. 119511337SWilliam.Krier@Sun.COM * 119611337SWilliam.Krier@Sun.COM * The total count and the returned count are returned as total size 119711337SWilliam.Krier@Sun.COM * and returned size. The client doesn't seem to care. 119811337SWilliam.Krier@Sun.COM */ 119911337SWilliam.Krier@Sun.COM static int 120011337SWilliam.Krier@Sun.COM samr_s_QueryDispInfo(void *arg, ndr_xa_t *mxa) 120111337SWilliam.Krier@Sun.COM { 120211337SWilliam.Krier@Sun.COM struct samr_QueryDispInfo *param = arg; 120311337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 120411337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 120511337SWilliam.Krier@Sun.COM samr_keydata_t *data; 120611337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 120711337SWilliam.Krier@Sun.COM struct user_acct_info *user; 120811337SWilliam.Krier@Sun.COM smb_pwditer_t pwi; 120911337SWilliam.Krier@Sun.COM smb_luser_t *uinfo; 121011337SWilliam.Krier@Sun.COM int num_users; 121111337SWilliam.Krier@Sun.COM int start_idx; 121211337SWilliam.Krier@Sun.COM int max_retcnt, retcnt; 121311337SWilliam.Krier@Sun.COM int skip; 121411337SWilliam.Krier@Sun.COM 121511337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 121611337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 121711337SWilliam.Krier@Sun.COM goto error; 121811337SWilliam.Krier@Sun.COM } 121911337SWilliam.Krier@Sun.COM 122011337SWilliam.Krier@Sun.COM if (!SAMR_VALID_DISPLEVEL(param->level)) { 122111337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_INFO_CLASS; 122211337SWilliam.Krier@Sun.COM goto error; 122311337SWilliam.Krier@Sun.COM } 122411337SWilliam.Krier@Sun.COM 122511337SWilliam.Krier@Sun.COM if (!SAMR_SUPPORTED_DISPLEVEL(param->level)) { 122611337SWilliam.Krier@Sun.COM status = NT_STATUS_NOT_IMPLEMENTED; 122711337SWilliam.Krier@Sun.COM goto error; 122811337SWilliam.Krier@Sun.COM } 122911337SWilliam.Krier@Sun.COM 123011337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 123111337SWilliam.Krier@Sun.COM 123211337SWilliam.Krier@Sun.COM switch (data->kd_type) { 123311337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 123411337SWilliam.Krier@Sun.COM goto no_info; 123511337SWilliam.Krier@Sun.COM 123611337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 123711337SWilliam.Krier@Sun.COM num_users = smb_sam_usr_cnt(); 123811337SWilliam.Krier@Sun.COM start_idx = param->start_idx; 123911337SWilliam.Krier@Sun.COM if ((num_users == 0) || (start_idx >= num_users)) 124011337SWilliam.Krier@Sun.COM goto no_info; 124111337SWilliam.Krier@Sun.COM 124211337SWilliam.Krier@Sun.COM max_retcnt = num_users - start_idx; 124311337SWilliam.Krier@Sun.COM if (max_retcnt > param->max_entries) 124411337SWilliam.Krier@Sun.COM max_retcnt = param->max_entries; 124511337SWilliam.Krier@Sun.COM param->users.acct = NDR_MALLOC(mxa, 124611337SWilliam.Krier@Sun.COM max_retcnt * sizeof (struct user_acct_info)); 124711337SWilliam.Krier@Sun.COM user = param->users.acct; 124811337SWilliam.Krier@Sun.COM if (user == NULL) { 124911337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 125011337SWilliam.Krier@Sun.COM goto error; 125111337SWilliam.Krier@Sun.COM } 125211337SWilliam.Krier@Sun.COM bzero(user, max_retcnt * sizeof (struct user_acct_info)); 125311337SWilliam.Krier@Sun.COM 125411337SWilliam.Krier@Sun.COM if (smb_pwd_iteropen(&pwi) != SMB_PWE_SUCCESS) 125511337SWilliam.Krier@Sun.COM goto no_info; 125611337SWilliam.Krier@Sun.COM 125711337SWilliam.Krier@Sun.COM skip = retcnt = 0; 125811337SWilliam.Krier@Sun.COM while ((uinfo = smb_pwd_iterate(&pwi)) != NULL) { 125911337SWilliam.Krier@Sun.COM if (skip++ < start_idx) 126011337SWilliam.Krier@Sun.COM continue; 126111337SWilliam.Krier@Sun.COM 126211337SWilliam.Krier@Sun.COM if (retcnt++ >= max_retcnt) 126311337SWilliam.Krier@Sun.COM break; 126411337SWilliam.Krier@Sun.COM 126511337SWilliam.Krier@Sun.COM assert(uinfo->su_name != NULL); 126611337SWilliam.Krier@Sun.COM 126711337SWilliam.Krier@Sun.COM user->index = start_idx + retcnt; 126811337SWilliam.Krier@Sun.COM user->rid = uinfo->su_rid; 126911337SWilliam.Krier@Sun.COM user->ctrl = ACF_NORMUSER | ACF_PWDNOEXP; 127011337SWilliam.Krier@Sun.COM if (uinfo->su_ctrl & SMB_PWF_DISABLE) 127111337SWilliam.Krier@Sun.COM user->ctrl |= ACF_DISABLED; 127211337SWilliam.Krier@Sun.COM if (NDR_MSTRING(mxa, uinfo->su_name, 127311337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->name) == -1) { 127411337SWilliam.Krier@Sun.COM smb_pwd_iterclose(&pwi); 127511337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 127611337SWilliam.Krier@Sun.COM goto error; 127711337SWilliam.Krier@Sun.COM } 127811337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, uinfo->su_fullname, 127911337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->fullname); 128011337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, uinfo->su_desc, 128111337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->desc); 128211337SWilliam.Krier@Sun.COM user++; 128311337SWilliam.Krier@Sun.COM } 128411337SWilliam.Krier@Sun.COM smb_pwd_iterclose(&pwi); 128511337SWilliam.Krier@Sun.COM 128611337SWilliam.Krier@Sun.COM if (retcnt >= max_retcnt) { 128711337SWilliam.Krier@Sun.COM retcnt = max_retcnt; 128811337SWilliam.Krier@Sun.COM param->status = status; 128911337SWilliam.Krier@Sun.COM } else { 129011337SWilliam.Krier@Sun.COM param->status = ERROR_MORE_ENTRIES; 129111337SWilliam.Krier@Sun.COM } 129211337SWilliam.Krier@Sun.COM 129311337SWilliam.Krier@Sun.COM param->users.total_size = num_users; 129411337SWilliam.Krier@Sun.COM param->users.returned_size = retcnt; 129511337SWilliam.Krier@Sun.COM param->users.switch_value = param->level; 129611337SWilliam.Krier@Sun.COM param->users.count = retcnt; 129711337SWilliam.Krier@Sun.COM 129811337SWilliam.Krier@Sun.COM break; 129911337SWilliam.Krier@Sun.COM 130011337SWilliam.Krier@Sun.COM default: 130111337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 130211337SWilliam.Krier@Sun.COM goto error; 130311337SWilliam.Krier@Sun.COM } 130411337SWilliam.Krier@Sun.COM 130511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 130611337SWilliam.Krier@Sun.COM 130711337SWilliam.Krier@Sun.COM no_info: 130811337SWilliam.Krier@Sun.COM param->users.total_size = 0; 130911337SWilliam.Krier@Sun.COM param->users.returned_size = 0; 131011337SWilliam.Krier@Sun.COM param->users.switch_value = param->level; 131111337SWilliam.Krier@Sun.COM param->users.count = 0; 131211337SWilliam.Krier@Sun.COM param->users.acct = NULL; 131311337SWilliam.Krier@Sun.COM param->status = status; 131411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 131511337SWilliam.Krier@Sun.COM 131611337SWilliam.Krier@Sun.COM error: 131711337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDispInfo)); 131811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 131911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 132011337SWilliam.Krier@Sun.COM } 132111337SWilliam.Krier@Sun.COM 132211337SWilliam.Krier@Sun.COM /* 132311337SWilliam.Krier@Sun.COM * samr_s_EnumDomainGroups 132411337SWilliam.Krier@Sun.COM * 132511337SWilliam.Krier@Sun.COM * 132611337SWilliam.Krier@Sun.COM * This function is supposed to return local group information. 132711337SWilliam.Krier@Sun.COM * As we don't support local users, this function dosen't send 132811337SWilliam.Krier@Sun.COM * back any information. 132911337SWilliam.Krier@Sun.COM * 133011337SWilliam.Krier@Sun.COM * Added template that returns information for a domain group as None. 133111337SWilliam.Krier@Sun.COM * All information is hard-coded from packet captures. 133211337SWilliam.Krier@Sun.COM */ 133311337SWilliam.Krier@Sun.COM static int 133411337SWilliam.Krier@Sun.COM samr_s_EnumDomainGroups(void *arg, ndr_xa_t *mxa) 133511337SWilliam.Krier@Sun.COM { 133611337SWilliam.Krier@Sun.COM struct samr_EnumDomainGroups *param = arg; 133711337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 133811337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 133911337SWilliam.Krier@Sun.COM 134011337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) 134111337SWilliam.Krier@Sun.COM status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 134211337SWilliam.Krier@Sun.COM 134311337SWilliam.Krier@Sun.COM param->total_size = 0; 134411337SWilliam.Krier@Sun.COM param->returned_size = 0; 134511337SWilliam.Krier@Sun.COM param->switch_value = 3; 134611337SWilliam.Krier@Sun.COM param->count = 0; 134711337SWilliam.Krier@Sun.COM param->groups = 0; 134811337SWilliam.Krier@Sun.COM param->status = status; 134911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 135011337SWilliam.Krier@Sun.COM 135111337SWilliam.Krier@Sun.COM #ifdef SAMR_SUPPORT_GROUPS 135211337SWilliam.Krier@Sun.COM if ((desc->discrim != SAMR_LOCAL_DOMAIN) || (param->start_idx != 0)) { 135311337SWilliam.Krier@Sun.COM param->total_size = 0; 135411337SWilliam.Krier@Sun.COM param->returned_size = 0; 135511337SWilliam.Krier@Sun.COM param->switch_value = 3; 135611337SWilliam.Krier@Sun.COM param->count = 0; 135711337SWilliam.Krier@Sun.COM param->groups = 0; 135811337SWilliam.Krier@Sun.COM } else { 135911337SWilliam.Krier@Sun.COM param->total_size = 64; 136011337SWilliam.Krier@Sun.COM param->returned_size = 64; 136111337SWilliam.Krier@Sun.COM param->switch_value = 3; 136211337SWilliam.Krier@Sun.COM param->count = 1; 136311337SWilliam.Krier@Sun.COM param->groups = (struct group_disp_info *)NDR_MALLOC( 136411337SWilliam.Krier@Sun.COM mxa, sizeof (struct group_disp_info)); 136511337SWilliam.Krier@Sun.COM 136611337SWilliam.Krier@Sun.COM param->groups->count = 1; 136711337SWilliam.Krier@Sun.COM param->groups->acct[0].index = 1; 136811337SWilliam.Krier@Sun.COM param->groups->acct[0].rid = 513; 136911337SWilliam.Krier@Sun.COM param->groups->acct[0].ctrl = 0x7; 137011337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "None", 137111337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->groups->acct[0].name); 137211337SWilliam.Krier@Sun.COM 137311337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "Ordinary users", 137411337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->groups->acct[0].desc); 137511337SWilliam.Krier@Sun.COM } 137611337SWilliam.Krier@Sun.COM 137711337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 137811337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 137911337SWilliam.Krier@Sun.COM #endif 138011337SWilliam.Krier@Sun.COM } 138111337SWilliam.Krier@Sun.COM 138211337SWilliam.Krier@Sun.COM /* 138311337SWilliam.Krier@Sun.COM * samr_s_OpenAlias 138411337SWilliam.Krier@Sun.COM * 138511337SWilliam.Krier@Sun.COM * Lookup for requested alias, if it exists return a handle 138611337SWilliam.Krier@Sun.COM * for that alias. The alias domain sid should match with 138711337SWilliam.Krier@Sun.COM * the passed domain handle. 138811337SWilliam.Krier@Sun.COM */ 138911337SWilliam.Krier@Sun.COM static int 139011337SWilliam.Krier@Sun.COM samr_s_OpenAlias(void *arg, ndr_xa_t *mxa) 139111337SWilliam.Krier@Sun.COM { 139211337SWilliam.Krier@Sun.COM struct samr_OpenAlias *param = arg; 139311447Samw@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 139411447Samw@Sun.COM ndr_handle_t *hd; 139511447Samw@Sun.COM samr_keydata_t *data; 139611963SAfshin.Ardakani@Sun.COM smb_domain_type_t gd_type; 139711447Samw@Sun.COM smb_sid_t *sid; 139811447Samw@Sun.COM smb_wka_t *wka; 139911447Samw@Sun.COM char sidstr[SMB_SID_STRSZ]; 140011447Samw@Sun.COM uint32_t rid; 140111447Samw@Sun.COM uint32_t status; 140211447Samw@Sun.COM int rc; 140311337SWilliam.Krier@Sun.COM 140411337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 140511337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 140611337SWilliam.Krier@Sun.COM goto open_alias_err; 140711337SWilliam.Krier@Sun.COM } 140811337SWilliam.Krier@Sun.COM 1409*12065SKeyur.Desai@Sun.COM if ((param->access_mask & SAMR_ALIAS_ACCESS_ALL_ACCESS) == 0) { 141011337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 141111337SWilliam.Krier@Sun.COM goto open_alias_err; 141211337SWilliam.Krier@Sun.COM } 141311337SWilliam.Krier@Sun.COM 141411337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 141511963SAfshin.Ardakani@Sun.COM gd_type = (smb_domain_type_t)data->kd_type; 141611447Samw@Sun.COM rid = param->rid; 141711447Samw@Sun.COM 141811447Samw@Sun.COM switch (gd_type) { 141911963SAfshin.Ardakani@Sun.COM case SMB_DOMAIN_BUILTIN: 142011447Samw@Sun.COM (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d", 142111447Samw@Sun.COM NT_BUILTIN_DOMAIN_SIDSTR, rid); 142211447Samw@Sun.COM if ((sid = smb_sid_fromstr(sidstr)) == NULL) { 142311447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 142411447Samw@Sun.COM goto open_alias_err; 142511447Samw@Sun.COM } 142611447Samw@Sun.COM 142711447Samw@Sun.COM wka = smb_wka_lookup_sid(sid); 142811447Samw@Sun.COM smb_sid_free(sid); 142911447Samw@Sun.COM 143011447Samw@Sun.COM if (wka == NULL) { 143111447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 143211447Samw@Sun.COM goto open_alias_err; 143311447Samw@Sun.COM } 143411447Samw@Sun.COM break; 143511447Samw@Sun.COM 143611963SAfshin.Ardakani@Sun.COM case SMB_DOMAIN_LOCAL: 143711447Samw@Sun.COM rc = smb_lgrp_getbyrid(rid, gd_type, NULL); 143811447Samw@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 143911447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 144011447Samw@Sun.COM goto open_alias_err; 144111447Samw@Sun.COM } 144211447Samw@Sun.COM break; 144311447Samw@Sun.COM 144411447Samw@Sun.COM default: 144511337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 144611337SWilliam.Krier@Sun.COM goto open_alias_err; 144711337SWilliam.Krier@Sun.COM } 144811337SWilliam.Krier@Sun.COM 144911337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, data->kd_type, param->rid); 145011337SWilliam.Krier@Sun.COM if (id) { 145111337SWilliam.Krier@Sun.COM bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t)); 145211337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 145311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 145411337SWilliam.Krier@Sun.COM } 145511337SWilliam.Krier@Sun.COM 145611337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 145711337SWilliam.Krier@Sun.COM 145811337SWilliam.Krier@Sun.COM open_alias_err: 145911337SWilliam.Krier@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 146011337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 146111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 146211337SWilliam.Krier@Sun.COM } 146311337SWilliam.Krier@Sun.COM 146411337SWilliam.Krier@Sun.COM /* 146511337SWilliam.Krier@Sun.COM * samr_s_CreateDomainAlias 146611337SWilliam.Krier@Sun.COM * 1467*12065SKeyur.Desai@Sun.COM * Create a local group in the security accounts manager (SAM) database. 1468*12065SKeyur.Desai@Sun.COM * A local SAM group can only be added if a Solaris group already exists 1469*12065SKeyur.Desai@Sun.COM * with the same name. On success, a valid group handle is returned. 1470*12065SKeyur.Desai@Sun.COM * 1471*12065SKeyur.Desai@Sun.COM * The caller must have administrator rights to execute this function. 147211337SWilliam.Krier@Sun.COM */ 147311337SWilliam.Krier@Sun.COM static int 147411337SWilliam.Krier@Sun.COM samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa) 147511337SWilliam.Krier@Sun.COM { 147611337SWilliam.Krier@Sun.COM struct samr_CreateDomainAlias *param = arg; 147711337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1478*12065SKeyur.Desai@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 1479*12065SKeyur.Desai@Sun.COM smb_group_t grp; 1480*12065SKeyur.Desai@Sun.COM uint32_t rc; 1481*12065SKeyur.Desai@Sun.COM char *gname; 148211337SWilliam.Krier@Sun.COM 1483*12065SKeyur.Desai@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) != NULL) { 148411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_CreateDomainAlias)); 148511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 148611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 148711337SWilliam.Krier@Sun.COM } 148811337SWilliam.Krier@Sun.COM 1489*12065SKeyur.Desai@Sun.COM gname = (char *)param->alias_name.str; 1490*12065SKeyur.Desai@Sun.COM if (gname == NULL) { 1491*12065SKeyur.Desai@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1492*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 1493*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 1494*12065SKeyur.Desai@Sun.COM } 149511337SWilliam.Krier@Sun.COM 1496*12065SKeyur.Desai@Sun.COM if ((!ndr_is_admin(mxa)) || 1497*12065SKeyur.Desai@Sun.COM ((param->access_mask & SAMR_ALIAS_ACCESS_WRITE_ACCOUNT) == 0)) { 1498*12065SKeyur.Desai@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1499*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 1500*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 1501*12065SKeyur.Desai@Sun.COM } 150211337SWilliam.Krier@Sun.COM 1503*12065SKeyur.Desai@Sun.COM if (getgrnam(gname) == NULL) { 1504*12065SKeyur.Desai@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1505*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 1506*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 150711337SWilliam.Krier@Sun.COM } 150811337SWilliam.Krier@Sun.COM 1509*12065SKeyur.Desai@Sun.COM rc = smb_lgrp_add(gname, ""); 1510*12065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 1511*12065SKeyur.Desai@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1512*12065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 1513*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 1514*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 151511337SWilliam.Krier@Sun.COM } 151611337SWilliam.Krier@Sun.COM 1517*12065SKeyur.Desai@Sun.COM rc = smb_lgrp_getbyname((char *)gname, &grp); 1518*12065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 1519*12065SKeyur.Desai@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1520*12065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 1521*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(status); 1522*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 1523*12065SKeyur.Desai@Sun.COM } 152411337SWilliam.Krier@Sun.COM 1525*12065SKeyur.Desai@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, SMB_DOMAIN_LOCAL, grp.sg_rid); 1526*12065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 1527*12065SKeyur.Desai@Sun.COM if (id) { 1528*12065SKeyur.Desai@Sun.COM bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t)); 1529*12065SKeyur.Desai@Sun.COM param->status = status; 1530*12065SKeyur.Desai@Sun.COM } else { 1531*12065SKeyur.Desai@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1532*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1533*12065SKeyur.Desai@Sun.COM } 153411337SWilliam.Krier@Sun.COM 153511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 153611337SWilliam.Krier@Sun.COM } 153711337SWilliam.Krier@Sun.COM 153811337SWilliam.Krier@Sun.COM /* 153911337SWilliam.Krier@Sun.COM * samr_s_SetAliasInfo 154011337SWilliam.Krier@Sun.COM * 154111337SWilliam.Krier@Sun.COM * Similar to NetLocalGroupSetInfo. 154211337SWilliam.Krier@Sun.COM */ 154311337SWilliam.Krier@Sun.COM static int 154411337SWilliam.Krier@Sun.COM samr_s_SetAliasInfo(void *arg, ndr_xa_t *mxa) 154511337SWilliam.Krier@Sun.COM { 154611337SWilliam.Krier@Sun.COM struct samr_SetAliasInfo *param = arg; 154711337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 154811337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 154911337SWilliam.Krier@Sun.COM 155011337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) 155111337SWilliam.Krier@Sun.COM status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 155211337SWilliam.Krier@Sun.COM 155311337SWilliam.Krier@Sun.COM param->status = status; 155411337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 155511337SWilliam.Krier@Sun.COM } 155611337SWilliam.Krier@Sun.COM 155711337SWilliam.Krier@Sun.COM /* 155811337SWilliam.Krier@Sun.COM * samr_s_QueryAliasInfo 155911337SWilliam.Krier@Sun.COM * 156011337SWilliam.Krier@Sun.COM * Retrieves information about the specified local group account 156111337SWilliam.Krier@Sun.COM * by given handle. 156211337SWilliam.Krier@Sun.COM */ 156311337SWilliam.Krier@Sun.COM static int 156411337SWilliam.Krier@Sun.COM samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa) 156511337SWilliam.Krier@Sun.COM { 156611337SWilliam.Krier@Sun.COM struct samr_QueryAliasInfo *param = arg; 156711447Samw@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 156811447Samw@Sun.COM ndr_handle_t *hd; 156911447Samw@Sun.COM samr_keydata_t *data; 157011447Samw@Sun.COM smb_group_t grp; 157111963SAfshin.Ardakani@Sun.COM smb_domain_type_t gd_type; 157211447Samw@Sun.COM smb_sid_t *sid; 157311447Samw@Sun.COM smb_wka_t *wka; 157411447Samw@Sun.COM char sidstr[SMB_SID_STRSZ]; 157511447Samw@Sun.COM char *name; 157611447Samw@Sun.COM char *desc; 157711447Samw@Sun.COM uint32_t rid; 157811447Samw@Sun.COM uint32_t status; 157911447Samw@Sun.COM int rc; 158011337SWilliam.Krier@Sun.COM 158111337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 158211337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 158311337SWilliam.Krier@Sun.COM goto query_alias_err; 158411337SWilliam.Krier@Sun.COM } 158511337SWilliam.Krier@Sun.COM 158611337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 158711963SAfshin.Ardakani@Sun.COM gd_type = (smb_domain_type_t)data->kd_type; 158811447Samw@Sun.COM rid = data->kd_rid; 158911447Samw@Sun.COM 159011447Samw@Sun.COM switch (gd_type) { 159111963SAfshin.Ardakani@Sun.COM case SMB_DOMAIN_BUILTIN: 159211447Samw@Sun.COM (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d", 159311447Samw@Sun.COM NT_BUILTIN_DOMAIN_SIDSTR, rid); 159411447Samw@Sun.COM if ((sid = smb_sid_fromstr(sidstr)) == NULL) { 159511447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 159611447Samw@Sun.COM goto query_alias_err; 159711447Samw@Sun.COM } 159811447Samw@Sun.COM 159911447Samw@Sun.COM wka = smb_wka_lookup_sid(sid); 160011447Samw@Sun.COM smb_sid_free(sid); 160111447Samw@Sun.COM 160211447Samw@Sun.COM if (wka == NULL) { 160311447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 160411447Samw@Sun.COM goto query_alias_err; 160511447Samw@Sun.COM } 160611447Samw@Sun.COM 160711447Samw@Sun.COM name = wka->wka_name; 160811447Samw@Sun.COM desc = (wka->wka_desc != NULL) ? wka->wka_desc : ""; 160911447Samw@Sun.COM break; 161011447Samw@Sun.COM 161111963SAfshin.Ardakani@Sun.COM case SMB_DOMAIN_LOCAL: 161211447Samw@Sun.COM rc = smb_lgrp_getbyrid(rid, gd_type, &grp); 161311447Samw@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 161411447Samw@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 161511447Samw@Sun.COM goto query_alias_err; 161611447Samw@Sun.COM } 161711447Samw@Sun.COM name = grp.sg_name; 161811447Samw@Sun.COM desc = grp.sg_cmnt; 161911447Samw@Sun.COM break; 162011447Samw@Sun.COM 162111447Samw@Sun.COM default: 162211337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 162311337SWilliam.Krier@Sun.COM goto query_alias_err; 162411337SWilliam.Krier@Sun.COM } 162511337SWilliam.Krier@Sun.COM 162611337SWilliam.Krier@Sun.COM switch (param->level) { 162711337SWilliam.Krier@Sun.COM case SAMR_QUERY_ALIAS_INFO_1: 162811337SWilliam.Krier@Sun.COM param->ru.info1.level = param->level; 162911447Samw@Sun.COM (void) NDR_MSTRING(mxa, name, 163011337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info1.name); 163111337SWilliam.Krier@Sun.COM 163211447Samw@Sun.COM (void) NDR_MSTRING(mxa, desc, 163311337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info1.desc); 163411337SWilliam.Krier@Sun.COM 163511337SWilliam.Krier@Sun.COM param->ru.info1.unknown = 1; 163611337SWilliam.Krier@Sun.COM break; 163711337SWilliam.Krier@Sun.COM 163811337SWilliam.Krier@Sun.COM case SAMR_QUERY_ALIAS_INFO_3: 163911337SWilliam.Krier@Sun.COM param->ru.info3.level = param->level; 164011447Samw@Sun.COM (void) NDR_MSTRING(mxa, desc, 164111337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info3.desc); 164211337SWilliam.Krier@Sun.COM break; 164311337SWilliam.Krier@Sun.COM 164411337SWilliam.Krier@Sun.COM default: 164511963SAfshin.Ardakani@Sun.COM if (gd_type == SMB_DOMAIN_LOCAL) 164611447Samw@Sun.COM smb_lgrp_free(&grp); 164711337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_INFO_CLASS; 164811337SWilliam.Krier@Sun.COM goto query_alias_err; 164911337SWilliam.Krier@Sun.COM }; 165011337SWilliam.Krier@Sun.COM 165111963SAfshin.Ardakani@Sun.COM if (gd_type == SMB_DOMAIN_LOCAL) 165211447Samw@Sun.COM smb_lgrp_free(&grp); 165311337SWilliam.Krier@Sun.COM param->address = (DWORD)(uintptr_t)¶m->ru; 165411337SWilliam.Krier@Sun.COM param->status = 0; 165511337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 165611337SWilliam.Krier@Sun.COM 165711337SWilliam.Krier@Sun.COM query_alias_err: 165811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 165911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 166011337SWilliam.Krier@Sun.COM } 166111337SWilliam.Krier@Sun.COM 166211337SWilliam.Krier@Sun.COM /* 166311337SWilliam.Krier@Sun.COM * samr_s_DeleteDomainAlias 166411337SWilliam.Krier@Sun.COM * 1665*12065SKeyur.Desai@Sun.COM * Deletes a local group in the security database, which is the 1666*12065SKeyur.Desai@Sun.COM * security accounts manager (SAM). A valid group handle is returned 1667*12065SKeyur.Desai@Sun.COM * to the caller upon success. 166811337SWilliam.Krier@Sun.COM * 1669*12065SKeyur.Desai@Sun.COM * The caller must have administrator rights to execute this function. 167011337SWilliam.Krier@Sun.COM */ 167111337SWilliam.Krier@Sun.COM static int 167211337SWilliam.Krier@Sun.COM samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa) 167311337SWilliam.Krier@Sun.COM { 167411337SWilliam.Krier@Sun.COM struct samr_DeleteDomainAlias *param = arg; 167511337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1676*12065SKeyur.Desai@Sun.COM ndr_handle_t *hd; 1677*12065SKeyur.Desai@Sun.COM smb_group_t grp; 1678*12065SKeyur.Desai@Sun.COM samr_keydata_t *data; 1679*12065SKeyur.Desai@Sun.COM smb_domain_type_t gd_type; 1680*12065SKeyur.Desai@Sun.COM uint32_t rid; 1681*12065SKeyur.Desai@Sun.COM uint32_t rc; 1682*12065SKeyur.Desai@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 168311337SWilliam.Krier@Sun.COM 1684*12065SKeyur.Desai@Sun.COM if (!ndr_is_admin(mxa)) { 1685*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1686*12065SKeyur.Desai@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 1687*12065SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 1688*12065SKeyur.Desai@Sun.COM } 1689*12065SKeyur.Desai@Sun.COM 1690*12065SKeyur.Desai@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 169111337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 169211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 169311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 169411337SWilliam.Krier@Sun.COM } 169511337SWilliam.Krier@Sun.COM 1696*12065SKeyur.Desai@Sun.COM data = (samr_keydata_t *)hd->nh_data; 1697*12065SKeyur.Desai@Sun.COM gd_type = (smb_domain_type_t)data->kd_type; 1698*12065SKeyur.Desai@Sun.COM rid = data->kd_rid; 1699*12065SKeyur.Desai@Sun.COM 1700*12065SKeyur.Desai@Sun.COM switch (gd_type) { 1701*12065SKeyur.Desai@Sun.COM case SMB_DOMAIN_BUILTIN: 1702*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1703*12065SKeyur.Desai@Sun.COM status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED); 1704*12065SKeyur.Desai@Sun.COM break; 170511337SWilliam.Krier@Sun.COM 1706*12065SKeyur.Desai@Sun.COM case SMB_DOMAIN_LOCAL: 1707*12065SKeyur.Desai@Sun.COM rc = smb_lgrp_getbyrid(rid, gd_type, &grp); 1708*12065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 1709*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1710*12065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 1711*12065SKeyur.Desai@Sun.COM status = NT_SC_ERROR(status); 1712*12065SKeyur.Desai@Sun.COM break; 1713*12065SKeyur.Desai@Sun.COM } 171411337SWilliam.Krier@Sun.COM 1715*12065SKeyur.Desai@Sun.COM rc = smb_lgrp_delete(grp.sg_name); 1716*12065SKeyur.Desai@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 1717*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1718*12065SKeyur.Desai@Sun.COM status = smb_lgrp_err_to_ntstatus(rc); 1719*12065SKeyur.Desai@Sun.COM status = NT_SC_ERROR(status); 1720*12065SKeyur.Desai@Sun.COM } 1721*12065SKeyur.Desai@Sun.COM smb_lgrp_free(&grp); 1722*12065SKeyur.Desai@Sun.COM break; 1723*12065SKeyur.Desai@Sun.COM 1724*12065SKeyur.Desai@Sun.COM default: 1725*12065SKeyur.Desai@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1726*12065SKeyur.Desai@Sun.COM status = NT_SC_ERROR(NT_STATUS_NO_SUCH_ALIAS); 172711337SWilliam.Krier@Sun.COM } 172811337SWilliam.Krier@Sun.COM 1729*12065SKeyur.Desai@Sun.COM param->status = status; 173011337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 173111337SWilliam.Krier@Sun.COM } 173211337SWilliam.Krier@Sun.COM 173311337SWilliam.Krier@Sun.COM /* 173411337SWilliam.Krier@Sun.COM * samr_s_EnumDomainAliases 173511337SWilliam.Krier@Sun.COM * 173611337SWilliam.Krier@Sun.COM * This function sends back a list which contains all local groups' name. 173711337SWilliam.Krier@Sun.COM */ 173811337SWilliam.Krier@Sun.COM static int 173911337SWilliam.Krier@Sun.COM samr_s_EnumDomainAliases(void *arg, ndr_xa_t *mxa) 174011337SWilliam.Krier@Sun.COM { 174111337SWilliam.Krier@Sun.COM struct samr_EnumDomainAliases *param = arg; 174211337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 174311337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 174411337SWilliam.Krier@Sun.COM samr_keydata_t *data; 174511337SWilliam.Krier@Sun.COM smb_group_t grp; 174611337SWilliam.Krier@Sun.COM smb_giter_t gi; 174711337SWilliam.Krier@Sun.COM int cnt, skip, i; 174811337SWilliam.Krier@Sun.COM struct name_rid *info; 174911337SWilliam.Krier@Sun.COM 175011337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 175111337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 175211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 175311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 175411337SWilliam.Krier@Sun.COM } 175511337SWilliam.Krier@Sun.COM 175611337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 175711337SWilliam.Krier@Sun.COM 175811337SWilliam.Krier@Sun.COM cnt = smb_sam_grp_cnt(data->kd_type); 175911337SWilliam.Krier@Sun.COM if (cnt <= param->resume_handle) { 176011337SWilliam.Krier@Sun.COM param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, 176111337SWilliam.Krier@Sun.COM sizeof (struct aliases_info)); 176211337SWilliam.Krier@Sun.COM 176311337SWilliam.Krier@Sun.COM if (param->aliases == NULL) { 176411337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 176511337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 176611337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 176711337SWilliam.Krier@Sun.COM } 176811337SWilliam.Krier@Sun.COM 176911337SWilliam.Krier@Sun.COM bzero(param->aliases, sizeof (struct aliases_info)); 177011337SWilliam.Krier@Sun.COM param->out_resume = 0; 177111337SWilliam.Krier@Sun.COM param->entries = 0; 177211337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 177311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 177411337SWilliam.Krier@Sun.COM } 177511337SWilliam.Krier@Sun.COM 177611337SWilliam.Krier@Sun.COM cnt -= param->resume_handle; 177711337SWilliam.Krier@Sun.COM param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, 177811337SWilliam.Krier@Sun.COM sizeof (struct aliases_info) + (cnt-1) * sizeof (struct name_rid)); 177911337SWilliam.Krier@Sun.COM 178011337SWilliam.Krier@Sun.COM if (param->aliases == NULL) { 178111337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 178211337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 178311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 178411337SWilliam.Krier@Sun.COM } 178511337SWilliam.Krier@Sun.COM 178611337SWilliam.Krier@Sun.COM if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 178711337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 178811337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); 178911337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 179011337SWilliam.Krier@Sun.COM } 179111337SWilliam.Krier@Sun.COM 179211337SWilliam.Krier@Sun.COM skip = i = 0; 179311337SWilliam.Krier@Sun.COM info = param->aliases->info; 179411337SWilliam.Krier@Sun.COM while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) { 179511337SWilliam.Krier@Sun.COM if ((skip++ >= param->resume_handle) && 179611337SWilliam.Krier@Sun.COM (grp.sg_domain == data->kd_type) && (i++ < cnt)) { 179711337SWilliam.Krier@Sun.COM info->rid = grp.sg_rid; 179811337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, grp.sg_name, 179911337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&info->name); 180011337SWilliam.Krier@Sun.COM 180111337SWilliam.Krier@Sun.COM info++; 180211337SWilliam.Krier@Sun.COM } 180311337SWilliam.Krier@Sun.COM smb_lgrp_free(&grp); 180411337SWilliam.Krier@Sun.COM } 180511337SWilliam.Krier@Sun.COM smb_lgrp_iterclose(&gi); 180611337SWilliam.Krier@Sun.COM 180711337SWilliam.Krier@Sun.COM param->aliases->count = i; 180811337SWilliam.Krier@Sun.COM param->aliases->address = i; 180911337SWilliam.Krier@Sun.COM 181011337SWilliam.Krier@Sun.COM param->out_resume = i; 181111337SWilliam.Krier@Sun.COM param->entries = i; 181211337SWilliam.Krier@Sun.COM param->status = 0; 181311337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 181411337SWilliam.Krier@Sun.COM } 181511337SWilliam.Krier@Sun.COM 181611337SWilliam.Krier@Sun.COM /* 181711337SWilliam.Krier@Sun.COM * samr_s_Connect3 181811337SWilliam.Krier@Sun.COM */ 181911337SWilliam.Krier@Sun.COM static int 182011337SWilliam.Krier@Sun.COM samr_s_Connect3(void *arg, ndr_xa_t *mxa) 182111337SWilliam.Krier@Sun.COM { 182211447Samw@Sun.COM struct samr_Connect3 *param = arg; 182311447Samw@Sun.COM ndr_hdid_t *id; 182411337SWilliam.Krier@Sun.COM 182511447Samw@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 182611447Samw@Sun.COM if (id) { 182711447Samw@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 182811447Samw@Sun.COM param->status = 0; 182911447Samw@Sun.COM } else { 183011447Samw@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 183111447Samw@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 183211447Samw@Sun.COM } 183311447Samw@Sun.COM 183411447Samw@Sun.COM return (NDR_DRC_OK); 183511337SWilliam.Krier@Sun.COM } 183611337SWilliam.Krier@Sun.COM 183711337SWilliam.Krier@Sun.COM /* 183811337SWilliam.Krier@Sun.COM * samr_s_Connect4 183911337SWilliam.Krier@Sun.COM * 184011337SWilliam.Krier@Sun.COM * This is the connect4 form of the connect request used by Windows XP. 184111337SWilliam.Krier@Sun.COM * Returns an RPC fault for now. 184211337SWilliam.Krier@Sun.COM */ 184311337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 184411337SWilliam.Krier@Sun.COM static int 184511337SWilliam.Krier@Sun.COM samr_s_Connect4(void *arg, ndr_xa_t *mxa) 184611337SWilliam.Krier@Sun.COM { 184711337SWilliam.Krier@Sun.COM struct samr_Connect4 *param = arg; 184811337SWilliam.Krier@Sun.COM 184911337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_Connect4)); 185011337SWilliam.Krier@Sun.COM return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 185111337SWilliam.Krier@Sun.COM } 185211337SWilliam.Krier@Sun.COM 185311337SWilliam.Krier@Sun.COM static ndr_stub_table_t samr_stub_table[] = { 185411337SWilliam.Krier@Sun.COM { samr_s_ConnectAnon, SAMR_OPNUM_ConnectAnon }, 185511337SWilliam.Krier@Sun.COM { samr_s_CloseHandle, SAMR_OPNUM_CloseHandle }, 185611337SWilliam.Krier@Sun.COM { samr_s_LookupDomain, SAMR_OPNUM_LookupDomain }, 185711337SWilliam.Krier@Sun.COM { samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains }, 185811337SWilliam.Krier@Sun.COM { samr_s_OpenDomain, SAMR_OPNUM_OpenDomain }, 185911337SWilliam.Krier@Sun.COM { samr_s_QueryDomainInfo, SAMR_OPNUM_QueryDomainInfo }, 186011447Samw@Sun.COM { samr_s_QueryInfoDomain2, SAMR_OPNUM_QueryInfoDomain2 }, 186111337SWilliam.Krier@Sun.COM { samr_s_LookupNames, SAMR_OPNUM_LookupNames }, 186211337SWilliam.Krier@Sun.COM { samr_s_OpenUser, SAMR_OPNUM_OpenUser }, 186311337SWilliam.Krier@Sun.COM { samr_s_DeleteUser, SAMR_OPNUM_DeleteUser }, 186411337SWilliam.Krier@Sun.COM { samr_s_QueryUserInfo, SAMR_OPNUM_QueryUserInfo }, 186511337SWilliam.Krier@Sun.COM { samr_s_QueryUserGroups, SAMR_OPNUM_QueryUserGroups }, 186611337SWilliam.Krier@Sun.COM { samr_s_OpenGroup, SAMR_OPNUM_OpenGroup }, 186711337SWilliam.Krier@Sun.COM { samr_s_Connect, SAMR_OPNUM_Connect }, 186811337SWilliam.Krier@Sun.COM { samr_s_GetUserPwInfo, SAMR_OPNUM_GetUserPwInfo }, 186911337SWilliam.Krier@Sun.COM { samr_s_CreateUser, SAMR_OPNUM_CreateUser }, 187011337SWilliam.Krier@Sun.COM { samr_s_ChangeUserPasswd, SAMR_OPNUM_ChangeUserPasswd }, 187111337SWilliam.Krier@Sun.COM { samr_s_GetDomainPwInfo, SAMR_OPNUM_GetDomainPwInfo }, 187211337SWilliam.Krier@Sun.COM { samr_s_SetUserInfo, SAMR_OPNUM_SetUserInfo }, 187311337SWilliam.Krier@Sun.COM { samr_s_Connect3, SAMR_OPNUM_Connect3 }, 187411337SWilliam.Krier@Sun.COM { samr_s_Connect4, SAMR_OPNUM_Connect4 }, 187511337SWilliam.Krier@Sun.COM { samr_s_QueryDispInfo, SAMR_OPNUM_QueryDispInfo }, 187611337SWilliam.Krier@Sun.COM { samr_s_OpenAlias, SAMR_OPNUM_OpenAlias }, 187711337SWilliam.Krier@Sun.COM { samr_s_CreateDomainAlias, SAMR_OPNUM_CreateDomainAlias }, 187811337SWilliam.Krier@Sun.COM { samr_s_SetAliasInfo, SAMR_OPNUM_SetAliasInfo }, 187911337SWilliam.Krier@Sun.COM { samr_s_QueryAliasInfo, SAMR_OPNUM_QueryAliasInfo }, 188011337SWilliam.Krier@Sun.COM { samr_s_DeleteDomainAlias, SAMR_OPNUM_DeleteDomainAlias }, 188111337SWilliam.Krier@Sun.COM { samr_s_EnumDomainAliases, SAMR_OPNUM_EnumDomainAliases }, 188211337SWilliam.Krier@Sun.COM { samr_s_EnumDomainGroups, SAMR_OPNUM_EnumDomainGroups }, 1883*12065SKeyur.Desai@Sun.COM { samr_s_AddAliasMember, SAMR_OPNUM_AddAliasMember }, 1884*12065SKeyur.Desai@Sun.COM { samr_s_DeleteAliasMember, SAMR_OPNUM_DeleteAliasMember }, 1885*12065SKeyur.Desai@Sun.COM { samr_s_ListAliasMembers, SAMR_OPNUM_ListAliasMembers }, 188611337SWilliam.Krier@Sun.COM {0} 188711337SWilliam.Krier@Sun.COM }; 188811337SWilliam.Krier@Sun.COM 188911337SWilliam.Krier@Sun.COM /* 189011337SWilliam.Krier@Sun.COM * There is a bug in the way that midl and the marshalling code handles 189111337SWilliam.Krier@Sun.COM * unions so we need to fix some of the data offsets at runtime. The 189211337SWilliam.Krier@Sun.COM * following macros and the fixup functions handle the corrections. 189311337SWilliam.Krier@Sun.COM */ 189411337SWilliam.Krier@Sun.COM 189511337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfo_ru); 189611337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfoRes); 189711337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfo); 189811337SWilliam.Krier@Sun.COM 189911337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(QueryUserInfo_result_u); 190011337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(QueryUserInfo_result); 190111337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryUserInfo); 190211337SWilliam.Krier@Sun.COM 190311337SWilliam.Krier@Sun.COM void 190411337SWilliam.Krier@Sun.COM fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo *val) 190511337SWilliam.Krier@Sun.COM { 190611337SWilliam.Krier@Sun.COM unsigned short size1 = 0; 190711337SWilliam.Krier@Sun.COM unsigned short size2 = 0; 190811337SWilliam.Krier@Sun.COM unsigned short size3 = 0; 190911337SWilliam.Krier@Sun.COM 191011337SWilliam.Krier@Sun.COM switch (val->level) { 191111337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryAliasInfo, 1); 191211337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryAliasInfo, 3); 191311337SWilliam.Krier@Sun.COM 191411337SWilliam.Krier@Sun.COM default: 191511337SWilliam.Krier@Sun.COM return; 191611337SWilliam.Krier@Sun.COM }; 191711337SWilliam.Krier@Sun.COM 191811337SWilliam.Krier@Sun.COM size2 = size1 + (2 * sizeof (DWORD)); 191911337SWilliam.Krier@Sun.COM size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 192011337SWilliam.Krier@Sun.COM 192111337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfo_ru, size1); 192211337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfoRes, size2); 192311337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfo, size3); 192411337SWilliam.Krier@Sun.COM } 192511337SWilliam.Krier@Sun.COM 192611337SWilliam.Krier@Sun.COM void 192711337SWilliam.Krier@Sun.COM fixup_samr_QueryUserInfo(struct samr_QueryUserInfo *val) 192811337SWilliam.Krier@Sun.COM { 192911337SWilliam.Krier@Sun.COM unsigned short size1 = 0; 193011337SWilliam.Krier@Sun.COM unsigned short size2 = 0; 193111337SWilliam.Krier@Sun.COM unsigned short size3 = 0; 193211337SWilliam.Krier@Sun.COM 193311337SWilliam.Krier@Sun.COM switch (val->switch_index) { 193411337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 1); 193511337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 6); 193611337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 7); 193711337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 8); 193811337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 9); 193911337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 16); 194011337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 21); 194111337SWilliam.Krier@Sun.COM 194211337SWilliam.Krier@Sun.COM default: 194311337SWilliam.Krier@Sun.COM return; 194411337SWilliam.Krier@Sun.COM }; 194511337SWilliam.Krier@Sun.COM 194611337SWilliam.Krier@Sun.COM size2 = size1 + (2 * sizeof (DWORD)); 194711337SWilliam.Krier@Sun.COM size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 194811337SWilliam.Krier@Sun.COM 194911337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(QueryUserInfo_result_u, size1); 195011337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(QueryUserInfo_result, size2); 195111337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryUserInfo, size3); 195211337SWilliam.Krier@Sun.COM } 195311337SWilliam.Krier@Sun.COM 195411337SWilliam.Krier@Sun.COM /* 195511337SWilliam.Krier@Sun.COM * As long as there is only one entry in the union, there is no need 195611337SWilliam.Krier@Sun.COM * to patch anything. 195711337SWilliam.Krier@Sun.COM */ 195811337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 195911337SWilliam.Krier@Sun.COM void 196011337SWilliam.Krier@Sun.COM fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo *val) 196111337SWilliam.Krier@Sun.COM { 196211337SWilliam.Krier@Sun.COM } 1963