1fe1c642dSBill Krier /* 2fe1c642dSBill Krier * CDDL HEADER START 3fe1c642dSBill Krier * 4fe1c642dSBill Krier * The contents of this file are subject to the terms of the 5fe1c642dSBill Krier * Common Development and Distribution License (the "License"). 6fe1c642dSBill Krier * You may not use this file except in compliance with the License. 7fe1c642dSBill Krier * 8fe1c642dSBill Krier * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fe1c642dSBill Krier * or http://www.opensolaris.org/os/licensing. 10fe1c642dSBill Krier * See the License for the specific language governing permissions 11fe1c642dSBill Krier * and limitations under the License. 12fe1c642dSBill Krier * 13fe1c642dSBill Krier * When distributing Covered Code, include this CDDL HEADER in each 14fe1c642dSBill Krier * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fe1c642dSBill Krier * If applicable, add the following below this CDDL HEADER, with the 16fe1c642dSBill Krier * fields enclosed by brackets "[]" replaced with your own identifying 17fe1c642dSBill Krier * information: Portions Copyright [yyyy] [name of copyright owner] 18fe1c642dSBill Krier * 19fe1c642dSBill Krier * CDDL HEADER END 20fe1c642dSBill Krier */ 21148c5f43SAlan Wright 22fe1c642dSBill Krier /* 23c5866007SKeyur Desai * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24*eef90b86SGordon Ross * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 25fe1c642dSBill Krier */ 26fe1c642dSBill Krier 27fe1c642dSBill Krier /* 28fe1c642dSBill Krier * Security Accounts Manager RPC (SAMR) server-side interface. 29fe1c642dSBill Krier * 30fe1c642dSBill Krier * The SAM is a hierarchical database: 31fe1c642dSBill Krier * - If you want to talk to the SAM you need a SAM handle. 32fe1c642dSBill Krier * - If you want to work with a domain, use the SAM handle. 33fe1c642dSBill Krier * to obtain a domain handle. 34fe1c642dSBill Krier * - Use domain handles to obtain user handles etc. 35fe1c642dSBill Krier */ 36fe1c642dSBill Krier 37fe1c642dSBill Krier #include <strings.h> 38fe1c642dSBill Krier #include <unistd.h> 39fe1c642dSBill Krier #include <netdb.h> 40fe1c642dSBill Krier #include <assert.h> 41c5866007SKeyur Desai #include <grp.h> 42fe1c642dSBill Krier #include <smbsrv/libsmb.h> 43fe1c642dSBill Krier #include <smbsrv/libmlrpc.h> 44fe1c642dSBill Krier #include <smbsrv/libmlsvc.h> 45fe1c642dSBill Krier #include <smbsrv/smbinfo.h> 46fe1c642dSBill Krier #include <smbsrv/nmpipes.h> 47fe1c642dSBill Krier #include <smbsrv/ndl/samrpc.ndl> 48fe1c642dSBill Krier #include <samlib.h> 49fe1c642dSBill Krier 50fe1c642dSBill Krier /* 51fe1c642dSBill Krier * The keys associated with the various handles dispensed by the SAMR 52fe1c642dSBill Krier * server. These keys can be used to validate client activity. 53fe1c642dSBill Krier * These values are never passed over the wire so security shouldn't 54fe1c642dSBill Krier * be an issue. 55fe1c642dSBill Krier */ 56fe1c642dSBill Krier typedef enum { 57fe1c642dSBill Krier SAMR_KEY_NULL = 0, 58fe1c642dSBill Krier SAMR_KEY_CONNECT, 59fe1c642dSBill Krier SAMR_KEY_DOMAIN, 60fe1c642dSBill Krier SAMR_KEY_USER, 61fe1c642dSBill Krier SAMR_KEY_GROUP, 62fe1c642dSBill Krier SAMR_KEY_ALIAS 63fe1c642dSBill Krier } samr_key_t; 64fe1c642dSBill Krier 65fe1c642dSBill Krier typedef struct samr_keydata { 66fe1c642dSBill Krier samr_key_t kd_key; 67fe1c642dSBill Krier smb_domain_type_t kd_type; 68fe1c642dSBill Krier DWORD kd_rid; 69fe1c642dSBill Krier } samr_keydata_t; 70fe1c642dSBill Krier 71fe1c642dSBill Krier /* 72fe1c642dSBill Krier * DomainDisplayUser All user objects (or those derived from user) with 73fe1c642dSBill Krier * userAccountControl containing the UF_NORMAL_ACCOUNT bit. 74fe1c642dSBill Krier * 75fe1c642dSBill Krier * DomainDisplayMachine All user objects (or those derived from user) with 76fe1c642dSBill Krier * userAccountControl containing the 77fe1c642dSBill Krier * UF_WORKSTATION_TRUST_ACCOUNT or UF_SERVER_TRUST_ACCOUNT 78fe1c642dSBill Krier * bit. 79fe1c642dSBill Krier * 80fe1c642dSBill Krier * DomainDisplayGroup All group objects (or those derived from group) with 81fe1c642dSBill Krier * groupType equal to GROUP_TYPE_SECURITY_UNIVERSAL or 82fe1c642dSBill Krier * GROUP_TYPE_SECURITY_ACCOUNT. 83fe1c642dSBill Krier * 84fe1c642dSBill Krier * DomainDisplayOemUser Same as DomainDisplayUser with OEM strings 85fe1c642dSBill Krier * 86fe1c642dSBill Krier * DomainDisplayOemGroup Same as DomainDisplayGroup with OEM strings 87fe1c642dSBill Krier */ 88fe1c642dSBill Krier typedef enum { 89fe1c642dSBill Krier DomainDisplayUser = 1, 90fe1c642dSBill Krier DomainDisplayMachine, 91fe1c642dSBill Krier DomainDispalyGroup, 92fe1c642dSBill Krier DomainDisplayOemUser, 93fe1c642dSBill Krier DomainDisplayOemGroup 94fe1c642dSBill Krier } samr_displvl_t; 95fe1c642dSBill Krier 96fe1c642dSBill Krier #define SAMR_VALID_DISPLEVEL(lvl) \ 97fe1c642dSBill Krier (((lvl) >= DomainDisplayUser) && ((lvl) <= DomainDisplayOemGroup)) 98fe1c642dSBill Krier 99fe1c642dSBill Krier #define SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser) 100fe1c642dSBill Krier 101fe1c642dSBill Krier static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t, 102fe1c642dSBill Krier DWORD); 103fe1c642dSBill Krier static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *); 104fe1c642dSBill Krier static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t); 105fe1c642dSBill Krier static int samr_call_stub(ndr_xa_t *mxa); 106fe1c642dSBill Krier static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *, 107fe1c642dSBill Krier ndr_xa_t *); 108fe1c642dSBill Krier 109fe1c642dSBill Krier static ndr_stub_table_t samr_stub_table[]; 110fe1c642dSBill Krier 111fe1c642dSBill Krier static ndr_service_t samr_service = { 112fe1c642dSBill Krier "SAMR", /* name */ 113fe1c642dSBill Krier "Security Accounts Manager", /* desc */ 114fe1c642dSBill Krier "\\samr", /* endpoint */ 115fe1c642dSBill Krier PIPE_LSASS, /* sec_addr_port */ 116fe1c642dSBill Krier "12345778-1234-abcd-ef00-0123456789ac", 1, /* abstract */ 117fe1c642dSBill Krier NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 118fe1c642dSBill Krier 0, /* no bind_instance_size */ 119fe1c642dSBill Krier NULL, /* no bind_req() */ 120fe1c642dSBill Krier NULL, /* no unbind_and_close() */ 121fe1c642dSBill Krier samr_call_stub, /* call_stub() */ 122fe1c642dSBill Krier &TYPEINFO(samr_interface), /* interface ti */ 123fe1c642dSBill Krier samr_stub_table /* stub_table */ 124fe1c642dSBill Krier }; 125fe1c642dSBill Krier 126fe1c642dSBill Krier /* 127fe1c642dSBill Krier * samr_initialize 128fe1c642dSBill Krier * 129fe1c642dSBill Krier * This function registers the SAM RPC interface with the RPC runtime 130fe1c642dSBill Krier * library. It must be called in order to use either the client side 131fe1c642dSBill Krier * or the server side functions. 132fe1c642dSBill Krier */ 133fe1c642dSBill Krier void 134fe1c642dSBill Krier samr_initialize(void) 135fe1c642dSBill Krier { 136fe1c642dSBill Krier (void) ndr_svc_register(&samr_service); 137fe1c642dSBill Krier } 138fe1c642dSBill Krier 139fe1c642dSBill Krier /* 140fe1c642dSBill Krier * Custom call_stub to set the stream string policy. 141fe1c642dSBill Krier */ 142fe1c642dSBill Krier static int 143fe1c642dSBill Krier samr_call_stub(ndr_xa_t *mxa) 144fe1c642dSBill Krier { 145fe1c642dSBill Krier NDS_SETF(&mxa->send_nds, NDS_F_NOTERM); 146fe1c642dSBill Krier NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM); 147fe1c642dSBill Krier 148fe1c642dSBill Krier return (ndr_generic_call_stub(mxa)); 149fe1c642dSBill Krier } 150fe1c642dSBill Krier 151fe1c642dSBill Krier /* 152fe1c642dSBill Krier * Handle allocation wrapper to setup the local context. 153fe1c642dSBill Krier */ 154fe1c642dSBill Krier static ndr_hdid_t * 155fe1c642dSBill Krier samr_hdalloc(ndr_xa_t *mxa, samr_key_t key, smb_domain_type_t domain_type, 156fe1c642dSBill Krier DWORD rid) 157fe1c642dSBill Krier { 1589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_handle_t *hd; 1599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_hdid_t *id; 160fe1c642dSBill Krier samr_keydata_t *data; 161fe1c642dSBill Krier 162fe1c642dSBill Krier if ((data = malloc(sizeof (samr_keydata_t))) == NULL) 163fe1c642dSBill Krier return (NULL); 164fe1c642dSBill Krier 165fe1c642dSBill Krier data->kd_key = key; 166fe1c642dSBill Krier data->kd_type = domain_type; 167fe1c642dSBill Krier data->kd_rid = rid; 168fe1c642dSBill Krier 1699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((id = ndr_hdalloc(mxa, data)) == NULL) { 1709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States free(data); 1719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NULL); 1729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 1739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 1749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((hd = ndr_hdlookup(mxa, id)) != NULL) 1759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States hd->nh_data_free = free; 1769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 1779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (id); 178fe1c642dSBill Krier } 179fe1c642dSBill Krier 180fe1c642dSBill Krier /* 181fe1c642dSBill Krier * Handle deallocation wrapper to free the local context. 182fe1c642dSBill Krier */ 183fe1c642dSBill Krier static void 184fe1c642dSBill Krier samr_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id) 185fe1c642dSBill Krier { 186fe1c642dSBill Krier ndr_handle_t *hd; 187fe1c642dSBill Krier 188fe1c642dSBill Krier if ((hd = ndr_hdlookup(mxa, id)) != NULL) { 189fe1c642dSBill Krier free(hd->nh_data); 1909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States hd->nh_data = NULL; 191fe1c642dSBill Krier ndr_hdfree(mxa, id); 192fe1c642dSBill Krier } 193fe1c642dSBill Krier } 194fe1c642dSBill Krier 195fe1c642dSBill Krier /* 196fe1c642dSBill Krier * Handle lookup wrapper to validate the local context. 197fe1c642dSBill Krier */ 198fe1c642dSBill Krier static ndr_handle_t * 199fe1c642dSBill Krier samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key) 200fe1c642dSBill Krier { 201fe1c642dSBill Krier ndr_handle_t *hd; 202fe1c642dSBill Krier samr_keydata_t *data; 203fe1c642dSBill Krier 204fe1c642dSBill Krier if ((hd = ndr_hdlookup(mxa, id)) == NULL) 205fe1c642dSBill Krier return (NULL); 206fe1c642dSBill Krier 207fe1c642dSBill Krier if ((data = (samr_keydata_t *)hd->nh_data) == NULL) 208fe1c642dSBill Krier return (NULL); 209fe1c642dSBill Krier 210fe1c642dSBill Krier if (data->kd_key != key) 211fe1c642dSBill Krier return (NULL); 212fe1c642dSBill Krier 213fe1c642dSBill Krier return (hd); 214fe1c642dSBill Krier } 215fe1c642dSBill Krier 216fe1c642dSBill Krier /* 217cb174861Sjoyce mcintosh * samr_s_Connect 218fe1c642dSBill Krier * 219fe1c642dSBill Krier * This is a request to connect to the local SAM database. We don't 220fe1c642dSBill Krier * support any form of update request and our database doesn't 221fe1c642dSBill Krier * contain any private information, so there is little point in 222fe1c642dSBill Krier * doing any access access checking here. 223fe1c642dSBill Krier * 224fe1c642dSBill Krier * Return a handle for use with subsequent SAM requests. 225fe1c642dSBill Krier */ 226fe1c642dSBill Krier static int 227cb174861Sjoyce mcintosh samr_s_Connect(void *arg, ndr_xa_t *mxa) 228fe1c642dSBill Krier { 229cb174861Sjoyce mcintosh struct samr_Connect *param = arg; 230fe1c642dSBill Krier ndr_hdid_t *id; 231fe1c642dSBill Krier 232fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 233fe1c642dSBill Krier if (id) { 234fe1c642dSBill Krier bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 235fe1c642dSBill Krier param->status = 0; 236fe1c642dSBill Krier } else { 237fe1c642dSBill Krier bzero(¶m->handle, sizeof (samr_handle_t)); 238fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 239fe1c642dSBill Krier } 240fe1c642dSBill Krier 241fe1c642dSBill Krier return (NDR_DRC_OK); 242fe1c642dSBill Krier } 243fe1c642dSBill Krier 244fe1c642dSBill Krier /* 245fe1c642dSBill Krier * samr_s_CloseHandle 246fe1c642dSBill Krier * 247fe1c642dSBill Krier * Close the SAM interface specified by the handle. 248fe1c642dSBill Krier * Free the handle and zero out the result handle for the client. 249fe1c642dSBill Krier */ 250fe1c642dSBill Krier static int 251fe1c642dSBill Krier samr_s_CloseHandle(void *arg, ndr_xa_t *mxa) 252fe1c642dSBill Krier { 253fe1c642dSBill Krier struct samr_CloseHandle *param = arg; 254fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 255fe1c642dSBill Krier 256fe1c642dSBill Krier samr_hdfree(mxa, id); 257fe1c642dSBill Krier 258fe1c642dSBill Krier bzero(¶m->result_handle, sizeof (samr_handle_t)); 259fe1c642dSBill Krier param->status = 0; 260fe1c642dSBill Krier return (NDR_DRC_OK); 261fe1c642dSBill Krier } 262fe1c642dSBill Krier 263fe1c642dSBill Krier /* 264fe1c642dSBill Krier * samr_s_LookupDomain 265fe1c642dSBill Krier * 266fe1c642dSBill Krier * This is a request to map a domain name to a domain SID. We can map 267fe1c642dSBill Krier * the primary domain name, our local domain name (hostname) and the 268fe1c642dSBill Krier * builtin domain names to the appropriate SID. Anything else will be 269fe1c642dSBill Krier * rejected. 270fe1c642dSBill Krier */ 271fe1c642dSBill Krier static int 272fe1c642dSBill Krier samr_s_LookupDomain(void *arg, ndr_xa_t *mxa) 273fe1c642dSBill Krier { 274fe1c642dSBill Krier struct samr_LookupDomain *param = arg; 275fe1c642dSBill Krier char *domain_name; 276fe1c642dSBill Krier smb_domain_t di; 277fe1c642dSBill Krier 278fe1c642dSBill Krier if ((domain_name = (char *)param->domain_name.str) == NULL) { 279fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupDomain)); 280fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 281fe1c642dSBill Krier return (NDR_DRC_OK); 282fe1c642dSBill Krier } 283fe1c642dSBill Krier 284fe1c642dSBill Krier if (!smb_domain_lookup_name(domain_name, &di)) { 285fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupDomain)); 286fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_DOMAIN); 287fe1c642dSBill Krier return (NDR_DRC_OK); 288fe1c642dSBill Krier } 289fe1c642dSBill Krier 290fe1c642dSBill Krier param->sid = (struct samr_sid *)NDR_SIDDUP(mxa, di.di_binsid); 291fe1c642dSBill Krier if (param->sid == NULL) { 292fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupDomain)); 293fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 294fe1c642dSBill Krier return (NDR_DRC_OK); 295fe1c642dSBill Krier } 296fe1c642dSBill Krier 297fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 298fe1c642dSBill Krier return (NDR_DRC_OK); 299fe1c642dSBill Krier } 300fe1c642dSBill Krier 301fe1c642dSBill Krier /* 302fe1c642dSBill Krier * samr_s_EnumLocalDomains 303fe1c642dSBill Krier * 304fe1c642dSBill Krier * This is a request for the local domains supported by this server. 305fe1c642dSBill Krier * All we do here is validate the handle and set the status. The real 306fe1c642dSBill Krier * work is done in samr_s_enum_local_domains. 307fe1c642dSBill Krier */ 308fe1c642dSBill Krier static int 309fe1c642dSBill Krier samr_s_EnumLocalDomains(void *arg, ndr_xa_t *mxa) 310fe1c642dSBill Krier { 311fe1c642dSBill Krier struct samr_EnumLocalDomain *param = arg; 312fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 313fe1c642dSBill Krier DWORD status; 314fe1c642dSBill Krier 315fe1c642dSBill Krier if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) 316fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED; 317fe1c642dSBill Krier else 318fe1c642dSBill Krier status = samr_s_enum_local_domains(param, mxa); 319fe1c642dSBill Krier 320fe1c642dSBill Krier if (status == NT_STATUS_SUCCESS) { 321fe1c642dSBill Krier param->enum_context = param->info->entries_read; 322fe1c642dSBill Krier param->total_entries = param->info->entries_read; 323fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 324fe1c642dSBill Krier } else { 325fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumLocalDomain)); 326fe1c642dSBill Krier param->status = NT_SC_ERROR(status); 327fe1c642dSBill Krier } 328fe1c642dSBill Krier 329fe1c642dSBill Krier return (NDR_DRC_OK); 330fe1c642dSBill Krier } 331fe1c642dSBill Krier 332fe1c642dSBill Krier 333fe1c642dSBill Krier /* 334fe1c642dSBill Krier * samr_s_enum_local_domains 335fe1c642dSBill Krier * 336fe1c642dSBill Krier * This function should only be called via samr_s_EnumLocalDomains to 337fe1c642dSBill Krier * ensure that the appropriate validation is performed. We will answer 338fe1c642dSBill Krier * queries about two domains: the local domain, synonymous with the 339fe1c642dSBill Krier * local hostname, and the BUILTIN domain. So we return these two 340fe1c642dSBill Krier * strings. 341fe1c642dSBill Krier * 342fe1c642dSBill Krier * Returns NT status values. 343fe1c642dSBill Krier */ 344fe1c642dSBill Krier static DWORD 345fe1c642dSBill Krier samr_s_enum_local_domains(struct samr_EnumLocalDomain *param, 346fe1c642dSBill Krier ndr_xa_t *mxa) 347fe1c642dSBill Krier { 348fe1c642dSBill Krier struct samr_LocalDomainInfo *info; 349fe1c642dSBill Krier struct samr_LocalDomainEntry *entry; 350fe1c642dSBill Krier char *hostname; 351fe1c642dSBill Krier 352fe1c642dSBill Krier hostname = NDR_MALLOC(mxa, NETBIOS_NAME_SZ); 353fe1c642dSBill Krier if (hostname == NULL) 354fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY); 355fe1c642dSBill Krier 356fe1c642dSBill Krier if (smb_getnetbiosname(hostname, NETBIOS_NAME_SZ) != 0) 357fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY); 358fe1c642dSBill Krier 359fe1c642dSBill Krier entry = NDR_NEWN(mxa, struct samr_LocalDomainEntry, 2); 360fe1c642dSBill Krier if (entry == NULL) 361fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY); 362fe1c642dSBill Krier 363fe1c642dSBill Krier bzero(entry, (sizeof (struct samr_LocalDomainEntry) * 2)); 364fe1c642dSBill Krier (void) NDR_MSTRING(mxa, hostname, (ndr_mstring_t *)&entry[0].name); 365fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "Builtin", (ndr_mstring_t *)&entry[1].name); 366fe1c642dSBill Krier 367fe1c642dSBill Krier info = NDR_NEW(mxa, struct samr_LocalDomainInfo); 368fe1c642dSBill Krier if (info == NULL) 369fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY); 370fe1c642dSBill Krier 371fe1c642dSBill Krier info->entries_read = 2; 372fe1c642dSBill Krier info->entry = entry; 373fe1c642dSBill Krier param->info = info; 374fe1c642dSBill Krier return (NT_STATUS_SUCCESS); 375fe1c642dSBill Krier } 376fe1c642dSBill Krier 377fe1c642dSBill Krier /* 378fe1c642dSBill Krier * samr_s_OpenDomain 379fe1c642dSBill Krier * 380fe1c642dSBill Krier * This is a request to open a domain within the local SAM database. 381fe1c642dSBill Krier * The caller must supply a valid connect handle. 382fe1c642dSBill Krier * We return a handle to be used to access objects within this domain. 383fe1c642dSBill Krier */ 384fe1c642dSBill Krier static int 385fe1c642dSBill Krier samr_s_OpenDomain(void *arg, ndr_xa_t *mxa) 386fe1c642dSBill Krier { 387fe1c642dSBill Krier struct samr_OpenDomain *param = arg; 388fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 389fe1c642dSBill Krier smb_domain_t domain; 390fe1c642dSBill Krier 391fe1c642dSBill Krier if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) { 392fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (samr_handle_t)); 393fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 394fe1c642dSBill Krier return (NDR_DRC_OK); 395fe1c642dSBill Krier } 396fe1c642dSBill Krier 397fe1c642dSBill Krier if (!smb_domain_lookup_sid((smb_sid_t *)param->sid, &domain)) { 398fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (samr_handle_t)); 399fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 400fe1c642dSBill Krier return (NDR_DRC_OK); 401fe1c642dSBill Krier } 402fe1c642dSBill Krier 403fe1c642dSBill Krier if ((domain.di_type != SMB_DOMAIN_BUILTIN) && 404fe1c642dSBill Krier (domain.di_type != SMB_DOMAIN_LOCAL)) { 405fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (samr_handle_t)); 406fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 407fe1c642dSBill Krier return (NDR_DRC_OK); 408fe1c642dSBill Krier } 409fe1c642dSBill Krier 410fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_DOMAIN, domain.di_type, 0); 411fe1c642dSBill Krier if (id) { 412fe1c642dSBill Krier bcopy(id, ¶m->domain_handle, sizeof (samr_handle_t)); 413fe1c642dSBill Krier param->status = 0; 414fe1c642dSBill Krier } else { 415fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (samr_handle_t)); 416fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 417fe1c642dSBill Krier } 418fe1c642dSBill Krier 419fe1c642dSBill Krier return (NDR_DRC_OK); 420fe1c642dSBill Krier } 421fe1c642dSBill Krier 422fe1c642dSBill Krier /* 423fe1c642dSBill Krier * samr_s_QueryDomainInfo 424fe1c642dSBill Krier * 425fe1c642dSBill Krier * The caller should pass a domain handle. 426fe1c642dSBill Krier * 427fe1c642dSBill Krier * Windows 95 Server Manager sends requests for levels 6 and 7 when 428fe1c642dSBill Krier * the services menu item is selected. Level 2 is basically for getting 429fe1c642dSBill Krier * number of users, groups, and aliases in a domain. 430fe1c642dSBill Krier * We have no information on what the various information levels mean. 431fe1c642dSBill Krier */ 432fe1c642dSBill Krier static int 433fe1c642dSBill Krier samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa) 434fe1c642dSBill Krier { 435fe1c642dSBill Krier struct samr_QueryDomainInfo *param = arg; 436fe1c642dSBill Krier struct samr_QueryDomainInfoRes *info; 437fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 438fe1c642dSBill Krier ndr_handle_t *hd; 439fe1c642dSBill Krier samr_keydata_t *data; 440fe1c642dSBill Krier char *domain; 441fe1c642dSBill Krier char hostname[NETBIOS_NAME_SZ]; 442fe1c642dSBill Krier int alias_cnt, user_cnt; 443fe1c642dSBill Krier int rc = 0; 444fe1c642dSBill Krier 445fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 446fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo)); 447fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 448fe1c642dSBill Krier return (NDR_DRC_OK); 449fe1c642dSBill Krier } 450fe1c642dSBill Krier 451fe1c642dSBill Krier info = NDR_NEW(mxa, struct samr_QueryDomainInfoRes); 452fe1c642dSBill Krier if (info == NULL) { 453fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo)); 454fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 455fe1c642dSBill Krier return (NDR_DRC_OK); 456fe1c642dSBill Krier } 457fe1c642dSBill Krier info->switch_value = param->info_level; 458fe1c642dSBill Krier param->info = info; 459fe1c642dSBill Krier 460fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data; 461fe1c642dSBill Krier 462fe1c642dSBill Krier switch (data->kd_type) { 463fe1c642dSBill Krier case SMB_DOMAIN_BUILTIN: 464fe1c642dSBill Krier domain = "BUILTIN"; 465fe1c642dSBill Krier user_cnt = 0; 466fe1c642dSBill Krier alias_cnt = smb_sam_grp_cnt(data->kd_type); 467fe1c642dSBill Krier break; 468fe1c642dSBill Krier 469fe1c642dSBill Krier case SMB_DOMAIN_LOCAL: 470fe1c642dSBill Krier rc = smb_getnetbiosname(hostname, sizeof (hostname)); 471fe1c642dSBill Krier if (rc == 0) { 472fe1c642dSBill Krier domain = hostname; 473fe1c642dSBill Krier user_cnt = smb_sam_usr_cnt(); 474fe1c642dSBill Krier alias_cnt = smb_sam_grp_cnt(data->kd_type); 475fe1c642dSBill Krier } 476fe1c642dSBill Krier break; 477fe1c642dSBill Krier 478fe1c642dSBill Krier default: 479fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo)); 480fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 481fe1c642dSBill Krier return (NDR_DRC_OK); 482fe1c642dSBill Krier } 483fe1c642dSBill Krier 484fe1c642dSBill Krier if (rc != 0) { 485fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo)); 486fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); 487fe1c642dSBill Krier return (NDR_DRC_OK); 488fe1c642dSBill Krier } 489fe1c642dSBill Krier 490fe1c642dSBill Krier switch (param->info_level) { 491fe1c642dSBill Krier case SAMR_QUERY_DOMAIN_INFO_6: 492fe1c642dSBill Krier info->ru.info6.unknown1 = 0x00000000; 493fe1c642dSBill Krier info->ru.info6.unknown2 = 0x00147FB0; 494fe1c642dSBill Krier info->ru.info6.unknown3 = 0x00000000; 495fe1c642dSBill Krier info->ru.info6.unknown4 = 0x00000000; 496fe1c642dSBill Krier info->ru.info6.unknown5 = 0x00000000; 497fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 498fe1c642dSBill Krier break; 499fe1c642dSBill Krier 500fe1c642dSBill Krier case SAMR_QUERY_DOMAIN_INFO_7: 501fe1c642dSBill Krier info->ru.info7.unknown1 = 0x00000003; 502fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 503fe1c642dSBill Krier break; 504fe1c642dSBill Krier 505fe1c642dSBill Krier case SAMR_QUERY_DOMAIN_INFO_2: 506fe1c642dSBill Krier info->ru.info2.unknown1 = 0x00000000; 507fe1c642dSBill Krier info->ru.info2.unknown2 = 0x80000000; 508fe1c642dSBill Krier 509fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "", 510fe1c642dSBill Krier (ndr_mstring_t *)&(info->ru.info2.s1)); 511fe1c642dSBill Krier (void) NDR_MSTRING(mxa, domain, 512fe1c642dSBill Krier (ndr_mstring_t *)&(info->ru.info2.domain)); 513fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "", 514fe1c642dSBill Krier (ndr_mstring_t *)&(info->ru.info2.s2)); 515fe1c642dSBill Krier 516fe1c642dSBill Krier info->ru.info2.sequence_num = 0x0000002B; 517fe1c642dSBill Krier info->ru.info2.unknown3 = 0x00000000; 518fe1c642dSBill Krier info->ru.info2.unknown4 = 0x00000001; 519fe1c642dSBill Krier info->ru.info2.unknown5 = 0x00000003; 520fe1c642dSBill Krier info->ru.info2.unknown6 = 0x00000001; 521fe1c642dSBill Krier info->ru.info2.num_users = user_cnt; 522fe1c642dSBill Krier info->ru.info2.num_groups = 0; 523fe1c642dSBill Krier info->ru.info2.num_aliases = alias_cnt; 524fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 525fe1c642dSBill Krier break; 526fe1c642dSBill Krier 527fe1c642dSBill Krier default: 528fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo)); 529fe1c642dSBill Krier return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 530fe1c642dSBill Krier }; 531fe1c642dSBill Krier 532fe1c642dSBill Krier return (NDR_DRC_OK); 533fe1c642dSBill Krier } 534fe1c642dSBill Krier 535fe1c642dSBill Krier /* 536f96bd5c8SAlan Wright * QueryInfoDomain2: Identical to QueryDomainInfo. 537f96bd5c8SAlan Wright */ 538f96bd5c8SAlan Wright static int 539f96bd5c8SAlan Wright samr_s_QueryInfoDomain2(void *arg, ndr_xa_t *mxa) 540f96bd5c8SAlan Wright { 541f96bd5c8SAlan Wright return (samr_s_QueryDomainInfo(arg, mxa)); 542f96bd5c8SAlan Wright } 543f96bd5c8SAlan Wright 544f96bd5c8SAlan Wright /* 545fe1c642dSBill Krier * Looks up the given name in the specified domain which could 546fe1c642dSBill Krier * be either the built-in or local domain. 547fe1c642dSBill Krier * 548fe1c642dSBill Krier * CAVEAT: this function should be able to handle a list of 549fe1c642dSBill Krier * names but currently it can only handle one name at a time. 550fe1c642dSBill Krier */ 551fe1c642dSBill Krier static int 552fe1c642dSBill Krier samr_s_LookupNames(void *arg, ndr_xa_t *mxa) 553fe1c642dSBill Krier { 554fe1c642dSBill Krier struct samr_LookupNames *param = arg; 555fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 556fe1c642dSBill Krier ndr_handle_t *hd; 557fe1c642dSBill Krier samr_keydata_t *data; 558fe1c642dSBill Krier smb_account_t account; 559fe1c642dSBill Krier smb_wka_t *wka; 560fe1c642dSBill Krier uint32_t status = NT_STATUS_SUCCESS; 561fe1c642dSBill Krier 562fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) 563fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE; 564fe1c642dSBill Krier 565fe1c642dSBill Krier if (param->n_entry != 1) 566fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED; 567fe1c642dSBill Krier 568fe1c642dSBill Krier if (param->name.str == NULL) { 569fe1c642dSBill Krier /* 570fe1c642dSBill Krier * Windows NT returns NT_STATUS_NONE_MAPPED. 571fe1c642dSBill Krier * Windows 2000 returns STATUS_INVALID_ACCOUNT_NAME. 572fe1c642dSBill Krier */ 573fe1c642dSBill Krier status = NT_STATUS_NONE_MAPPED; 574fe1c642dSBill Krier } 575fe1c642dSBill Krier 576fe1c642dSBill Krier if (status != NT_STATUS_SUCCESS) { 577fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupNames)); 578fe1c642dSBill Krier param->status = NT_SC_ERROR(status); 579fe1c642dSBill Krier return (NDR_DRC_OK); 580fe1c642dSBill Krier } 581fe1c642dSBill Krier 582fe1c642dSBill Krier param->rids.rid = NDR_NEW(mxa, DWORD); 583fe1c642dSBill Krier param->rid_types.rid_type = NDR_NEW(mxa, DWORD); 584fe1c642dSBill Krier 585fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data; 586fe1c642dSBill Krier 587fe1c642dSBill Krier switch (data->kd_type) { 588fe1c642dSBill Krier case SMB_DOMAIN_BUILTIN: 589f96bd5c8SAlan Wright wka = smb_wka_lookup_builtin((char *)param->name.str); 590fe1c642dSBill Krier if (wka != NULL) { 591fe1c642dSBill Krier param->rids.n_entry = 1; 592fe1c642dSBill Krier (void) smb_sid_getrid(wka->wka_binsid, 593fe1c642dSBill Krier ¶m->rids.rid[0]); 594fe1c642dSBill Krier param->rid_types.n_entry = 1; 595fe1c642dSBill Krier param->rid_types.rid_type[0] = wka->wka_type; 596fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 597fe1c642dSBill Krier return (NDR_DRC_OK); 598fe1c642dSBill Krier } 599fe1c642dSBill Krier break; 600fe1c642dSBill Krier 601fe1c642dSBill Krier case SMB_DOMAIN_LOCAL: 602fe1c642dSBill Krier status = smb_sam_lookup_name(NULL, (char *)param->name.str, 603fe1c642dSBill Krier SidTypeUnknown, &account); 604fe1c642dSBill Krier if (status == NT_STATUS_SUCCESS) { 605fe1c642dSBill Krier param->rids.n_entry = 1; 606fe1c642dSBill Krier param->rids.rid[0] = account.a_rid; 607fe1c642dSBill Krier param->rid_types.n_entry = 1; 608fe1c642dSBill Krier param->rid_types.rid_type[0] = account.a_type; 609fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 610fe1c642dSBill Krier smb_account_free(&account); 611fe1c642dSBill Krier return (NDR_DRC_OK); 612fe1c642dSBill Krier } 613fe1c642dSBill Krier break; 614fe1c642dSBill Krier 615fe1c642dSBill Krier default: 616fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupNames)); 617fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 618fe1c642dSBill Krier return (NDR_DRC_OK); 619fe1c642dSBill Krier } 620fe1c642dSBill Krier 621fe1c642dSBill Krier param->rids.n_entry = 0; 622fe1c642dSBill Krier param->rid_types.n_entry = 0; 623fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NONE_MAPPED); 624fe1c642dSBill Krier return (NDR_DRC_OK); 625fe1c642dSBill Krier } 626fe1c642dSBill Krier 627fe1c642dSBill Krier /* 628fe1c642dSBill Krier * samr_s_OpenUser 629fe1c642dSBill Krier * 630fe1c642dSBill Krier * This is a request to open a user within a specified domain in the 631fe1c642dSBill Krier * local SAM database. The caller must supply a valid domain handle, 632fe1c642dSBill Krier * obtained via a successful domain open request. The user is 633fe1c642dSBill Krier * specified by the rid in the request. 634fe1c642dSBill Krier */ 635fe1c642dSBill Krier static int 636fe1c642dSBill Krier samr_s_OpenUser(void *arg, ndr_xa_t *mxa) 637fe1c642dSBill Krier { 638fe1c642dSBill Krier struct samr_OpenUser *param = arg; 639fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 640fe1c642dSBill Krier ndr_handle_t *hd; 641fe1c642dSBill Krier samr_keydata_t *data; 642fe1c642dSBill Krier 643fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 644fe1c642dSBill Krier bzero(¶m->user_handle, sizeof (samr_handle_t)); 645fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 646fe1c642dSBill Krier return (NDR_DRC_OK); 647fe1c642dSBill Krier } 648fe1c642dSBill Krier 649fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data; 650fe1c642dSBill Krier 651fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_USER, data->kd_type, param->rid); 652fe1c642dSBill Krier if (id == NULL) { 653fe1c642dSBill Krier bzero(¶m->user_handle, sizeof (samr_handle_t)); 654fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 655fe1c642dSBill Krier } else { 656fe1c642dSBill Krier bcopy(id, ¶m->user_handle, sizeof (samr_handle_t)); 657fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 658fe1c642dSBill Krier } 659fe1c642dSBill Krier 660fe1c642dSBill Krier return (NDR_DRC_OK); 661fe1c642dSBill Krier } 662fe1c642dSBill Krier 663fe1c642dSBill Krier /* 664fe1c642dSBill Krier * samr_s_DeleteUser 665fe1c642dSBill Krier * 666fe1c642dSBill Krier * Request to delete a user within a specified domain in the local 667fe1c642dSBill Krier * SAM database. The caller should supply a valid user handle. 668fe1c642dSBill Krier */ 669fe1c642dSBill Krier /*ARGSUSED*/ 670fe1c642dSBill Krier static int 671fe1c642dSBill Krier samr_s_DeleteUser(void *arg, ndr_xa_t *mxa) 672fe1c642dSBill Krier { 673fe1c642dSBill Krier struct samr_DeleteUser *param = arg; 674fe1c642dSBill Krier 675fe1c642dSBill Krier bzero(param, sizeof (struct samr_DeleteUser)); 676fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 677fe1c642dSBill Krier return (NDR_DRC_OK); 678fe1c642dSBill Krier } 679fe1c642dSBill Krier 680fe1c642dSBill Krier /* 681fe1c642dSBill Krier * samr_s_QueryUserInfo 682fe1c642dSBill Krier * 683fe1c642dSBill Krier * Returns: 684fe1c642dSBill Krier * NT_STATUS_SUCCESS 685fe1c642dSBill Krier * NT_STATUS_ACCESS_DENIED 686fe1c642dSBill Krier * NT_STATUS_INVALID_INFO_CLASS 687fe1c642dSBill Krier */ 688fe1c642dSBill Krier /*ARGSUSED*/ 689fe1c642dSBill Krier static int 690fe1c642dSBill Krier samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa) 691fe1c642dSBill Krier { 692fe1c642dSBill Krier static uint16_t owf_buf[8]; 693fe1c642dSBill Krier static uint8_t hour_buf[SAMR_SET_USER_HOURS_SZ]; 694fe1c642dSBill Krier struct samr_QueryUserInfo *param = arg; 695fe1c642dSBill Krier struct samr_QueryUserInfo21 *all_info; 696fe1c642dSBill Krier ndr_hdid_t *id; 697fe1c642dSBill Krier ndr_handle_t *hd; 698fe1c642dSBill Krier samr_keydata_t *data; 699fe1c642dSBill Krier smb_domain_t di; 700fe1c642dSBill Krier smb_account_t account; 701fe1c642dSBill Krier smb_sid_t *sid; 702fe1c642dSBill Krier uint32_t status; 703fe1c642dSBill Krier 704fe1c642dSBill Krier id = (ndr_hdid_t *)¶m->user_handle; 705fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) { 706fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE; 707fe1c642dSBill Krier goto QueryUserInfoError; 708fe1c642dSBill Krier } 709fe1c642dSBill Krier 710fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data; 711fe1c642dSBill Krier 712fe1c642dSBill Krier if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) { 713fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED; 714fe1c642dSBill Krier goto QueryUserInfoError; 715fe1c642dSBill Krier } 716fe1c642dSBill Krier 717fe1c642dSBill Krier if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) { 718fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED; 719fe1c642dSBill Krier goto QueryUserInfoError; 720fe1c642dSBill Krier } 721fe1c642dSBill Krier 722fe1c642dSBill Krier if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) { 723fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED; 724fe1c642dSBill Krier goto QueryUserInfoError; 725fe1c642dSBill Krier } 726fe1c642dSBill Krier 727fe1c642dSBill Krier if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) { 728fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED; 729fe1c642dSBill Krier goto QueryUserInfoError; 730fe1c642dSBill Krier } 731fe1c642dSBill Krier 732fe1c642dSBill Krier all_info = ¶m->ru.info21; 733fe1c642dSBill Krier bzero(all_info, sizeof (struct samr_QueryUserInfo21)); 734fe1c642dSBill Krier 735fe1c642dSBill Krier all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID; 736fe1c642dSBill Krier 737fe1c642dSBill Krier (void) NDR_MSTRING(mxa, account.a_name, 738fe1c642dSBill Krier (ndr_mstring_t *)&all_info->UserName); 739fe1c642dSBill Krier all_info->UserId = data->kd_rid; 740fe1c642dSBill Krier 741fe1c642dSBill Krier all_info->LmOwfPassword.length = 16; 742fe1c642dSBill Krier all_info->LmOwfPassword.maxlen = 16; 743fe1c642dSBill Krier all_info->LmOwfPassword.buf = owf_buf; 744fe1c642dSBill Krier all_info->NtOwfPassword.length = 16; 745fe1c642dSBill Krier all_info->NtOwfPassword.maxlen = 16; 746fe1c642dSBill Krier all_info->NtOwfPassword.buf = owf_buf; 747fe1c642dSBill Krier all_info->LogonHours.units_per_week = SAMR_HOURS_PER_WEEK; 748fe1c642dSBill Krier all_info->LogonHours.hours = hour_buf; 749fe1c642dSBill Krier 750fe1c642dSBill Krier param->address = 1; 751fe1c642dSBill Krier param->switch_index = SAMR_QUERY_USER_ALL_INFO; 752fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 7539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_account_free(&account); 7549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_sid_free(sid); 755fe1c642dSBill Krier return (NDR_DRC_OK); 756fe1c642dSBill Krier 757fe1c642dSBill Krier QueryUserInfoError: 7589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_sid_free(sid); 759fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryUserInfo)); 760fe1c642dSBill Krier param->status = NT_SC_ERROR(status); 761fe1c642dSBill Krier return (NDR_DRC_OK); 762fe1c642dSBill Krier } 763fe1c642dSBill Krier 764fe1c642dSBill Krier /* 765fe1c642dSBill Krier * samr_s_QueryUserGroups 766fe1c642dSBill Krier * 767fe1c642dSBill Krier * Request the list of groups of which a user is a member. 768fe1c642dSBill Krier * The user is identified from the handle, which contains an 769fe1c642dSBill Krier * rid in the discriminator field. Note that this is a local user. 770fe1c642dSBill Krier */ 771fe1c642dSBill Krier static int 772fe1c642dSBill Krier samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa) 773fe1c642dSBill Krier { 774fe1c642dSBill Krier struct samr_QueryUserGroups *param = arg; 775fe1c642dSBill Krier struct samr_UserGroupInfo *info; 776fe1c642dSBill Krier struct samr_UserGroups *group; 777fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->user_handle; 778fe1c642dSBill Krier ndr_handle_t *hd; 779fe1c642dSBill Krier samr_keydata_t *data; 780fe1c642dSBill Krier smb_sid_t *user_sid = NULL; 781fe1c642dSBill Krier smb_group_t grp; 782fe1c642dSBill Krier smb_giter_t gi; 783fe1c642dSBill Krier smb_domain_t di; 784fe1c642dSBill Krier uint32_t status; 785fe1c642dSBill Krier int size; 786fe1c642dSBill Krier int ngrp_max; 787fe1c642dSBill Krier 788fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) { 789fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED; 790fe1c642dSBill Krier goto query_error; 791fe1c642dSBill Krier } 792fe1c642dSBill Krier 793fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data; 794fe1c642dSBill Krier switch (data->kd_type) { 795fe1c642dSBill Krier case SMB_DOMAIN_BUILTIN: 796fe1c642dSBill Krier case SMB_DOMAIN_LOCAL: 797fe1c642dSBill Krier if (!smb_domain_lookup_type(data->kd_type, &di)) { 798fe1c642dSBill Krier status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 799fe1c642dSBill Krier goto query_error; 800fe1c642dSBill Krier } 801fe1c642dSBill Krier break; 802fe1c642dSBill Krier default: 803fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE; 804fe1c642dSBill Krier goto query_error; 805fe1c642dSBill Krier } 806fe1c642dSBill Krier 807fe1c642dSBill Krier user_sid = smb_sid_splice(di.di_binsid, data->kd_rid); 808fe1c642dSBill Krier if (user_sid == NULL) { 809fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY; 810fe1c642dSBill Krier goto query_error; 811fe1c642dSBill Krier } 812fe1c642dSBill Krier 813fe1c642dSBill Krier info = NDR_NEW(mxa, struct samr_UserGroupInfo); 814fe1c642dSBill Krier if (info == NULL) { 815fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY; 816fe1c642dSBill Krier goto query_error; 817fe1c642dSBill Krier } 818fe1c642dSBill Krier bzero(info, sizeof (struct samr_UserGroupInfo)); 819fe1c642dSBill Krier 820fe1c642dSBill Krier size = 32 * 1024; 821fe1c642dSBill Krier info->groups = NDR_MALLOC(mxa, size); 822fe1c642dSBill Krier if (info->groups == NULL) { 823fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY; 824fe1c642dSBill Krier goto query_error; 825fe1c642dSBill Krier } 826fe1c642dSBill Krier ngrp_max = size / sizeof (struct samr_UserGroups); 827fe1c642dSBill Krier 828fe1c642dSBill Krier if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 829fe1c642dSBill Krier status = NT_STATUS_INTERNAL_ERROR; 830fe1c642dSBill Krier goto query_error; 831fe1c642dSBill Krier } 832fe1c642dSBill Krier 833fe1c642dSBill Krier info->n_entry = 0; 834fe1c642dSBill Krier group = info->groups; 835fe1c642dSBill Krier while ((info->n_entry < ngrp_max) && 836fe1c642dSBill Krier (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS)) { 837fe1c642dSBill Krier if (smb_lgrp_is_member(&grp, user_sid)) { 838fe1c642dSBill Krier group->rid = grp.sg_rid; 839fe1c642dSBill Krier group->attr = grp.sg_attr; 840fe1c642dSBill Krier group++; 841fe1c642dSBill Krier info->n_entry++; 842fe1c642dSBill Krier } 843fe1c642dSBill Krier smb_lgrp_free(&grp); 844fe1c642dSBill Krier } 845fe1c642dSBill Krier smb_lgrp_iterclose(&gi); 846fe1c642dSBill Krier 847fe1c642dSBill Krier free(user_sid); 848fe1c642dSBill Krier param->info = info; 849fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 850fe1c642dSBill Krier return (NDR_DRC_OK); 851fe1c642dSBill Krier 852fe1c642dSBill Krier query_error: 853fe1c642dSBill Krier free(user_sid); 854fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryUserGroups)); 855fe1c642dSBill Krier param->status = NT_SC_ERROR(status); 856fe1c642dSBill Krier return (NDR_DRC_OK); 857fe1c642dSBill Krier } 858fe1c642dSBill Krier 859fe1c642dSBill Krier /* 860fe1c642dSBill Krier * samr_s_OpenGroup 861fe1c642dSBill Krier * 862fe1c642dSBill Krier * This is a request to open a group within the specified domain in the 863fe1c642dSBill Krier * local SAM database. The caller must supply a valid domain handle, 864fe1c642dSBill Krier * obtained via a successful domain open request. The group is 865fe1c642dSBill Krier * specified by the rid in the request. If this is a local RID it 866fe1c642dSBill Krier * should already be encoded with type information. 867fe1c642dSBill Krier * 868fe1c642dSBill Krier * We return a handle to be used to access information about this group. 869fe1c642dSBill Krier */ 870fe1c642dSBill Krier static int 871fe1c642dSBill Krier samr_s_OpenGroup(void *arg, ndr_xa_t *mxa) 872fe1c642dSBill Krier { 873fe1c642dSBill Krier struct samr_OpenGroup *param = arg; 874fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 875fe1c642dSBill Krier ndr_handle_t *hd; 876fe1c642dSBill Krier samr_keydata_t *data; 877fe1c642dSBill Krier 878fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 879fe1c642dSBill Krier bzero(¶m->group_handle, sizeof (samr_handle_t)); 880fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 881fe1c642dSBill Krier return (NDR_DRC_OK); 882fe1c642dSBill Krier } 883fe1c642dSBill Krier 884fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data; 885fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_GROUP, data->kd_type, param->rid); 886fe1c642dSBill Krier 887fe1c642dSBill Krier if (id) { 888fe1c642dSBill Krier bcopy(id, ¶m->group_handle, sizeof (samr_handle_t)); 889fe1c642dSBill Krier param->status = 0; 890fe1c642dSBill Krier } else { 891fe1c642dSBill Krier bzero(¶m->group_handle, sizeof (samr_handle_t)); 892fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 893fe1c642dSBill Krier } 894fe1c642dSBill Krier 895fe1c642dSBill Krier return (NDR_DRC_OK); 896fe1c642dSBill Krier } 897fe1c642dSBill Krier 898fe1c642dSBill Krier /* 899c5866007SKeyur Desai * samr_s_AddAliasMember 900c5866007SKeyur Desai * 901c5866007SKeyur Desai * Add a member to a local SAM group. 902c5866007SKeyur Desai * The caller must supply a valid group handle. 903c5866007SKeyur Desai * The member is specified by the sid in the request. 904c5866007SKeyur Desai */ 905c5866007SKeyur Desai static int 906c5866007SKeyur Desai samr_s_AddAliasMember(void *arg, ndr_xa_t *mxa) 907c5866007SKeyur Desai { 908c5866007SKeyur Desai struct samr_AddAliasMember *param = arg; 909c5866007SKeyur Desai ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 910c5866007SKeyur Desai ndr_handle_t *hd; 911c5866007SKeyur Desai samr_keydata_t *data; 912c5866007SKeyur Desai smb_group_t grp; 913c5866007SKeyur Desai uint32_t rc; 914c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS; 915c5866007SKeyur Desai 916c5866007SKeyur Desai if (param->sid == NULL) { 917c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember)); 918c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 919c5866007SKeyur Desai return (NDR_DRC_OK); 920c5866007SKeyur Desai } 921c5866007SKeyur Desai 922c5866007SKeyur Desai if (!ndr_is_admin(mxa)) { 923c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember)); 924c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 925c5866007SKeyur Desai return (NDR_DRC_OK); 926c5866007SKeyur Desai } 927c5866007SKeyur Desai 928c5866007SKeyur Desai 929c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 930c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember)); 931c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 932c5866007SKeyur Desai return (NDR_DRC_OK); 933c5866007SKeyur Desai } 934c5866007SKeyur Desai 935c5866007SKeyur Desai data = (samr_keydata_t *)hd->nh_data; 936c5866007SKeyur Desai rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp); 937c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) { 938c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember)); 939c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc); 940c5866007SKeyur Desai param->status = NT_SC_ERROR(status); 941c5866007SKeyur Desai return (NDR_DRC_OK); 942c5866007SKeyur Desai } 943c5866007SKeyur Desai 944c5866007SKeyur Desai rc = smb_lgrp_add_member(grp.sg_name, 945c5866007SKeyur Desai (smb_sid_t *)param->sid, SidTypeUser); 946c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) { 947c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember)); 948c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc); 949c5866007SKeyur Desai param->status = NT_SC_ERROR(status); 950c5866007SKeyur Desai } 951c5866007SKeyur Desai smb_lgrp_free(&grp); 952c5866007SKeyur Desai 953c5866007SKeyur Desai param->status = status; 954c5866007SKeyur Desai return (NDR_DRC_OK); 955c5866007SKeyur Desai } 956c5866007SKeyur Desai 957c5866007SKeyur Desai /* 958c5866007SKeyur Desai * samr_s_DeleteAliasMember 959c5866007SKeyur Desai * 960c5866007SKeyur Desai * Delete a member from a local SAM group. 961c5866007SKeyur Desai * The caller must supply a valid group handle. 962c5866007SKeyur Desai * The member is specified by the sid in the request. 963c5866007SKeyur Desai */ 964c5866007SKeyur Desai static int 965c5866007SKeyur Desai samr_s_DeleteAliasMember(void *arg, ndr_xa_t *mxa) 966c5866007SKeyur Desai { 967c5866007SKeyur Desai struct samr_DeleteAliasMember *param = arg; 968c5866007SKeyur Desai ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 969c5866007SKeyur Desai ndr_handle_t *hd; 970c5866007SKeyur Desai samr_keydata_t *data; 971c5866007SKeyur Desai smb_group_t grp; 972c5866007SKeyur Desai uint32_t rc; 973c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS; 974c5866007SKeyur Desai 975c5866007SKeyur Desai if (param->sid == NULL) { 976c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember)); 977c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 978c5866007SKeyur Desai return (NDR_DRC_OK); 979c5866007SKeyur Desai } 980c5866007SKeyur Desai 981c5866007SKeyur Desai if (!ndr_is_admin(mxa)) { 982c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember)); 983c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 984c5866007SKeyur Desai return (NDR_DRC_OK); 985c5866007SKeyur Desai } 986c5866007SKeyur Desai 987c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 988c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember)); 989c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 990c5866007SKeyur Desai return (NDR_DRC_OK); 991c5866007SKeyur Desai } 992c5866007SKeyur Desai 993c5866007SKeyur Desai data = (samr_keydata_t *)hd->nh_data; 994c5866007SKeyur Desai rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp); 995c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) { 996c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember)); 997c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc); 998c5866007SKeyur Desai param->status = NT_SC_ERROR(status); 999c5866007SKeyur Desai return (NDR_DRC_OK); 1000c5866007SKeyur Desai } 1001c5866007SKeyur Desai 1002c5866007SKeyur Desai rc = smb_lgrp_del_member(grp.sg_name, 1003c5866007SKeyur Desai (smb_sid_t *)param->sid, SidTypeUser); 1004c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) { 1005c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember)); 1006c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc); 1007c5866007SKeyur Desai param->status = NT_SC_ERROR(status); 1008c5866007SKeyur Desai } 1009c5866007SKeyur Desai smb_lgrp_free(&grp); 1010c5866007SKeyur Desai 1011c5866007SKeyur Desai param->status = status; 1012c5866007SKeyur Desai return (NDR_DRC_OK); 1013c5866007SKeyur Desai } 1014c5866007SKeyur Desai 1015c5866007SKeyur Desai /* 1016c5866007SKeyur Desai * samr_s_ListAliasMembers 1017c5866007SKeyur Desai * 1018c5866007SKeyur Desai * List members from a local SAM group. 1019c5866007SKeyur Desai * The caller must supply a valid group handle. 1020c5866007SKeyur Desai * A list of user SIDs in the specified group is returned to the caller. 1021c5866007SKeyur Desai */ 1022c5866007SKeyur Desai static int 1023c5866007SKeyur Desai samr_s_ListAliasMembers(void *arg, ndr_xa_t *mxa) 1024c5866007SKeyur Desai { 1025c5866007SKeyur Desai struct samr_ListAliasMembers *param = arg; 1026c5866007SKeyur Desai ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1027c5866007SKeyur Desai ndr_handle_t *hd; 1028c5866007SKeyur Desai samr_keydata_t *data; 1029c5866007SKeyur Desai smb_group_t grp; 1030c5866007SKeyur Desai smb_gsid_t *members; 1031c5866007SKeyur Desai struct samr_SidInfo info; 1032c5866007SKeyur Desai struct samr_SidList *user; 1033c5866007SKeyur Desai uint32_t num = 0, size; 1034c5866007SKeyur Desai int i; 1035c5866007SKeyur Desai uint32_t rc; 1036c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS; 1037c5866007SKeyur Desai 1038c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 1039c5866007SKeyur Desai bzero(param, sizeof (struct samr_ListAliasMembers)); 1040c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 1041c5866007SKeyur Desai return (NDR_DRC_OK); 1042c5866007SKeyur Desai } 1043c5866007SKeyur Desai 1044c5866007SKeyur Desai bzero(&info, sizeof (struct samr_SidInfo)); 1045c5866007SKeyur Desai data = (samr_keydata_t *)hd->nh_data; 1046c5866007SKeyur Desai rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp); 1047c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) { 1048c5866007SKeyur Desai bzero(param, sizeof (struct samr_ListAliasMembers)); 1049c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc); 1050c5866007SKeyur Desai param->status = NT_SC_ERROR(status); 1051c5866007SKeyur Desai return (NDR_DRC_OK); 1052c5866007SKeyur Desai } 1053c5866007SKeyur Desai 1054c5866007SKeyur Desai num = grp.sg_nmembers; 1055c5866007SKeyur Desai members = grp.sg_members; 1056c5866007SKeyur Desai size = num * sizeof (struct samr_SidList); 1057c5866007SKeyur Desai info.sidlist = NDR_MALLOC(mxa, size); 1058c5866007SKeyur Desai if (info.sidlist == NULL) { 1059c5866007SKeyur Desai bzero(param, sizeof (struct samr_ListAliasMembers)); 1060c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1061c5866007SKeyur Desai smb_lgrp_free(&grp); 1062c5866007SKeyur Desai return (NDR_DRC_OK); 1063c5866007SKeyur Desai } 1064c5866007SKeyur Desai 1065c5866007SKeyur Desai info.n_entry = num; 1066c5866007SKeyur Desai user = info.sidlist; 1067c5866007SKeyur Desai for (i = 0; i < num; i++) { 1068c5866007SKeyur Desai user->sid = (struct samr_sid *)NDR_SIDDUP(mxa, 1069c5866007SKeyur Desai members[i].gs_sid); 1070c5866007SKeyur Desai if (user->sid == NULL) { 1071c5866007SKeyur Desai bzero(param, sizeof (struct samr_ListAliasMembers)); 1072c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1073c5866007SKeyur Desai smb_lgrp_free(&grp); 1074c5866007SKeyur Desai return (NDR_DRC_OK); 1075c5866007SKeyur Desai } 1076c5866007SKeyur Desai user++; 1077c5866007SKeyur Desai } 1078c5866007SKeyur Desai smb_lgrp_free(&grp); 1079c5866007SKeyur Desai 1080c5866007SKeyur Desai param->info = info; 1081c5866007SKeyur Desai param->status = status; 1082c5866007SKeyur Desai return (NDR_DRC_OK); 1083c5866007SKeyur Desai } 1084c5866007SKeyur Desai 1085c5866007SKeyur Desai /* 1086cb174861Sjoyce mcintosh * samr_s_Connect2 1087fe1c642dSBill Krier * 1088fe1c642dSBill Krier * This is a request to connect to the local SAM database. 1089fe1c642dSBill Krier * We don't support any form of update request and our database doesn't 1090fe1c642dSBill Krier * contain any private information, so there is little point in doing 1091fe1c642dSBill Krier * any access access checking here. 1092fe1c642dSBill Krier * 1093fe1c642dSBill Krier * Return a handle for use with subsequent SAM requests. 1094fe1c642dSBill Krier */ 1095fe1c642dSBill Krier static int 1096cb174861Sjoyce mcintosh samr_s_Connect2(void *arg, ndr_xa_t *mxa) 1097fe1c642dSBill Krier { 1098cb174861Sjoyce mcintosh struct samr_Connect2 *param = arg; 1099fe1c642dSBill Krier ndr_hdid_t *id; 1100fe1c642dSBill Krier 1101fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 1102fe1c642dSBill Krier if (id) { 1103fe1c642dSBill Krier bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 1104fe1c642dSBill Krier param->status = 0; 1105fe1c642dSBill Krier } else { 1106fe1c642dSBill Krier bzero(¶m->handle, sizeof (samr_handle_t)); 1107fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1108fe1c642dSBill Krier } 1109fe1c642dSBill Krier 1110fe1c642dSBill Krier return (NDR_DRC_OK); 1111fe1c642dSBill Krier } 1112fe1c642dSBill Krier 1113fe1c642dSBill Krier /* 1114fe1c642dSBill Krier * samr_s_GetUserPwInfo 1115fe1c642dSBill Krier * 1116f96bd5c8SAlan Wright * Request for a user's password policy information. 1117fe1c642dSBill Krier */ 1118fe1c642dSBill Krier /*ARGSUSED*/ 1119fe1c642dSBill Krier static int 1120fe1c642dSBill Krier samr_s_GetUserPwInfo(void *arg, ndr_xa_t *mxa) 1121fe1c642dSBill Krier { 1122f96bd5c8SAlan Wright static samr_password_info_t pwinfo; 1123fe1c642dSBill Krier struct samr_GetUserPwInfo *param = arg; 1124fe1c642dSBill Krier 1125f96bd5c8SAlan Wright param->pwinfo = &pwinfo; 1126f96bd5c8SAlan Wright param->status = NT_STATUS_SUCCESS; 1127fe1c642dSBill Krier return (NDR_DRC_OK); 1128fe1c642dSBill Krier } 1129fe1c642dSBill Krier 1130fe1c642dSBill Krier /* 1131fe1c642dSBill Krier * samr_s_CreateUser 1132fe1c642dSBill Krier */ 1133fe1c642dSBill Krier /*ARGSUSED*/ 1134fe1c642dSBill Krier static int 1135fe1c642dSBill Krier samr_s_CreateUser(void *arg, ndr_xa_t *mxa) 1136fe1c642dSBill Krier { 1137fe1c642dSBill Krier struct samr_CreateUser *param = arg; 1138fe1c642dSBill Krier 1139fe1c642dSBill Krier bzero(¶m->user_handle, sizeof (samr_handle_t)); 1140fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 1141fe1c642dSBill Krier return (NDR_DRC_OK); 1142fe1c642dSBill Krier } 1143fe1c642dSBill Krier 1144fe1c642dSBill Krier /* 11451ed6b69aSGordon Ross * samr_s_ChangePasswordUser2 1146fe1c642dSBill Krier */ 1147fe1c642dSBill Krier /*ARGSUSED*/ 1148fe1c642dSBill Krier static int 11491ed6b69aSGordon Ross samr_s_ChangePasswordUser2(void *arg, ndr_xa_t *mxa) 1150fe1c642dSBill Krier { 11511ed6b69aSGordon Ross struct samr_ChangePasswordUser2 *param = arg; 1152fe1c642dSBill Krier 11531ed6b69aSGordon Ross bzero(param, sizeof (*param)); 1154fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 1155fe1c642dSBill Krier return (NDR_DRC_OK); 1156fe1c642dSBill Krier } 1157fe1c642dSBill Krier 1158fe1c642dSBill Krier /* 1159fe1c642dSBill Krier * samr_s_GetDomainPwInfo 1160f96bd5c8SAlan Wright * 1161f96bd5c8SAlan Wright * Request for the domain password policy information. 1162fe1c642dSBill Krier */ 1163fe1c642dSBill Krier /*ARGSUSED*/ 1164fe1c642dSBill Krier static int 1165fe1c642dSBill Krier samr_s_GetDomainPwInfo(void *arg, ndr_xa_t *mxa) 1166fe1c642dSBill Krier { 1167f96bd5c8SAlan Wright static samr_password_info_t pwinfo; 1168fe1c642dSBill Krier struct samr_GetDomainPwInfo *param = arg; 1169fe1c642dSBill Krier 1170f96bd5c8SAlan Wright param->pwinfo = &pwinfo; 1171f96bd5c8SAlan Wright param->status = NT_STATUS_SUCCESS; 1172fe1c642dSBill Krier return (NDR_DRC_OK); 1173fe1c642dSBill Krier } 1174fe1c642dSBill Krier 1175fe1c642dSBill Krier /* 1176fe1c642dSBill Krier * samr_s_SetUserInfo 1177fe1c642dSBill Krier */ 1178fe1c642dSBill Krier /*ARGSUSED*/ 1179fe1c642dSBill Krier static int 1180fe1c642dSBill Krier samr_s_SetUserInfo(void *arg, ndr_xa_t *mxa) 1181fe1c642dSBill Krier { 1182fe1c642dSBill Krier struct samr_SetUserInfo *param = arg; 1183fe1c642dSBill Krier 1184fe1c642dSBill Krier bzero(param, sizeof (struct samr_SetUserInfo)); 1185fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 1186fe1c642dSBill Krier return (NDR_DRC_OK); 1187fe1c642dSBill Krier } 1188fe1c642dSBill Krier 1189fe1c642dSBill Krier /* 1190fe1c642dSBill Krier * samr_s_QueryDispInfo 1191fe1c642dSBill Krier * 1192fe1c642dSBill Krier * This function currently return local users' information only. 1193fe1c642dSBill Krier * This RPC is called repeatedly until all the users info are 1194fe1c642dSBill Krier * retrieved. 1195fe1c642dSBill Krier * 1196fe1c642dSBill Krier * The total count and the returned count are returned as total size 1197fe1c642dSBill Krier * and returned size. The client doesn't seem to care. 1198fe1c642dSBill Krier */ 1199fe1c642dSBill Krier static int 1200fe1c642dSBill Krier samr_s_QueryDispInfo(void *arg, ndr_xa_t *mxa) 1201fe1c642dSBill Krier { 1202fe1c642dSBill Krier struct samr_QueryDispInfo *param = arg; 1203fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 1204fe1c642dSBill Krier ndr_handle_t *hd; 1205fe1c642dSBill Krier samr_keydata_t *data; 1206fe1c642dSBill Krier DWORD status = NT_STATUS_SUCCESS; 1207fe1c642dSBill Krier struct user_acct_info *user; 1208fe1c642dSBill Krier smb_pwditer_t pwi; 1209fe1c642dSBill Krier smb_luser_t *uinfo; 1210fe1c642dSBill Krier int num_users; 1211fe1c642dSBill Krier int start_idx; 1212fe1c642dSBill Krier int max_retcnt, retcnt; 1213fe1c642dSBill Krier int skip; 1214fe1c642dSBill Krier 1215fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 1216fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE; 1217fe1c642dSBill Krier goto error; 1218fe1c642dSBill Krier } 1219fe1c642dSBill Krier 1220fe1c642dSBill Krier if (!SAMR_VALID_DISPLEVEL(param->level)) { 1221fe1c642dSBill Krier status = NT_STATUS_INVALID_INFO_CLASS; 1222fe1c642dSBill Krier goto error; 1223fe1c642dSBill Krier } 1224fe1c642dSBill Krier 1225fe1c642dSBill Krier if (!SAMR_SUPPORTED_DISPLEVEL(param->level)) { 1226fe1c642dSBill Krier status = NT_STATUS_NOT_IMPLEMENTED; 1227fe1c642dSBill Krier goto error; 1228fe1c642dSBill Krier } 1229fe1c642dSBill Krier 1230fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data; 1231fe1c642dSBill Krier 1232fe1c642dSBill Krier switch (data->kd_type) { 1233fe1c642dSBill Krier case SMB_DOMAIN_BUILTIN: 1234fe1c642dSBill Krier goto no_info; 1235fe1c642dSBill Krier 1236fe1c642dSBill Krier case SMB_DOMAIN_LOCAL: 1237fe1c642dSBill Krier num_users = smb_sam_usr_cnt(); 1238fe1c642dSBill Krier start_idx = param->start_idx; 1239fe1c642dSBill Krier if ((num_users == 0) || (start_idx >= num_users)) 1240fe1c642dSBill Krier goto no_info; 1241fe1c642dSBill Krier 1242fe1c642dSBill Krier max_retcnt = num_users - start_idx; 1243fe1c642dSBill Krier if (max_retcnt > param->max_entries) 1244fe1c642dSBill Krier max_retcnt = param->max_entries; 1245fe1c642dSBill Krier param->users.acct = NDR_MALLOC(mxa, 1246fe1c642dSBill Krier max_retcnt * sizeof (struct user_acct_info)); 1247fe1c642dSBill Krier user = param->users.acct; 1248fe1c642dSBill Krier if (user == NULL) { 1249fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY; 1250fe1c642dSBill Krier goto error; 1251fe1c642dSBill Krier } 1252fe1c642dSBill Krier bzero(user, max_retcnt * sizeof (struct user_acct_info)); 1253fe1c642dSBill Krier 1254fe1c642dSBill Krier if (smb_pwd_iteropen(&pwi) != SMB_PWE_SUCCESS) 1255fe1c642dSBill Krier goto no_info; 1256fe1c642dSBill Krier 1257fe1c642dSBill Krier skip = retcnt = 0; 1258fe1c642dSBill Krier while ((uinfo = smb_pwd_iterate(&pwi)) != NULL) { 1259fe1c642dSBill Krier if (skip++ < start_idx) 1260fe1c642dSBill Krier continue; 1261fe1c642dSBill Krier 1262fe1c642dSBill Krier if (retcnt++ >= max_retcnt) 1263fe1c642dSBill Krier break; 1264fe1c642dSBill Krier 1265fe1c642dSBill Krier assert(uinfo->su_name != NULL); 1266fe1c642dSBill Krier 1267fe1c642dSBill Krier user->index = start_idx + retcnt; 1268fe1c642dSBill Krier user->rid = uinfo->su_rid; 1269fe1c642dSBill Krier user->ctrl = ACF_NORMUSER | ACF_PWDNOEXP; 1270fe1c642dSBill Krier if (uinfo->su_ctrl & SMB_PWF_DISABLE) 1271fe1c642dSBill Krier user->ctrl |= ACF_DISABLED; 1272fe1c642dSBill Krier if (NDR_MSTRING(mxa, uinfo->su_name, 1273fe1c642dSBill Krier (ndr_mstring_t *)&user->name) == -1) { 1274fe1c642dSBill Krier smb_pwd_iterclose(&pwi); 1275fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY; 1276fe1c642dSBill Krier goto error; 1277fe1c642dSBill Krier } 1278fe1c642dSBill Krier (void) NDR_MSTRING(mxa, uinfo->su_fullname, 1279fe1c642dSBill Krier (ndr_mstring_t *)&user->fullname); 1280fe1c642dSBill Krier (void) NDR_MSTRING(mxa, uinfo->su_desc, 1281fe1c642dSBill Krier (ndr_mstring_t *)&user->desc); 1282fe1c642dSBill Krier user++; 1283fe1c642dSBill Krier } 1284fe1c642dSBill Krier smb_pwd_iterclose(&pwi); 1285fe1c642dSBill Krier 1286fe1c642dSBill Krier if (retcnt >= max_retcnt) { 1287fe1c642dSBill Krier retcnt = max_retcnt; 1288fe1c642dSBill Krier param->status = status; 1289fe1c642dSBill Krier } else { 1290148c5f43SAlan Wright param->status = NT_STATUS_MORE_ENTRIES; 1291fe1c642dSBill Krier } 1292fe1c642dSBill Krier 1293fe1c642dSBill Krier param->users.total_size = num_users; 1294fe1c642dSBill Krier param->users.returned_size = retcnt; 1295fe1c642dSBill Krier param->users.switch_value = param->level; 1296fe1c642dSBill Krier param->users.count = retcnt; 1297fe1c642dSBill Krier 1298fe1c642dSBill Krier break; 1299fe1c642dSBill Krier 1300fe1c642dSBill Krier default: 1301fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE; 1302fe1c642dSBill Krier goto error; 1303fe1c642dSBill Krier } 1304fe1c642dSBill Krier 1305fe1c642dSBill Krier return (NDR_DRC_OK); 1306fe1c642dSBill Krier 1307fe1c642dSBill Krier no_info: 1308fe1c642dSBill Krier param->users.total_size = 0; 1309fe1c642dSBill Krier param->users.returned_size = 0; 1310fe1c642dSBill Krier param->users.switch_value = param->level; 1311fe1c642dSBill Krier param->users.count = 0; 1312fe1c642dSBill Krier param->users.acct = NULL; 1313fe1c642dSBill Krier param->status = status; 1314fe1c642dSBill Krier return (NDR_DRC_OK); 1315fe1c642dSBill Krier 1316fe1c642dSBill Krier error: 1317fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDispInfo)); 1318fe1c642dSBill Krier param->status = NT_SC_ERROR(status); 1319fe1c642dSBill Krier return (NDR_DRC_OK); 1320fe1c642dSBill Krier } 1321fe1c642dSBill Krier 1322fe1c642dSBill Krier /* 1323fe1c642dSBill Krier * samr_s_EnumDomainGroups 1324fe1c642dSBill Krier * 1325fe1c642dSBill Krier * 1326fe1c642dSBill Krier * This function is supposed to return local group information. 1327fe1c642dSBill Krier * As we don't support local users, this function dosen't send 1328fe1c642dSBill Krier * back any information. 1329fe1c642dSBill Krier * 1330fe1c642dSBill Krier * Added template that returns information for a domain group as None. 1331fe1c642dSBill Krier * All information is hard-coded from packet captures. 1332fe1c642dSBill Krier */ 1333fe1c642dSBill Krier static int 1334fe1c642dSBill Krier samr_s_EnumDomainGroups(void *arg, ndr_xa_t *mxa) 1335fe1c642dSBill Krier { 1336fe1c642dSBill Krier struct samr_EnumDomainGroups *param = arg; 1337fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 1338fe1c642dSBill Krier DWORD status = NT_STATUS_SUCCESS; 1339fe1c642dSBill Krier 1340fe1c642dSBill Krier if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) 1341fe1c642dSBill Krier status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 1342fe1c642dSBill Krier 1343fe1c642dSBill Krier param->total_size = 0; 1344fe1c642dSBill Krier param->returned_size = 0; 1345fe1c642dSBill Krier param->switch_value = 3; 1346fe1c642dSBill Krier param->count = 0; 1347fe1c642dSBill Krier param->groups = 0; 1348fe1c642dSBill Krier param->status = status; 1349fe1c642dSBill Krier return (NDR_DRC_OK); 1350fe1c642dSBill Krier 1351fe1c642dSBill Krier #ifdef SAMR_SUPPORT_GROUPS 1352fe1c642dSBill Krier if ((desc->discrim != SAMR_LOCAL_DOMAIN) || (param->start_idx != 0)) { 1353fe1c642dSBill Krier param->total_size = 0; 1354fe1c642dSBill Krier param->returned_size = 0; 1355fe1c642dSBill Krier param->switch_value = 3; 1356fe1c642dSBill Krier param->count = 0; 1357fe1c642dSBill Krier param->groups = 0; 1358fe1c642dSBill Krier } else { 1359fe1c642dSBill Krier param->total_size = 64; 1360fe1c642dSBill Krier param->returned_size = 64; 1361fe1c642dSBill Krier param->switch_value = 3; 1362fe1c642dSBill Krier param->count = 1; 1363fe1c642dSBill Krier param->groups = (struct group_disp_info *)NDR_MALLOC( 1364fe1c642dSBill Krier mxa, sizeof (struct group_disp_info)); 1365fe1c642dSBill Krier 1366fe1c642dSBill Krier param->groups->count = 1; 1367fe1c642dSBill Krier param->groups->acct[0].index = 1; 1368fe1c642dSBill Krier param->groups->acct[0].rid = 513; 1369fe1c642dSBill Krier param->groups->acct[0].ctrl = 0x7; 1370fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "None", 1371fe1c642dSBill Krier (ndr_mstring_t *)¶m->groups->acct[0].name); 1372fe1c642dSBill Krier 1373fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "Ordinary users", 1374fe1c642dSBill Krier (ndr_mstring_t *)¶m->groups->acct[0].desc); 1375fe1c642dSBill Krier } 1376fe1c642dSBill Krier 1377fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 1378fe1c642dSBill Krier return (NDR_DRC_OK); 1379fe1c642dSBill Krier #endif 1380fe1c642dSBill Krier } 1381fe1c642dSBill Krier 1382fe1c642dSBill Krier /* 1383fe1c642dSBill Krier * samr_s_OpenAlias 1384fe1c642dSBill Krier * 1385fe1c642dSBill Krier * Lookup for requested alias, if it exists return a handle 1386fe1c642dSBill Krier * for that alias. The alias domain sid should match with 1387fe1c642dSBill Krier * the passed domain handle. 1388fe1c642dSBill Krier */ 1389fe1c642dSBill Krier static int 1390fe1c642dSBill Krier samr_s_OpenAlias(void *arg, ndr_xa_t *mxa) 1391fe1c642dSBill Krier { 1392fe1c642dSBill Krier struct samr_OpenAlias *param = arg; 1393fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 1394fe1c642dSBill Krier ndr_handle_t *hd; 1395fe1c642dSBill Krier samr_keydata_t *data; 13969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_domain_type_t gd_type; 1397f96bd5c8SAlan Wright smb_sid_t *sid; 1398f96bd5c8SAlan Wright smb_wka_t *wka; 1399f96bd5c8SAlan Wright char sidstr[SMB_SID_STRSZ]; 1400f96bd5c8SAlan Wright uint32_t rid; 1401f96bd5c8SAlan Wright uint32_t status; 1402fe1c642dSBill Krier int rc; 1403fe1c642dSBill Krier 1404fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 1405fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE; 1406fe1c642dSBill Krier goto open_alias_err; 1407fe1c642dSBill Krier } 1408fe1c642dSBill Krier 1409c5866007SKeyur Desai if ((param->access_mask & SAMR_ALIAS_ACCESS_ALL_ACCESS) == 0) { 1410fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED; 1411fe1c642dSBill Krier goto open_alias_err; 1412fe1c642dSBill Krier } 1413fe1c642dSBill Krier 1414fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data; 14159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States gd_type = (smb_domain_type_t)data->kd_type; 1416f96bd5c8SAlan Wright rid = param->rid; 1417f96bd5c8SAlan Wright 1418f96bd5c8SAlan Wright switch (gd_type) { 14199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_DOMAIN_BUILTIN: 1420f96bd5c8SAlan Wright (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d", 1421f96bd5c8SAlan Wright NT_BUILTIN_DOMAIN_SIDSTR, rid); 1422f96bd5c8SAlan Wright if ((sid = smb_sid_fromstr(sidstr)) == NULL) { 1423f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS; 1424f96bd5c8SAlan Wright goto open_alias_err; 1425f96bd5c8SAlan Wright } 1426f96bd5c8SAlan Wright 1427f96bd5c8SAlan Wright wka = smb_wka_lookup_sid(sid); 1428f96bd5c8SAlan Wright smb_sid_free(sid); 1429f96bd5c8SAlan Wright 1430f96bd5c8SAlan Wright if (wka == NULL) { 1431f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS; 1432f96bd5c8SAlan Wright goto open_alias_err; 1433f96bd5c8SAlan Wright } 1434f96bd5c8SAlan Wright break; 1435f96bd5c8SAlan Wright 14369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_DOMAIN_LOCAL: 1437f96bd5c8SAlan Wright rc = smb_lgrp_getbyrid(rid, gd_type, NULL); 1438fe1c642dSBill Krier if (rc != SMB_LGRP_SUCCESS) { 1439fe1c642dSBill Krier status = NT_STATUS_NO_SUCH_ALIAS; 1440fe1c642dSBill Krier goto open_alias_err; 1441fe1c642dSBill Krier } 1442f96bd5c8SAlan Wright break; 1443f96bd5c8SAlan Wright 1444f96bd5c8SAlan Wright default: 1445f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS; 1446f96bd5c8SAlan Wright goto open_alias_err; 1447f96bd5c8SAlan Wright } 1448fe1c642dSBill Krier 1449fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, data->kd_type, param->rid); 1450fe1c642dSBill Krier if (id) { 1451fe1c642dSBill Krier bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t)); 1452fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 1453fe1c642dSBill Krier return (NDR_DRC_OK); 1454fe1c642dSBill Krier } 1455fe1c642dSBill Krier 1456fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY; 1457fe1c642dSBill Krier 1458fe1c642dSBill Krier open_alias_err: 1459fe1c642dSBill Krier bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1460fe1c642dSBill Krier param->status = NT_SC_ERROR(status); 1461fe1c642dSBill Krier return (NDR_DRC_OK); 1462fe1c642dSBill Krier } 1463fe1c642dSBill Krier 1464fe1c642dSBill Krier /* 1465fe1c642dSBill Krier * samr_s_CreateDomainAlias 1466fe1c642dSBill Krier * 1467c5866007SKeyur Desai * Create a local group in the security accounts manager (SAM) database. 1468c5866007SKeyur Desai * A local SAM group can only be added if a Solaris group already exists 1469c5866007SKeyur Desai * with the same name. On success, a valid group handle is returned. 1470c5866007SKeyur Desai * 1471c5866007SKeyur Desai * The caller must have administrator rights to execute this function. 1472fe1c642dSBill Krier */ 1473fe1c642dSBill Krier static int 1474fe1c642dSBill Krier samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa) 1475fe1c642dSBill Krier { 1476fe1c642dSBill Krier struct samr_CreateDomainAlias *param = arg; 1477fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1478c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS; 1479c5866007SKeyur Desai smb_group_t grp; 1480c5866007SKeyur Desai uint32_t rc; 1481c5866007SKeyur Desai char *gname; 1482fe1c642dSBill Krier 1483c5866007SKeyur Desai if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) != NULL) { 1484fe1c642dSBill Krier bzero(param, sizeof (struct samr_CreateDomainAlias)); 1485fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 1486fe1c642dSBill Krier return (NDR_DRC_OK); 1487fe1c642dSBill Krier } 1488fe1c642dSBill Krier 1489c5866007SKeyur Desai gname = (char *)param->alias_name.str; 1490c5866007SKeyur Desai if (gname == NULL) { 1491c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1492c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 1493c5866007SKeyur Desai return (NDR_DRC_OK); 1494c5866007SKeyur Desai } 1495c5866007SKeyur Desai 1496c5866007SKeyur Desai if ((!ndr_is_admin(mxa)) || 1497c5866007SKeyur Desai ((param->access_mask & SAMR_ALIAS_ACCESS_WRITE_ACCOUNT) == 0)) { 1498c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1499fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 1500fe1c642dSBill Krier return (NDR_DRC_OK); 1501fe1c642dSBill Krier } 1502fe1c642dSBill Krier 1503c5866007SKeyur Desai rc = smb_lgrp_add(gname, ""); 1504c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) { 1505c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1506c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc); 1507fe1c642dSBill Krier param->status = NT_SC_ERROR(status); 1508fe1c642dSBill Krier return (NDR_DRC_OK); 1509c5866007SKeyur Desai } 1510c5866007SKeyur Desai 1511c5866007SKeyur Desai rc = smb_lgrp_getbyname((char *)gname, &grp); 1512c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) { 1513c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1514c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc); 1515c5866007SKeyur Desai param->status = NT_SC_ERROR(status); 1516c5866007SKeyur Desai return (NDR_DRC_OK); 1517c5866007SKeyur Desai } 1518c5866007SKeyur Desai 1519c5866007SKeyur Desai id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, SMB_DOMAIN_LOCAL, grp.sg_rid); 1520c5866007SKeyur Desai smb_lgrp_free(&grp); 1521c5866007SKeyur Desai if (id) { 1522c5866007SKeyur Desai bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t)); 1523c5866007SKeyur Desai param->status = status; 1524c5866007SKeyur Desai } else { 1525c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1526c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1527c5866007SKeyur Desai } 1528c5866007SKeyur Desai 1529c5866007SKeyur Desai return (NDR_DRC_OK); 1530fe1c642dSBill Krier } 1531fe1c642dSBill Krier 1532fe1c642dSBill Krier /* 1533fe1c642dSBill Krier * samr_s_SetAliasInfo 1534fe1c642dSBill Krier * 1535fe1c642dSBill Krier * Similar to NetLocalGroupSetInfo. 1536fe1c642dSBill Krier */ 1537fe1c642dSBill Krier static int 1538fe1c642dSBill Krier samr_s_SetAliasInfo(void *arg, ndr_xa_t *mxa) 1539fe1c642dSBill Krier { 1540fe1c642dSBill Krier struct samr_SetAliasInfo *param = arg; 1541fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1542fe1c642dSBill Krier DWORD status = NT_STATUS_SUCCESS; 1543fe1c642dSBill Krier 1544fe1c642dSBill Krier if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) 1545fe1c642dSBill Krier status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 1546fe1c642dSBill Krier 1547fe1c642dSBill Krier param->status = status; 1548fe1c642dSBill Krier return (NDR_DRC_OK); 1549fe1c642dSBill Krier } 1550fe1c642dSBill Krier 1551fe1c642dSBill Krier /* 1552fe1c642dSBill Krier * samr_s_QueryAliasInfo 1553fe1c642dSBill Krier * 1554fe1c642dSBill Krier * Retrieves information about the specified local group account 1555fe1c642dSBill Krier * by given handle. 1556fe1c642dSBill Krier */ 1557fe1c642dSBill Krier static int 1558fe1c642dSBill Krier samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa) 1559fe1c642dSBill Krier { 1560fe1c642dSBill Krier struct samr_QueryAliasInfo *param = arg; 1561fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1562fe1c642dSBill Krier ndr_handle_t *hd; 1563fe1c642dSBill Krier samr_keydata_t *data; 1564fe1c642dSBill Krier smb_group_t grp; 15659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_domain_type_t gd_type; 1566f96bd5c8SAlan Wright smb_sid_t *sid; 1567f96bd5c8SAlan Wright smb_wka_t *wka; 1568f96bd5c8SAlan Wright char sidstr[SMB_SID_STRSZ]; 1569f96bd5c8SAlan Wright char *name; 1570f96bd5c8SAlan Wright char *desc; 1571f96bd5c8SAlan Wright uint32_t rid; 1572fe1c642dSBill Krier uint32_t status; 1573fe1c642dSBill Krier int rc; 1574fe1c642dSBill Krier 1575fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 1576fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE; 1577fe1c642dSBill Krier goto query_alias_err; 1578fe1c642dSBill Krier } 1579fe1c642dSBill Krier 1580fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data; 15819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States gd_type = (smb_domain_type_t)data->kd_type; 1582f96bd5c8SAlan Wright rid = data->kd_rid; 1583f96bd5c8SAlan Wright 1584f96bd5c8SAlan Wright switch (gd_type) { 15859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_DOMAIN_BUILTIN: 1586f96bd5c8SAlan Wright (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d", 1587f96bd5c8SAlan Wright NT_BUILTIN_DOMAIN_SIDSTR, rid); 1588f96bd5c8SAlan Wright if ((sid = smb_sid_fromstr(sidstr)) == NULL) { 1589f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS; 1590f96bd5c8SAlan Wright goto query_alias_err; 1591f96bd5c8SAlan Wright } 1592f96bd5c8SAlan Wright 1593f96bd5c8SAlan Wright wka = smb_wka_lookup_sid(sid); 1594f96bd5c8SAlan Wright smb_sid_free(sid); 1595f96bd5c8SAlan Wright 1596f96bd5c8SAlan Wright if (wka == NULL) { 1597f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS; 1598f96bd5c8SAlan Wright goto query_alias_err; 1599f96bd5c8SAlan Wright } 1600f96bd5c8SAlan Wright 1601f96bd5c8SAlan Wright name = wka->wka_name; 1602f96bd5c8SAlan Wright desc = (wka->wka_desc != NULL) ? wka->wka_desc : ""; 1603f96bd5c8SAlan Wright break; 1604f96bd5c8SAlan Wright 16059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_DOMAIN_LOCAL: 1606f96bd5c8SAlan Wright rc = smb_lgrp_getbyrid(rid, gd_type, &grp); 1607fe1c642dSBill Krier if (rc != SMB_LGRP_SUCCESS) { 1608fe1c642dSBill Krier status = NT_STATUS_NO_SUCH_ALIAS; 1609fe1c642dSBill Krier goto query_alias_err; 1610fe1c642dSBill Krier } 1611f96bd5c8SAlan Wright name = grp.sg_name; 1612f96bd5c8SAlan Wright desc = grp.sg_cmnt; 1613f96bd5c8SAlan Wright break; 1614f96bd5c8SAlan Wright 1615f96bd5c8SAlan Wright default: 1616f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS; 1617f96bd5c8SAlan Wright goto query_alias_err; 1618f96bd5c8SAlan Wright } 1619fe1c642dSBill Krier 1620fe1c642dSBill Krier switch (param->level) { 1621*eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_GENERAL: 1622fe1c642dSBill Krier param->ru.info1.level = param->level; 1623f96bd5c8SAlan Wright (void) NDR_MSTRING(mxa, name, 1624fe1c642dSBill Krier (ndr_mstring_t *)¶m->ru.info1.name); 1625f96bd5c8SAlan Wright (void) NDR_MSTRING(mxa, desc, 1626fe1c642dSBill Krier (ndr_mstring_t *)¶m->ru.info1.desc); 1627*eef90b86SGordon Ross param->ru.info1.member_count = 1; 1628fe1c642dSBill Krier break; 1629fe1c642dSBill Krier 1630*eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_NAME: 1631*eef90b86SGordon Ross param->ru.info2.level = param->level; 1632*eef90b86SGordon Ross (void) NDR_MSTRING(mxa, name, 1633*eef90b86SGordon Ross (ndr_mstring_t *)¶m->ru.info2.name); 1634*eef90b86SGordon Ross break; 1635*eef90b86SGordon Ross 1636*eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_COMMENT: 1637fe1c642dSBill Krier param->ru.info3.level = param->level; 1638f96bd5c8SAlan Wright (void) NDR_MSTRING(mxa, desc, 1639fe1c642dSBill Krier (ndr_mstring_t *)¶m->ru.info3.desc); 1640fe1c642dSBill Krier break; 1641fe1c642dSBill Krier 1642fe1c642dSBill Krier default: 16439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (gd_type == SMB_DOMAIN_LOCAL) 1644fe1c642dSBill Krier smb_lgrp_free(&grp); 1645fe1c642dSBill Krier status = NT_STATUS_INVALID_INFO_CLASS; 1646fe1c642dSBill Krier goto query_alias_err; 1647fe1c642dSBill Krier }; 1648fe1c642dSBill Krier 16499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (gd_type == SMB_DOMAIN_LOCAL) 1650fe1c642dSBill Krier smb_lgrp_free(&grp); 1651fe1c642dSBill Krier param->address = (DWORD)(uintptr_t)¶m->ru; 1652fe1c642dSBill Krier param->status = 0; 1653fe1c642dSBill Krier return (NDR_DRC_OK); 1654fe1c642dSBill Krier 1655fe1c642dSBill Krier query_alias_err: 1656fe1c642dSBill Krier param->status = NT_SC_ERROR(status); 1657fe1c642dSBill Krier return (NDR_DRC_OK); 1658fe1c642dSBill Krier } 1659fe1c642dSBill Krier 1660fe1c642dSBill Krier /* 1661fe1c642dSBill Krier * samr_s_DeleteDomainAlias 1662fe1c642dSBill Krier * 1663c5866007SKeyur Desai * Deletes a local group in the security database, which is the 1664c5866007SKeyur Desai * security accounts manager (SAM). A valid group handle is returned 1665c5866007SKeyur Desai * to the caller upon success. 1666fe1c642dSBill Krier * 1667c5866007SKeyur Desai * The caller must have administrator rights to execute this function. 1668fe1c642dSBill Krier */ 1669fe1c642dSBill Krier static int 1670fe1c642dSBill Krier samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa) 1671fe1c642dSBill Krier { 1672fe1c642dSBill Krier struct samr_DeleteDomainAlias *param = arg; 1673fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1674c5866007SKeyur Desai ndr_handle_t *hd; 1675c5866007SKeyur Desai smb_group_t grp; 1676c5866007SKeyur Desai samr_keydata_t *data; 1677c5866007SKeyur Desai smb_domain_type_t gd_type; 1678c5866007SKeyur Desai uint32_t rid; 1679c5866007SKeyur Desai uint32_t rc; 1680c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS; 1681fe1c642dSBill Krier 1682c5866007SKeyur Desai if (!ndr_is_admin(mxa)) { 1683c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1684c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 1685c5866007SKeyur Desai return (NDR_DRC_OK); 1686c5866007SKeyur Desai } 1687c5866007SKeyur Desai 1688c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 1689fe1c642dSBill Krier bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1690fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 1691fe1c642dSBill Krier return (NDR_DRC_OK); 1692fe1c642dSBill Krier } 1693fe1c642dSBill Krier 1694c5866007SKeyur Desai data = (samr_keydata_t *)hd->nh_data; 1695c5866007SKeyur Desai gd_type = (smb_domain_type_t)data->kd_type; 1696c5866007SKeyur Desai rid = data->kd_rid; 1697c5866007SKeyur Desai 1698c5866007SKeyur Desai switch (gd_type) { 1699c5866007SKeyur Desai case SMB_DOMAIN_BUILTIN: 1700fe1c642dSBill Krier bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1701c5866007SKeyur Desai status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED); 1702c5866007SKeyur Desai break; 1703fe1c642dSBill Krier 1704c5866007SKeyur Desai case SMB_DOMAIN_LOCAL: 1705c5866007SKeyur Desai rc = smb_lgrp_getbyrid(rid, gd_type, &grp); 1706c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) { 1707c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1708c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc); 1709c5866007SKeyur Desai status = NT_SC_ERROR(status); 1710c5866007SKeyur Desai break; 1711fe1c642dSBill Krier } 1712fe1c642dSBill Krier 1713c5866007SKeyur Desai rc = smb_lgrp_delete(grp.sg_name); 1714c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) { 1715c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1716c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc); 1717c5866007SKeyur Desai status = NT_SC_ERROR(status); 1718c5866007SKeyur Desai } 1719c5866007SKeyur Desai smb_lgrp_free(&grp); 1720c5866007SKeyur Desai break; 1721c5866007SKeyur Desai 1722c5866007SKeyur Desai default: 1723c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1724c5866007SKeyur Desai status = NT_SC_ERROR(NT_STATUS_NO_SUCH_ALIAS); 1725fe1c642dSBill Krier } 1726fe1c642dSBill Krier 1727c5866007SKeyur Desai param->status = status; 1728fe1c642dSBill Krier return (NDR_DRC_OK); 1729fe1c642dSBill Krier } 1730fe1c642dSBill Krier 1731fe1c642dSBill Krier /* 1732fe1c642dSBill Krier * samr_s_EnumDomainAliases 1733fe1c642dSBill Krier * 1734fe1c642dSBill Krier * This function sends back a list which contains all local groups' name. 1735fe1c642dSBill Krier */ 1736fe1c642dSBill Krier static int 1737fe1c642dSBill Krier samr_s_EnumDomainAliases(void *arg, ndr_xa_t *mxa) 1738fe1c642dSBill Krier { 1739fe1c642dSBill Krier struct samr_EnumDomainAliases *param = arg; 1740fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 1741fe1c642dSBill Krier ndr_handle_t *hd; 1742fe1c642dSBill Krier samr_keydata_t *data; 1743fe1c642dSBill Krier smb_group_t grp; 1744fe1c642dSBill Krier smb_giter_t gi; 1745fe1c642dSBill Krier int cnt, skip, i; 1746fe1c642dSBill Krier struct name_rid *info; 1747fe1c642dSBill Krier 1748fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 1749fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumDomainAliases)); 1750fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 1751fe1c642dSBill Krier return (NDR_DRC_OK); 1752fe1c642dSBill Krier } 1753fe1c642dSBill Krier 1754fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data; 1755fe1c642dSBill Krier 1756fe1c642dSBill Krier cnt = smb_sam_grp_cnt(data->kd_type); 1757fe1c642dSBill Krier if (cnt <= param->resume_handle) { 1758fe1c642dSBill Krier param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, 1759fe1c642dSBill Krier sizeof (struct aliases_info)); 1760fe1c642dSBill Krier 1761fe1c642dSBill Krier if (param->aliases == NULL) { 1762fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumDomainAliases)); 1763fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1764fe1c642dSBill Krier return (NDR_DRC_OK); 1765fe1c642dSBill Krier } 1766fe1c642dSBill Krier 1767fe1c642dSBill Krier bzero(param->aliases, sizeof (struct aliases_info)); 1768fe1c642dSBill Krier param->out_resume = 0; 1769fe1c642dSBill Krier param->entries = 0; 1770fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 1771fe1c642dSBill Krier return (NDR_DRC_OK); 1772fe1c642dSBill Krier } 1773fe1c642dSBill Krier 1774fe1c642dSBill Krier cnt -= param->resume_handle; 1775fe1c642dSBill Krier param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, 1776fe1c642dSBill Krier sizeof (struct aliases_info) + (cnt-1) * sizeof (struct name_rid)); 1777fe1c642dSBill Krier 1778fe1c642dSBill Krier if (param->aliases == NULL) { 1779fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumDomainAliases)); 1780fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1781fe1c642dSBill Krier return (NDR_DRC_OK); 1782fe1c642dSBill Krier } 1783fe1c642dSBill Krier 1784fe1c642dSBill Krier if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 1785fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumDomainAliases)); 1786fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); 1787fe1c642dSBill Krier return (NDR_DRC_OK); 1788fe1c642dSBill Krier } 1789fe1c642dSBill Krier 1790fe1c642dSBill Krier skip = i = 0; 1791fe1c642dSBill Krier info = param->aliases->info; 1792fe1c642dSBill Krier while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) { 1793fe1c642dSBill Krier if ((skip++ >= param->resume_handle) && 1794fe1c642dSBill Krier (grp.sg_domain == data->kd_type) && (i++ < cnt)) { 1795fe1c642dSBill Krier info->rid = grp.sg_rid; 1796fe1c642dSBill Krier (void) NDR_MSTRING(mxa, grp.sg_name, 1797fe1c642dSBill Krier (ndr_mstring_t *)&info->name); 1798fe1c642dSBill Krier 1799fe1c642dSBill Krier info++; 1800fe1c642dSBill Krier } 1801fe1c642dSBill Krier smb_lgrp_free(&grp); 1802fe1c642dSBill Krier } 1803fe1c642dSBill Krier smb_lgrp_iterclose(&gi); 1804fe1c642dSBill Krier 1805fe1c642dSBill Krier param->aliases->count = i; 1806fe1c642dSBill Krier param->aliases->address = i; 1807fe1c642dSBill Krier 1808fe1c642dSBill Krier param->out_resume = i; 1809fe1c642dSBill Krier param->entries = i; 1810fe1c642dSBill Krier param->status = 0; 1811fe1c642dSBill Krier return (NDR_DRC_OK); 1812fe1c642dSBill Krier } 1813fe1c642dSBill Krier 1814fe1c642dSBill Krier /* 1815cb174861Sjoyce mcintosh * samr_s_Connect4 1816fe1c642dSBill Krier */ 1817fe1c642dSBill Krier static int 1818cb174861Sjoyce mcintosh samr_s_Connect4(void *arg, ndr_xa_t *mxa) 1819fe1c642dSBill Krier { 1820cb174861Sjoyce mcintosh struct samr_Connect4 *param = arg; 1821f96bd5c8SAlan Wright ndr_hdid_t *id; 1822fe1c642dSBill Krier 1823f96bd5c8SAlan Wright id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 1824f96bd5c8SAlan Wright if (id) { 1825f96bd5c8SAlan Wright bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 1826f96bd5c8SAlan Wright param->status = 0; 1827f96bd5c8SAlan Wright } else { 1828f96bd5c8SAlan Wright bzero(¶m->handle, sizeof (samr_handle_t)); 1829f96bd5c8SAlan Wright param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1830fe1c642dSBill Krier } 1831fe1c642dSBill Krier 1832f96bd5c8SAlan Wright return (NDR_DRC_OK); 1833f96bd5c8SAlan Wright } 1834fe1c642dSBill Krier 1835fe1c642dSBill Krier /* 1836cb174861Sjoyce mcintosh * samr_s_Connect5 1837fe1c642dSBill Krier * 1838cb174861Sjoyce mcintosh * This is the connect5 form of the connect request used by Windows XP. 1839fe1c642dSBill Krier * Returns an RPC fault for now. 1840fe1c642dSBill Krier */ 1841fe1c642dSBill Krier /*ARGSUSED*/ 1842fe1c642dSBill Krier static int 1843cb174861Sjoyce mcintosh samr_s_Connect5(void *arg, ndr_xa_t *mxa) 1844fe1c642dSBill Krier { 1845cb174861Sjoyce mcintosh struct samr_Connect5 *param = arg; 1846fe1c642dSBill Krier 1847cb174861Sjoyce mcintosh bzero(param, sizeof (struct samr_Connect5)); 1848fe1c642dSBill Krier return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 1849fe1c642dSBill Krier } 1850fe1c642dSBill Krier 1851fe1c642dSBill Krier static ndr_stub_table_t samr_stub_table[] = { 1852cb174861Sjoyce mcintosh { samr_s_Connect, SAMR_OPNUM_Connect }, 1853fe1c642dSBill Krier { samr_s_CloseHandle, SAMR_OPNUM_CloseHandle }, 1854fe1c642dSBill Krier { samr_s_LookupDomain, SAMR_OPNUM_LookupDomain }, 1855fe1c642dSBill Krier { samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains }, 1856fe1c642dSBill Krier { samr_s_OpenDomain, SAMR_OPNUM_OpenDomain }, 1857fe1c642dSBill Krier { samr_s_QueryDomainInfo, SAMR_OPNUM_QueryDomainInfo }, 1858f96bd5c8SAlan Wright { samr_s_QueryInfoDomain2, SAMR_OPNUM_QueryInfoDomain2 }, 1859fe1c642dSBill Krier { samr_s_LookupNames, SAMR_OPNUM_LookupNames }, 1860fe1c642dSBill Krier { samr_s_OpenUser, SAMR_OPNUM_OpenUser }, 1861fe1c642dSBill Krier { samr_s_DeleteUser, SAMR_OPNUM_DeleteUser }, 1862fe1c642dSBill Krier { samr_s_QueryUserInfo, SAMR_OPNUM_QueryUserInfo }, 1863fe1c642dSBill Krier { samr_s_QueryUserGroups, SAMR_OPNUM_QueryUserGroups }, 1864fe1c642dSBill Krier { samr_s_OpenGroup, SAMR_OPNUM_OpenGroup }, 1865cb174861Sjoyce mcintosh { samr_s_Connect2, SAMR_OPNUM_Connect2 }, 1866fe1c642dSBill Krier { samr_s_GetUserPwInfo, SAMR_OPNUM_GetUserPwInfo }, 1867fe1c642dSBill Krier { samr_s_CreateUser, SAMR_OPNUM_CreateUser }, 18681ed6b69aSGordon Ross { samr_s_ChangePasswordUser2, SAMR_OPNUM_ChangePasswordUser2 }, 1869fe1c642dSBill Krier { samr_s_GetDomainPwInfo, SAMR_OPNUM_GetDomainPwInfo }, 1870fe1c642dSBill Krier { samr_s_SetUserInfo, SAMR_OPNUM_SetUserInfo }, 1871fe1c642dSBill Krier { samr_s_Connect4, SAMR_OPNUM_Connect4 }, 1872cb174861Sjoyce mcintosh { samr_s_Connect5, SAMR_OPNUM_Connect5 }, 1873fe1c642dSBill Krier { samr_s_QueryDispInfo, SAMR_OPNUM_QueryDispInfo }, 1874fe1c642dSBill Krier { samr_s_OpenAlias, SAMR_OPNUM_OpenAlias }, 1875fe1c642dSBill Krier { samr_s_CreateDomainAlias, SAMR_OPNUM_CreateDomainAlias }, 1876fe1c642dSBill Krier { samr_s_SetAliasInfo, SAMR_OPNUM_SetAliasInfo }, 1877fe1c642dSBill Krier { samr_s_QueryAliasInfo, SAMR_OPNUM_QueryAliasInfo }, 1878fe1c642dSBill Krier { samr_s_DeleteDomainAlias, SAMR_OPNUM_DeleteDomainAlias }, 1879fe1c642dSBill Krier { samr_s_EnumDomainAliases, SAMR_OPNUM_EnumDomainAliases }, 1880fe1c642dSBill Krier { samr_s_EnumDomainGroups, SAMR_OPNUM_EnumDomainGroups }, 1881c5866007SKeyur Desai { samr_s_AddAliasMember, SAMR_OPNUM_AddAliasMember }, 1882c5866007SKeyur Desai { samr_s_DeleteAliasMember, SAMR_OPNUM_DeleteAliasMember }, 1883c5866007SKeyur Desai { samr_s_ListAliasMembers, SAMR_OPNUM_ListAliasMembers }, 1884fe1c642dSBill Krier {0} 1885fe1c642dSBill Krier }; 1886fe1c642dSBill Krier 1887fe1c642dSBill Krier /* 1888fe1c642dSBill Krier * There is a bug in the way that midl and the marshalling code handles 1889fe1c642dSBill Krier * unions so we need to fix some of the data offsets at runtime. The 1890fe1c642dSBill Krier * following macros and the fixup functions handle the corrections. 1891fe1c642dSBill Krier */ 1892fe1c642dSBill Krier 1893fe1c642dSBill Krier DECL_FIXUP_STRUCT(samr_QueryAliasInfo_ru); 1894fe1c642dSBill Krier DECL_FIXUP_STRUCT(samr_QueryAliasInfoRes); 1895fe1c642dSBill Krier DECL_FIXUP_STRUCT(samr_QueryAliasInfo); 1896fe1c642dSBill Krier 1897fe1c642dSBill Krier DECL_FIXUP_STRUCT(QueryUserInfo_result_u); 1898fe1c642dSBill Krier DECL_FIXUP_STRUCT(QueryUserInfo_result); 1899fe1c642dSBill Krier DECL_FIXUP_STRUCT(samr_QueryUserInfo); 1900fe1c642dSBill Krier 1901fe1c642dSBill Krier void 1902fe1c642dSBill Krier fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo *val) 1903fe1c642dSBill Krier { 1904fe1c642dSBill Krier unsigned short size1 = 0; 1905fe1c642dSBill Krier unsigned short size2 = 0; 1906fe1c642dSBill Krier unsigned short size3 = 0; 1907fe1c642dSBill Krier 1908fe1c642dSBill Krier switch (val->level) { 1909*eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_GENERAL: 1910*eef90b86SGordon Ross size1 = sizeof (struct samr_QueryAliasInfoGeneral); 1911*eef90b86SGordon Ross break; 1912*eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_NAME: 1913*eef90b86SGordon Ross size1 = sizeof (struct samr_QueryAliasInfoName); 1914*eef90b86SGordon Ross break; 1915*eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_COMMENT: 1916*eef90b86SGordon Ross size1 = sizeof (struct samr_QueryAliasInfoComment); 1917*eef90b86SGordon Ross break; 1918fe1c642dSBill Krier 1919fe1c642dSBill Krier default: 1920fe1c642dSBill Krier return; 1921fe1c642dSBill Krier }; 1922fe1c642dSBill Krier 1923fe1c642dSBill Krier size2 = size1 + (2 * sizeof (DWORD)); 1924fe1c642dSBill Krier size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 1925fe1c642dSBill Krier 1926fe1c642dSBill Krier FIXUP_PDU_SIZE(samr_QueryAliasInfo_ru, size1); 1927fe1c642dSBill Krier FIXUP_PDU_SIZE(samr_QueryAliasInfoRes, size2); 1928fe1c642dSBill Krier FIXUP_PDU_SIZE(samr_QueryAliasInfo, size3); 1929fe1c642dSBill Krier } 1930fe1c642dSBill Krier 1931fe1c642dSBill Krier void 1932fe1c642dSBill Krier fixup_samr_QueryUserInfo(struct samr_QueryUserInfo *val) 1933fe1c642dSBill Krier { 1934fe1c642dSBill Krier unsigned short size1 = 0; 1935fe1c642dSBill Krier unsigned short size2 = 0; 1936fe1c642dSBill Krier unsigned short size3 = 0; 1937fe1c642dSBill Krier 1938fe1c642dSBill Krier switch (val->switch_index) { 1939fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 1); 1940fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 6); 1941fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 7); 1942fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 8); 1943fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 9); 1944fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 16); 1945fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 21); 1946fe1c642dSBill Krier 1947fe1c642dSBill Krier default: 1948fe1c642dSBill Krier return; 1949fe1c642dSBill Krier }; 1950fe1c642dSBill Krier 1951fe1c642dSBill Krier size2 = size1 + (2 * sizeof (DWORD)); 1952fe1c642dSBill Krier size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 1953fe1c642dSBill Krier 1954fe1c642dSBill Krier FIXUP_PDU_SIZE(QueryUserInfo_result_u, size1); 1955fe1c642dSBill Krier FIXUP_PDU_SIZE(QueryUserInfo_result, size2); 1956fe1c642dSBill Krier FIXUP_PDU_SIZE(samr_QueryUserInfo, size3); 1957fe1c642dSBill Krier } 1958fe1c642dSBill Krier 1959fe1c642dSBill Krier /* 1960fe1c642dSBill Krier * As long as there is only one entry in the union, there is no need 1961fe1c642dSBill Krier * to patch anything. 1962fe1c642dSBill Krier */ 1963fe1c642dSBill Krier /*ARGSUSED*/ 1964fe1c642dSBill Krier void 1965fe1c642dSBill Krier fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo *val) 1966fe1c642dSBill Krier { 1967fe1c642dSBill Krier } 1968