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