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 /* 23148c5f43SAlan Wright * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 2468b2bbf2SGordon Ross * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 25fe1c642dSBill Krier */ 26fe1c642dSBill Krier 27fe1c642dSBill Krier /* 28fe1c642dSBill Krier * Local Security Authority RPC (LSAR) server-side interface. 29fe1c642dSBill Krier */ 30fe1c642dSBill Krier 31fe1c642dSBill Krier #include <unistd.h> 32fe1c642dSBill Krier #include <strings.h> 33fe1c642dSBill Krier #include <pwd.h> 34fe1c642dSBill Krier #include <grp.h> 35fe1c642dSBill Krier 36fe1c642dSBill Krier #include <smbsrv/libsmb.h> 37fe1c642dSBill Krier #include <smbsrv/libmlrpc.h> 38fe1c642dSBill Krier #include <smbsrv/libmlsvc.h> 39fe1c642dSBill Krier #include <smbsrv/ndl/lsarpc.ndl> 40fe1c642dSBill Krier #include <lsalib.h> 41fe1c642dSBill Krier #include <smbsrv/smbinfo.h> 42fe1c642dSBill Krier #include <smbsrv/nmpipes.h> 43fe1c642dSBill Krier #include <smbsrv/ntlocale.h> 44fe1c642dSBill Krier 45fe1c642dSBill Krier struct local_group_table { 46fe1c642dSBill Krier WORD sid_name_use; 47fe1c642dSBill Krier WORD domain_ix; 48fe1c642dSBill Krier char *sid; 49fe1c642dSBill Krier char *name; 50fe1c642dSBill Krier }; 51fe1c642dSBill Krier 52fe1c642dSBill Krier static int lsarpc_key_domain; 53fe1c642dSBill Krier static int lsarpc_key_account; 54fe1c642dSBill Krier 55fe1c642dSBill Krier static int lsarpc_call_stub(ndr_xa_t *mxa); 56fe1c642dSBill Krier 57fe1c642dSBill Krier static int lsarpc_s_CloseHandle(void *, ndr_xa_t *); 58fe1c642dSBill Krier static int lsarpc_s_QuerySecurityObject(void *, ndr_xa_t *); 59fe1c642dSBill Krier static int lsarpc_s_EnumAccounts(void *, ndr_xa_t *); 60fe1c642dSBill Krier static int lsarpc_s_EnumTrustedDomain(void *, ndr_xa_t *); 61fe1c642dSBill Krier static int lsarpc_s_EnumTrustedDomainsEx(void *, ndr_xa_t *); 62fe1c642dSBill Krier static int lsarpc_s_OpenAccount(void *, ndr_xa_t *); 63fe1c642dSBill Krier static int lsarpc_s_EnumPrivsAccount(void *, ndr_xa_t *); 64fe1c642dSBill Krier static int lsarpc_s_LookupPrivValue(void *, ndr_xa_t *); 65fe1c642dSBill Krier static int lsarpc_s_LookupPrivName(void *, ndr_xa_t *); 66fe1c642dSBill Krier static int lsarpc_s_LookupPrivDisplayName(void *, ndr_xa_t *); 67fe1c642dSBill Krier static int lsarpc_s_CreateSecret(void *, ndr_xa_t *); 68fe1c642dSBill Krier static int lsarpc_s_OpenSecret(void *, ndr_xa_t *); 69fe1c642dSBill Krier static int lsarpc_s_QueryInfoPolicy(void *, ndr_xa_t *); 70fe1c642dSBill Krier static int lsarpc_s_OpenDomainHandle(void *, ndr_xa_t *); 71fe1c642dSBill Krier static int lsarpc_s_OpenDomainHandle(void *, ndr_xa_t *); 72fe1c642dSBill Krier static int lsarpc_s_LookupSids(void *, ndr_xa_t *); 73fe1c642dSBill Krier static int lsarpc_s_LookupNames(void *, ndr_xa_t *); 74fe1c642dSBill Krier static int lsarpc_s_GetConnectedUser(void *, ndr_xa_t *); 75fe1c642dSBill Krier static int lsarpc_s_LookupSids2(void *, ndr_xa_t *); 76fe1c642dSBill Krier static int lsarpc_s_LookupSids3(void *, ndr_xa_t *); 77fe1c642dSBill Krier static int lsarpc_s_LookupNames2(void *, ndr_xa_t *); 78fe1c642dSBill Krier static int lsarpc_s_LookupNames3(void *, ndr_xa_t *); 79fe1c642dSBill Krier static int lsarpc_s_LookupNames4(void *, ndr_xa_t *); 80fe1c642dSBill Krier 81fe1c642dSBill Krier static DWORD lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *, 82fe1c642dSBill Krier ndr_xa_t *); 83fe1c642dSBill Krier static DWORD lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *, 84fe1c642dSBill Krier ndr_xa_t *); 85fe1c642dSBill Krier static int lsarpc_s_UpdateDomainTable(ndr_xa_t *, 86fe1c642dSBill Krier smb_account_t *, struct mslsa_domain_table *, DWORD *); 87fe1c642dSBill Krier 88fe1c642dSBill Krier static ndr_stub_table_t lsarpc_stub_table[] = { 89fe1c642dSBill Krier { lsarpc_s_CloseHandle, LSARPC_OPNUM_CloseHandle }, 90fe1c642dSBill Krier { lsarpc_s_QuerySecurityObject, LSARPC_OPNUM_QuerySecurityObject }, 91fe1c642dSBill Krier { lsarpc_s_EnumAccounts, LSARPC_OPNUM_EnumerateAccounts }, 92fe1c642dSBill Krier { lsarpc_s_EnumTrustedDomain, LSARPC_OPNUM_EnumTrustedDomain }, 93fe1c642dSBill Krier { lsarpc_s_EnumTrustedDomainsEx, LSARPC_OPNUM_EnumTrustedDomainsEx }, 94fe1c642dSBill Krier { lsarpc_s_OpenAccount, LSARPC_OPNUM_OpenAccount }, 95fe1c642dSBill Krier { lsarpc_s_EnumPrivsAccount, LSARPC_OPNUM_EnumPrivsAccount }, 96fe1c642dSBill Krier { lsarpc_s_LookupPrivValue, LSARPC_OPNUM_LookupPrivValue }, 97fe1c642dSBill Krier { lsarpc_s_LookupPrivName, LSARPC_OPNUM_LookupPrivName }, 98fe1c642dSBill Krier { lsarpc_s_LookupPrivDisplayName, LSARPC_OPNUM_LookupPrivDisplayName }, 99fe1c642dSBill Krier { lsarpc_s_CreateSecret, LSARPC_OPNUM_CreateSecret }, 100fe1c642dSBill Krier { lsarpc_s_OpenSecret, LSARPC_OPNUM_OpenSecret }, 101fe1c642dSBill Krier { lsarpc_s_QueryInfoPolicy, LSARPC_OPNUM_QueryInfoPolicy }, 102fe1c642dSBill Krier { lsarpc_s_OpenDomainHandle, LSARPC_OPNUM_OpenPolicy }, 103fe1c642dSBill Krier { lsarpc_s_OpenDomainHandle, LSARPC_OPNUM_OpenPolicy2 }, 104fe1c642dSBill Krier { lsarpc_s_LookupSids, LSARPC_OPNUM_LookupSids }, 105fe1c642dSBill Krier { lsarpc_s_LookupNames, LSARPC_OPNUM_LookupNames }, 106fe1c642dSBill Krier { lsarpc_s_GetConnectedUser, LSARPC_OPNUM_GetConnectedUser }, 107fe1c642dSBill Krier { lsarpc_s_LookupSids2, LSARPC_OPNUM_LookupSids2 }, 108fe1c642dSBill Krier { lsarpc_s_LookupSids3, LSARPC_OPNUM_LookupSids3 }, 109fe1c642dSBill Krier { lsarpc_s_LookupNames2, LSARPC_OPNUM_LookupNames2 }, 110fe1c642dSBill Krier { lsarpc_s_LookupNames3, LSARPC_OPNUM_LookupNames3 }, 111fe1c642dSBill Krier { lsarpc_s_LookupNames4, LSARPC_OPNUM_LookupNames4 }, 112fe1c642dSBill Krier {0} 113fe1c642dSBill Krier }; 114fe1c642dSBill Krier 115fe1c642dSBill Krier static ndr_service_t lsarpc_service = { 116fe1c642dSBill Krier "LSARPC", /* name */ 117fe1c642dSBill Krier "Local Security Authority", /* desc */ 118fe1c642dSBill Krier "\\lsarpc", /* endpoint */ 119fe1c642dSBill Krier PIPE_LSASS, /* sec_addr_port */ 120fe1c642dSBill Krier "12345778-1234-abcd-ef00-0123456789ab", 0, /* abstract */ 121fe1c642dSBill Krier NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 122fe1c642dSBill Krier 0, /* no bind_instance_size */ 123fe1c642dSBill Krier NULL, /* no bind_req() */ 124fe1c642dSBill Krier NULL, /* no unbind_and_close() */ 125fe1c642dSBill Krier lsarpc_call_stub, /* call_stub() */ 126fe1c642dSBill Krier &TYPEINFO(lsarpc_interface), /* interface ti */ 127fe1c642dSBill Krier lsarpc_stub_table /* stub_table */ 128fe1c642dSBill Krier }; 129fe1c642dSBill Krier 130fe1c642dSBill Krier /* 131fe1c642dSBill Krier * lsarpc_initialize 132fe1c642dSBill Krier * 133fe1c642dSBill Krier * This function registers the LSA RPC interface with the RPC runtime 134fe1c642dSBill Krier * library. It must be called in order to use either the client side 135fe1c642dSBill Krier * or the server side functions. 136fe1c642dSBill Krier */ 137fe1c642dSBill Krier void 138fe1c642dSBill Krier lsarpc_initialize(void) 139fe1c642dSBill Krier { 140fe1c642dSBill Krier (void) ndr_svc_register(&lsarpc_service); 141fe1c642dSBill Krier } 142fe1c642dSBill Krier 143fe1c642dSBill Krier /* 144fe1c642dSBill Krier * Custom call_stub to set the stream string policy. 145fe1c642dSBill Krier */ 146fe1c642dSBill Krier static int 147fe1c642dSBill Krier lsarpc_call_stub(ndr_xa_t *mxa) 148fe1c642dSBill Krier { 149fe1c642dSBill Krier NDS_SETF(&mxa->send_nds, NDS_F_NOTERM); 150fe1c642dSBill Krier NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM); 151fe1c642dSBill Krier 152fe1c642dSBill Krier return (ndr_generic_call_stub(mxa)); 153fe1c642dSBill Krier } 154fe1c642dSBill Krier 155fe1c642dSBill Krier /* 156fe1c642dSBill Krier * lsarpc_s_OpenDomainHandle opnum=0x06 157fe1c642dSBill Krier * 158fe1c642dSBill Krier * This is a request to open the LSA (OpenPolicy and OpenPolicy2). 159fe1c642dSBill Krier * The client is looking for an LSA domain handle. 160fe1c642dSBill Krier */ 161fe1c642dSBill Krier static int 162fe1c642dSBill Krier lsarpc_s_OpenDomainHandle(void *arg, ndr_xa_t *mxa) 163fe1c642dSBill Krier { 164fe1c642dSBill Krier struct mslsa_OpenPolicy2 *param = arg; 165fe1c642dSBill Krier ndr_hdid_t *id; 166fe1c642dSBill Krier 167fe1c642dSBill Krier if ((id = ndr_hdalloc(mxa, &lsarpc_key_domain)) != NULL) { 168fe1c642dSBill Krier bcopy(id, ¶m->domain_handle, sizeof (mslsa_handle_t)); 169fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 170fe1c642dSBill Krier } else { 171fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (mslsa_handle_t)); 172fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 173fe1c642dSBill Krier } 174fe1c642dSBill Krier 175fe1c642dSBill Krier return (NDR_DRC_OK); 176fe1c642dSBill Krier } 177fe1c642dSBill Krier 178fe1c642dSBill Krier /* 179fe1c642dSBill Krier * lsarpc_s_CloseHandle opnum=0x00 180fe1c642dSBill Krier * 181fe1c642dSBill Krier * This is a request to close the LSA interface specified by the handle. 182fe1c642dSBill Krier * We don't track handles (yet), so just zero out the handle and return 183fe1c642dSBill Krier * NDR_DRC_OK. Setting the handle to zero appears to be standard 184fe1c642dSBill Krier * behaviour and someone may rely on it, i.e. we do on the client side. 185fe1c642dSBill Krier */ 186fe1c642dSBill Krier static int 187fe1c642dSBill Krier lsarpc_s_CloseHandle(void *arg, ndr_xa_t *mxa) 188fe1c642dSBill Krier { 189fe1c642dSBill Krier struct mslsa_CloseHandle *param = arg; 190fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 191fe1c642dSBill Krier 192fe1c642dSBill Krier ndr_hdfree(mxa, id); 193fe1c642dSBill Krier 194fe1c642dSBill Krier bzero(¶m->result_handle, sizeof (param->result_handle)); 195fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 196fe1c642dSBill Krier return (NDR_DRC_OK); 197fe1c642dSBill Krier } 198fe1c642dSBill Krier 199fe1c642dSBill Krier /* 200fe1c642dSBill Krier * lsarpc_s_QuerySecurityObject 201fe1c642dSBill Krier */ 202fe1c642dSBill Krier /*ARGSUSED*/ 203fe1c642dSBill Krier static int 204fe1c642dSBill Krier lsarpc_s_QuerySecurityObject(void *arg, ndr_xa_t *mxa) 205fe1c642dSBill Krier { 206fe1c642dSBill Krier struct mslsa_QuerySecurityObject *param = arg; 207fe1c642dSBill Krier 208fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_QuerySecurityObject)); 209fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 210fe1c642dSBill Krier 211fe1c642dSBill Krier return (NDR_DRC_OK); 212fe1c642dSBill Krier } 213fe1c642dSBill Krier 214fe1c642dSBill Krier /* 215fe1c642dSBill Krier * lsarpc_s_EnumAccounts 216fe1c642dSBill Krier * 217fe1c642dSBill Krier * Enumerate the list of local accounts SIDs. The client should supply 218fe1c642dSBill Krier * a valid OpenPolicy2 handle. The enum_context is used to support 219fe1c642dSBill Krier * multiple enumeration calls to obtain the complete list of SIDs. 220fe1c642dSBill Krier * It should be set to 0 on the first call and passed unchanged on 221fe1c642dSBill Krier * subsequent calls until there are no more accounts - the server will 222148c5f43SAlan Wright * return STATUS_NO_MORE_ENTRIES. 223fe1c642dSBill Krier * 224fe1c642dSBill Krier * For now just set the status to access-denied. Note that we still have 225fe1c642dSBill Krier * to provide a valid address for enum_buf because it's a reference and 226fe1c642dSBill Krier * the marshalling rules require that references must not be null. 227fe1c642dSBill Krier * The enum_context is used to support multiple 228fe1c642dSBill Krier */ 229fe1c642dSBill Krier static int 230fe1c642dSBill Krier lsarpc_s_EnumAccounts(void *arg, ndr_xa_t *mxa) 231fe1c642dSBill Krier { 232fe1c642dSBill Krier struct mslsa_EnumerateAccounts *param = arg; 233fe1c642dSBill Krier struct mslsa_EnumAccountBuf *enum_buf; 234fe1c642dSBill Krier 235fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_EnumerateAccounts)); 236fe1c642dSBill Krier 237fe1c642dSBill Krier enum_buf = NDR_NEW(mxa, struct mslsa_EnumAccountBuf); 238fe1c642dSBill Krier if (enum_buf == NULL) { 239fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 240fe1c642dSBill Krier return (NDR_DRC_OK); 241fe1c642dSBill Krier } 242fe1c642dSBill Krier 243fe1c642dSBill Krier bzero(enum_buf, sizeof (struct mslsa_EnumAccountBuf)); 244fe1c642dSBill Krier param->enum_buf = enum_buf; 245fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 246fe1c642dSBill Krier return (NDR_DRC_OK); 247fe1c642dSBill Krier } 248fe1c642dSBill Krier 249fe1c642dSBill Krier 250fe1c642dSBill Krier /* 251fe1c642dSBill Krier * lsarpc_s_EnumTrustedDomain 252fe1c642dSBill Krier * 253fe1c642dSBill Krier * This is the server side function for handling requests to enumerate 254fe1c642dSBill Krier * the list of trusted domains: currently held in the NT domain database. 255fe1c642dSBill Krier * This call requires an OpenPolicy2 handle. The enum_context is used to 256fe1c642dSBill Krier * support multiple enumeration calls to obtain the complete list. 257fe1c642dSBill Krier * It should be set to 0 on the first call and passed unchanged on 258fe1c642dSBill Krier * subsequent calls until there are no more accounts - the server will 259148c5f43SAlan Wright * return STATUS_NO_MORE_ENTRIES. 260fe1c642dSBill Krier * 261fe1c642dSBill Krier * For now just set the status to access-denied. Note that we still have 262fe1c642dSBill Krier * to provide a valid address for enum_buf because it's a reference and 263fe1c642dSBill Krier * the marshalling rules require that references must not be null. 264fe1c642dSBill Krier */ 265fe1c642dSBill Krier static int 266fe1c642dSBill Krier lsarpc_s_EnumTrustedDomain(void *arg, ndr_xa_t *mxa) 267fe1c642dSBill Krier { 268fe1c642dSBill Krier struct mslsa_EnumTrustedDomain *param = arg; 269fe1c642dSBill Krier struct mslsa_EnumTrustedDomainBuf *enum_buf; 270fe1c642dSBill Krier 271fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_EnumTrustedDomain)); 272fe1c642dSBill Krier 273fe1c642dSBill Krier enum_buf = NDR_NEW(mxa, struct mslsa_EnumTrustedDomainBuf); 274fe1c642dSBill Krier if (enum_buf == NULL) { 275fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 276fe1c642dSBill Krier return (NDR_DRC_OK); 277fe1c642dSBill Krier } 278fe1c642dSBill Krier 279fe1c642dSBill Krier bzero(enum_buf, sizeof (struct mslsa_EnumTrustedDomainBuf)); 280fe1c642dSBill Krier param->enum_buf = enum_buf; 281fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 282fe1c642dSBill Krier return (NDR_DRC_OK); 283fe1c642dSBill Krier } 284fe1c642dSBill Krier 285fe1c642dSBill Krier /* 286fe1c642dSBill Krier * lsarpc_s_EnumTrustedDomainsEx 287fe1c642dSBill Krier * 288fe1c642dSBill Krier * This is the server side function for handling requests to enumerate 289fe1c642dSBill Krier * the list of trusted domains: currently held in the NT domain database. 290fe1c642dSBill Krier * This call requires an OpenPolicy2 handle. The enum_context is used to 291fe1c642dSBill Krier * support multiple enumeration calls to obtain the complete list. 292fe1c642dSBill Krier * It should be set to 0 on the first call and passed unchanged on 293fe1c642dSBill Krier * subsequent calls until there are no more accounts - the server will 294148c5f43SAlan Wright * return STATUS_NO_MORE_ENTRIES. 295fe1c642dSBill Krier * 296fe1c642dSBill Krier * For now just set the status to access-denied. Note that we still have 297fe1c642dSBill Krier * to provide a valid address for enum_buf because it's a reference and 298fe1c642dSBill Krier * the marshalling rules require that references must not be null. 299fe1c642dSBill Krier */ 300fe1c642dSBill Krier static int 301fe1c642dSBill Krier lsarpc_s_EnumTrustedDomainsEx(void *arg, ndr_xa_t *mxa) 302fe1c642dSBill Krier { 303fe1c642dSBill Krier struct mslsa_EnumTrustedDomainEx *param = arg; 304fe1c642dSBill Krier struct mslsa_EnumTrustedDomainBufEx *enum_buf; 305fe1c642dSBill Krier 306fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_EnumTrustedDomainEx)); 307fe1c642dSBill Krier 308fe1c642dSBill Krier enum_buf = NDR_NEW(mxa, struct mslsa_EnumTrustedDomainBufEx); 309fe1c642dSBill Krier if (enum_buf == NULL) { 310fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 311fe1c642dSBill Krier return (NDR_DRC_OK); 312fe1c642dSBill Krier } 313fe1c642dSBill Krier 314fe1c642dSBill Krier bzero(enum_buf, sizeof (struct mslsa_EnumTrustedDomainBufEx)); 315fe1c642dSBill Krier param->enum_buf = enum_buf; 316fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 317fe1c642dSBill Krier return (NDR_DRC_OK); 318fe1c642dSBill Krier } 319fe1c642dSBill Krier 320fe1c642dSBill Krier /* 321fe1c642dSBill Krier * lsarpc_s_OpenAccount 322fe1c642dSBill Krier * 323fe1c642dSBill Krier * This is a request to open an account handle. 324fe1c642dSBill Krier */ 325fe1c642dSBill Krier static int 326fe1c642dSBill Krier lsarpc_s_OpenAccount(void *arg, ndr_xa_t *mxa) 327fe1c642dSBill Krier { 328fe1c642dSBill Krier struct mslsa_OpenAccount *param = arg; 329fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 330fe1c642dSBill Krier ndr_handle_t *hd; 331fe1c642dSBill Krier 332fe1c642dSBill Krier hd = ndr_hdlookup(mxa, id); 333fe1c642dSBill Krier if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) { 334fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_OpenAccount)); 335fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 336fe1c642dSBill Krier return (NDR_DRC_OK); 337fe1c642dSBill Krier } 338fe1c642dSBill Krier 339fe1c642dSBill Krier if ((id = ndr_hdalloc(mxa, &lsarpc_key_account)) != NULL) { 340fe1c642dSBill Krier bcopy(id, ¶m->account_handle, sizeof (mslsa_handle_t)); 341fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 342fe1c642dSBill Krier } else { 343fe1c642dSBill Krier bzero(¶m->account_handle, sizeof (mslsa_handle_t)); 344fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 345fe1c642dSBill Krier } 346fe1c642dSBill Krier 347fe1c642dSBill Krier return (NDR_DRC_OK); 348fe1c642dSBill Krier } 349fe1c642dSBill Krier 350fe1c642dSBill Krier 351fe1c642dSBill Krier /* 352fe1c642dSBill Krier * lsarpc_s_EnumPrivsAccount 353fe1c642dSBill Krier * 354fe1c642dSBill Krier * This is the server side function for handling requests for account 355fe1c642dSBill Krier * privileges. For now just set the status to not-supported status and 356fe1c642dSBill Krier * return NDR_DRC_OK. Note that we still have to provide a valid 357fe1c642dSBill Krier * address for enum_buf because it's a reference and the marshalling 358fe1c642dSBill Krier * rules require that references must not be null. 359fe1c642dSBill Krier */ 360fe1c642dSBill Krier /*ARGSUSED*/ 361fe1c642dSBill Krier static int 362fe1c642dSBill Krier lsarpc_s_EnumPrivsAccount(void *arg, ndr_xa_t *mxa) 363fe1c642dSBill Krier { 364fe1c642dSBill Krier struct mslsa_EnumPrivsAccount *param = arg; 365fe1c642dSBill Krier 366fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_EnumPrivsAccount)); 367fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED); 368fe1c642dSBill Krier return (NDR_DRC_OK); 369fe1c642dSBill Krier } 370fe1c642dSBill Krier 371fe1c642dSBill Krier /* 372fe1c642dSBill Krier * lsarpc_s_LookupPrivValue 373fe1c642dSBill Krier * 374fe1c642dSBill Krier * Server side function used to map a privilege name to a locally unique 375fe1c642dSBill Krier * identifier (LUID). 376fe1c642dSBill Krier */ 377fe1c642dSBill Krier /*ARGSUSED*/ 378fe1c642dSBill Krier static int 379fe1c642dSBill Krier lsarpc_s_LookupPrivValue(void *arg, ndr_xa_t *mxa) 380fe1c642dSBill Krier { 381fe1c642dSBill Krier struct mslsa_LookupPrivValue *param = arg; 382fe1c642dSBill Krier smb_privinfo_t *pi; 383fe1c642dSBill Krier 384fe1c642dSBill Krier if ((pi = smb_priv_getbyname((char *)param->name.str)) == NULL) { 385fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_LookupPrivValue)); 386fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE); 387fe1c642dSBill Krier return (NDR_DRC_OK); 388fe1c642dSBill Krier } 389fe1c642dSBill Krier 390fe1c642dSBill Krier param->luid.low_part = pi->id; 391fe1c642dSBill Krier param->luid.high_part = 0; 392fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 393fe1c642dSBill Krier return (NDR_DRC_OK); 394fe1c642dSBill Krier } 395fe1c642dSBill Krier 396fe1c642dSBill Krier /* 397fe1c642dSBill Krier * lsarpc_s_LookupPrivName 398fe1c642dSBill Krier * 399fe1c642dSBill Krier * Server side function used to map a locally unique identifier (LUID) 400fe1c642dSBill Krier * to the appropriate privilege name string. 401fe1c642dSBill Krier */ 402fe1c642dSBill Krier static int 403fe1c642dSBill Krier lsarpc_s_LookupPrivName(void *arg, ndr_xa_t *mxa) 404fe1c642dSBill Krier { 405fe1c642dSBill Krier struct mslsa_LookupPrivName *param = arg; 406fe1c642dSBill Krier smb_privinfo_t *pi; 407fe1c642dSBill Krier int rc; 408fe1c642dSBill Krier 409fe1c642dSBill Krier if ((pi = smb_priv_getbyvalue(param->luid.low_part)) == NULL) { 410fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_LookupPrivName)); 411fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE); 412fe1c642dSBill Krier return (NDR_DRC_OK); 413fe1c642dSBill Krier } 414fe1c642dSBill Krier 415fe1c642dSBill Krier param->name = NDR_NEW(mxa, mslsa_string_t); 416fe1c642dSBill Krier if (param->name == NULL) { 417fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_LookupPrivName)); 418fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 419fe1c642dSBill Krier return (NDR_DRC_OK); 420fe1c642dSBill Krier } 421fe1c642dSBill Krier 422fe1c642dSBill Krier rc = NDR_MSTRING(mxa, pi->name, (ndr_mstring_t *)param->name); 423fe1c642dSBill Krier if (rc == -1) { 424fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_LookupPrivName)); 425fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 426fe1c642dSBill Krier return (NDR_DRC_OK); 427fe1c642dSBill Krier } 428fe1c642dSBill Krier 429fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 430fe1c642dSBill Krier return (NDR_DRC_OK); 431fe1c642dSBill Krier } 432fe1c642dSBill Krier 433fe1c642dSBill Krier /* 434fe1c642dSBill Krier * lsarpc_s_LookupPrivDisplayName 435fe1c642dSBill Krier * 436fe1c642dSBill Krier * This is the server side function for handling requests for account 437fe1c642dSBill Krier * privileges. For now just set the status to not-supported status and 438fe1c642dSBill Krier * return NDR_DRC_OK. 439fe1c642dSBill Krier */ 440fe1c642dSBill Krier static int 441fe1c642dSBill Krier lsarpc_s_LookupPrivDisplayName(void *arg, ndr_xa_t *mxa) 442fe1c642dSBill Krier { 443fe1c642dSBill Krier struct mslsa_LookupPrivDisplayName *param = arg; 444fe1c642dSBill Krier smb_privinfo_t *pi; 445fe1c642dSBill Krier int rc; 446fe1c642dSBill Krier 447fe1c642dSBill Krier if ((pi = smb_priv_getbyname((char *)param->name.str)) == NULL) { 448fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_LookupPrivDisplayName)); 449fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE); 450fe1c642dSBill Krier return (NDR_DRC_OK); 451fe1c642dSBill Krier } 452fe1c642dSBill Krier 453fe1c642dSBill Krier param->display_name = NDR_NEW(mxa, mslsa_string_t); 454fe1c642dSBill Krier if (param->display_name == NULL) { 455fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_LookupPrivDisplayName)); 456fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 457fe1c642dSBill Krier return (NDR_DRC_OK); 458fe1c642dSBill Krier } 459fe1c642dSBill Krier 460fe1c642dSBill Krier rc = NDR_MSTRING(mxa, pi->display_name, 461fe1c642dSBill Krier (ndr_mstring_t *)param->display_name); 462fe1c642dSBill Krier if (rc == -1) { 463fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_LookupPrivDisplayName)); 464fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 465fe1c642dSBill Krier return (NDR_DRC_OK); 466fe1c642dSBill Krier } 467fe1c642dSBill Krier 468fe1c642dSBill Krier param->language_ret = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); 469fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 470fe1c642dSBill Krier return (NDR_DRC_OK); 471fe1c642dSBill Krier } 472fe1c642dSBill Krier 473fe1c642dSBill Krier static int 474fe1c642dSBill Krier lsarpc_s_CreateSecret(void *arg, ndr_xa_t *mxa) 475fe1c642dSBill Krier { 476fe1c642dSBill Krier struct mslsa_CreateSecret *param = arg; 477fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 478fe1c642dSBill Krier ndr_handle_t *hd; 479fe1c642dSBill Krier 480fe1c642dSBill Krier hd = ndr_hdlookup(mxa, id); 481fe1c642dSBill Krier if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) { 482fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_OpenAccount)); 483fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 484fe1c642dSBill Krier return (NDR_DRC_OK); 485fe1c642dSBill Krier } 486fe1c642dSBill Krier 487fe1c642dSBill Krier bzero(¶m->secret_handle, sizeof (mslsa_handle_t)); 488fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 489fe1c642dSBill Krier return (NDR_DRC_OK); 490fe1c642dSBill Krier } 491fe1c642dSBill Krier 492fe1c642dSBill Krier static int 493fe1c642dSBill Krier lsarpc_s_OpenSecret(void *arg, ndr_xa_t *mxa) 494fe1c642dSBill Krier { 495fe1c642dSBill Krier struct mslsa_OpenSecret *param = arg; 496fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 497fe1c642dSBill Krier ndr_handle_t *hd; 498fe1c642dSBill Krier 499fe1c642dSBill Krier hd = ndr_hdlookup(mxa, id); 500fe1c642dSBill Krier if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) { 501fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_OpenAccount)); 502fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 503fe1c642dSBill Krier return (NDR_DRC_OK); 504fe1c642dSBill Krier } 505fe1c642dSBill Krier 506fe1c642dSBill Krier bzero(¶m->secret_handle, sizeof (mslsa_handle_t)); 507fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 508fe1c642dSBill Krier return (NDR_DRC_OK); 509fe1c642dSBill Krier } 510fe1c642dSBill Krier 511fe1c642dSBill Krier /* 512fe1c642dSBill Krier * lsarpc_s_GetConnectedUser 513fe1c642dSBill Krier * 514fe1c642dSBill Krier * Return the account name and NetBIOS domain name for the user making 515fe1c642dSBill Krier * the request. The hostname field should be ignored by the server. 516*510e1dfaSGordon Ross * 517*510e1dfaSGordon Ross * Note: MacOS uses this, whether we're a domain member or not. 518fe1c642dSBill Krier */ 519fe1c642dSBill Krier static int 520fe1c642dSBill Krier lsarpc_s_GetConnectedUser(void *arg, ndr_xa_t *mxa) 521fe1c642dSBill Krier { 522fe1c642dSBill Krier struct mslsa_GetConnectedUser *param = arg; 52368b2bbf2SGordon Ross smb_netuserinfo_t *user = mxa->pipe->np_user; 524fe1c642dSBill Krier DWORD status = NT_STATUS_SUCCESS; 525fe1c642dSBill Krier int rc1; 526fe1c642dSBill Krier int rc2; 527fe1c642dSBill Krier 528fe1c642dSBill Krier param->owner = NDR_NEW(mxa, struct mslsa_string_desc); 529fe1c642dSBill Krier param->domain = NDR_NEW(mxa, struct mslsa_DomainName); 530fe1c642dSBill Krier if (param->owner == NULL || param->domain == NULL) { 531fe1c642dSBill Krier status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 532fe1c642dSBill Krier param->status = status; 533fe1c642dSBill Krier return (NDR_DRC_OK); 534fe1c642dSBill Krier } 535fe1c642dSBill Krier 536fe1c642dSBill Krier param->domain->name = NDR_NEW(mxa, struct mslsa_string_desc); 537fe1c642dSBill Krier if (param->domain->name == NULL) { 538fe1c642dSBill Krier status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 539fe1c642dSBill Krier param->status = status; 540fe1c642dSBill Krier return (NDR_DRC_OK); 541fe1c642dSBill Krier } 542fe1c642dSBill Krier 543fe1c642dSBill Krier rc1 = NDR_MSTRING(mxa, user->ui_account, 544fe1c642dSBill Krier (ndr_mstring_t *)param->owner); 545fe1c642dSBill Krier rc2 = NDR_MSTRING(mxa, user->ui_domain, 546fe1c642dSBill Krier (ndr_mstring_t *)param->domain->name); 547fe1c642dSBill Krier 548fe1c642dSBill Krier if (rc1 == -1 || rc2 == -1) 549fe1c642dSBill Krier status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 550fe1c642dSBill Krier 551fe1c642dSBill Krier param->status = status; 552fe1c642dSBill Krier return (NDR_DRC_OK); 553fe1c642dSBill Krier } 554fe1c642dSBill Krier 555fe1c642dSBill Krier 556fe1c642dSBill Krier /* 557fe1c642dSBill Krier * lsarpc_s_QueryInfoPolicy 558fe1c642dSBill Krier * 559fe1c642dSBill Krier * This is the server side function for handling LSA information policy 560fe1c642dSBill Krier * queries. Currently, we only support primary domain and account 561fe1c642dSBill Krier * domain queries. This is just a front end to switch on the request 562fe1c642dSBill Krier * and hand it off to the appropriate function to actually deal with 563fe1c642dSBill Krier * obtaining and building the response. 564fe1c642dSBill Krier */ 565fe1c642dSBill Krier static int 566fe1c642dSBill Krier lsarpc_s_QueryInfoPolicy(void *arg, ndr_xa_t *mxa) 567fe1c642dSBill Krier { 568fe1c642dSBill Krier struct mslsa_QueryInfoPolicy *param = arg; 569fe1c642dSBill Krier union mslsa_PolicyInfoResUnion *ru = ¶m->ru; 570fe1c642dSBill Krier int security_mode; 571fe1c642dSBill Krier DWORD status; 572fe1c642dSBill Krier 573fe1c642dSBill Krier param->switch_value = param->info_class; 574fe1c642dSBill Krier 575fe1c642dSBill Krier switch (param->info_class) { 576fe1c642dSBill Krier case MSLSA_POLICY_AUDIT_EVENTS_INFO: 577fe1c642dSBill Krier ru->audit_events.enabled = 0; 578fe1c642dSBill Krier ru->audit_events.count = 1; 579fe1c642dSBill Krier ru->audit_events.settings 580fe1c642dSBill Krier = NDR_MALLOC(mxa, sizeof (DWORD)); 581fe1c642dSBill Krier bzero(ru->audit_events.settings, sizeof (DWORD)); 582fe1c642dSBill Krier status = NT_STATUS_SUCCESS; 583fe1c642dSBill Krier break; 584fe1c642dSBill Krier 585fe1c642dSBill Krier case MSLSA_POLICY_PRIMARY_DOMAIN_INFO: 586fe1c642dSBill Krier status = lsarpc_s_PrimaryDomainInfo(&ru->pd_info, mxa); 587fe1c642dSBill Krier break; 588fe1c642dSBill Krier 589fe1c642dSBill Krier case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO: 590fe1c642dSBill Krier status = lsarpc_s_AccountDomainInfo(&ru->ad_info, mxa); 591fe1c642dSBill Krier break; 592fe1c642dSBill Krier 593fe1c642dSBill Krier case MSLSA_POLICY_SERVER_ROLE_INFO: 594fe1c642dSBill Krier security_mode = smb_config_get_secmode(); 595fe1c642dSBill Krier 596fe1c642dSBill Krier if (security_mode == SMB_SECMODE_DOMAIN) 597fe1c642dSBill Krier ru->server_role.role = LSA_ROLE_MEMBER_SERVER; 598fe1c642dSBill Krier else 599fe1c642dSBill Krier ru->server_role.role = LSA_ROLE_STANDALONE_SERVER; 600fe1c642dSBill Krier 601fe1c642dSBill Krier ru->server_role.pad = 0; 602fe1c642dSBill Krier status = NT_STATUS_SUCCESS; 603fe1c642dSBill Krier break; 604fe1c642dSBill Krier 605fe1c642dSBill Krier default: 606fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_QueryInfoPolicy)); 607fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_INFO_CLASS); 608fe1c642dSBill Krier return (NDR_DRC_OK); 609fe1c642dSBill Krier } 610fe1c642dSBill Krier 611fe1c642dSBill Krier if (status != NT_STATUS_SUCCESS) 612fe1c642dSBill Krier param->status = NT_SC_ERROR(status); 613fe1c642dSBill Krier else 614fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 615fe1c642dSBill Krier param->address = (DWORD)(uintptr_t)ru; 616fe1c642dSBill Krier 617fe1c642dSBill Krier return (NDR_DRC_OK); 618fe1c642dSBill Krier } 619fe1c642dSBill Krier 620fe1c642dSBill Krier 621fe1c642dSBill Krier /* 622fe1c642dSBill Krier * lsarpc_s_PrimaryDomainInfo 623fe1c642dSBill Krier * 624fe1c642dSBill Krier * Service primary domain policy queries. In domain mode, return the 625fe1c642dSBill Krier * primary domain name and SID. In workgroup mode, return the local 626fe1c642dSBill Krier * hostname and local domain SID. 627fe1c642dSBill Krier * 628fe1c642dSBill Krier * Note: info is zeroed on entry to ensure the SID and name do not 629fe1c642dSBill Krier * contain spurious values if an error is returned. 630fe1c642dSBill Krier */ 631fe1c642dSBill Krier static DWORD 632fe1c642dSBill Krier lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *info, 633fe1c642dSBill Krier ndr_xa_t *mxa) 634fe1c642dSBill Krier { 635fe1c642dSBill Krier smb_domain_t di; 636fe1c642dSBill Krier boolean_t found; 637fe1c642dSBill Krier int rc; 638fe1c642dSBill Krier 639fe1c642dSBill Krier bzero(info, sizeof (struct mslsa_PrimaryDomainInfo)); 640fe1c642dSBill Krier 641fe1c642dSBill Krier if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) 642fe1c642dSBill Krier found = smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di); 643fe1c642dSBill Krier else 644fe1c642dSBill Krier found = smb_domain_lookup_type(SMB_DOMAIN_PRIMARY, &di); 645fe1c642dSBill Krier 646fe1c642dSBill Krier if (!found) 647fe1c642dSBill Krier return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 648fe1c642dSBill Krier 649fe1c642dSBill Krier rc = NDR_MSTRING(mxa, di.di_nbname, (ndr_mstring_t *)&info->name); 650fe1c642dSBill Krier info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, di.di_binsid); 651fe1c642dSBill Krier 652fe1c642dSBill Krier if ((rc == -1) || (info->sid == NULL)) 653fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY); 654fe1c642dSBill Krier 655fe1c642dSBill Krier return (NT_STATUS_SUCCESS); 656fe1c642dSBill Krier } 657fe1c642dSBill Krier 658fe1c642dSBill Krier 659fe1c642dSBill Krier /* 660fe1c642dSBill Krier * lsarpc_s_AccountDomainInfo 661fe1c642dSBill Krier * 662fe1c642dSBill Krier * Service account domain policy queries. We return our local domain 663fe1c642dSBill Krier * information so that the client knows who to query for information 664fe1c642dSBill Krier * on local names and SIDs. The domain name is the local hostname. 665fe1c642dSBill Krier * 666fe1c642dSBill Krier * Note: info is zeroed on entry to ensure the SID and name do not 667fe1c642dSBill Krier * contain spurious values if an error is returned. 668fe1c642dSBill Krier */ 669fe1c642dSBill Krier static DWORD 670fe1c642dSBill Krier lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *info, 671fe1c642dSBill Krier ndr_xa_t *mxa) 672fe1c642dSBill Krier { 673fe1c642dSBill Krier smb_domain_t di; 674fe1c642dSBill Krier int rc; 675fe1c642dSBill Krier 676fe1c642dSBill Krier bzero(info, sizeof (struct mslsa_AccountDomainInfo)); 677fe1c642dSBill Krier 678fe1c642dSBill Krier if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) 679fe1c642dSBill Krier return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 680fe1c642dSBill Krier 681fe1c642dSBill Krier rc = NDR_MSTRING(mxa, di.di_nbname, (ndr_mstring_t *)&info->name); 682fe1c642dSBill Krier info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, di.di_binsid); 683fe1c642dSBill Krier 684fe1c642dSBill Krier if ((rc == -1) || (info->sid == NULL)) 685fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY); 686fe1c642dSBill Krier 687fe1c642dSBill Krier return (NT_STATUS_SUCCESS); 688fe1c642dSBill Krier } 689fe1c642dSBill Krier 690fe1c642dSBill Krier /* 691fe1c642dSBill Krier * lsarpc_s_LookupNames 692fe1c642dSBill Krier * 693fe1c642dSBill Krier * This is the service side function for handling name lookup requests. 694fe1c642dSBill Krier * Currently, we only support lookups of a single name. This is also a 695fe1c642dSBill Krier * pass through interface so all we do is act as a proxy between the 696fe1c642dSBill Krier * client and the DC. 697fe1c642dSBill Krier */ 698fe1c642dSBill Krier static int 699fe1c642dSBill Krier lsarpc_s_LookupNames(void *arg, ndr_xa_t *mxa) 700fe1c642dSBill Krier { 701fe1c642dSBill Krier struct mslsa_LookupNames *param = arg; 702fe1c642dSBill Krier struct mslsa_rid_entry *rids; 703fe1c642dSBill Krier struct mslsa_domain_table *domain_table; 704fe1c642dSBill Krier struct mslsa_domain_entry *domain_entry; 705fe1c642dSBill Krier smb_account_t account; 706fe1c642dSBill Krier uint32_t status; 707fe1c642dSBill Krier char *accname; 708fe1c642dSBill Krier int rc = 0; 709fe1c642dSBill Krier 710fe1c642dSBill Krier if (param->name_table->n_entry != 1) 711fe1c642dSBill Krier return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED); 712fe1c642dSBill Krier 713fe1c642dSBill Krier rids = NDR_NEW(mxa, struct mslsa_rid_entry); 714fe1c642dSBill Krier domain_table = NDR_NEW(mxa, struct mslsa_domain_table); 715fe1c642dSBill Krier domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry); 716fe1c642dSBill Krier 717fe1c642dSBill Krier if (rids == NULL || domain_table == NULL || domain_entry == NULL) { 718fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_LookupNames)); 719fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 720fe1c642dSBill Krier return (NDR_DRC_OK); 721fe1c642dSBill Krier } 722fe1c642dSBill Krier 723fe1c642dSBill Krier accname = (char *)param->name_table->names->str; 724fe1c642dSBill Krier status = lsa_lookup_name(accname, SidTypeUnknown, &account); 725fe1c642dSBill Krier if (status != NT_STATUS_SUCCESS) { 726fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_LookupNames)); 727fe1c642dSBill Krier param->status = NT_SC_ERROR(status); 728fe1c642dSBill Krier return (NDR_DRC_OK); 729fe1c642dSBill Krier } 730fe1c642dSBill Krier 731fe1c642dSBill Krier /* 732fe1c642dSBill Krier * Set up the rid table. 733fe1c642dSBill Krier */ 734fe1c642dSBill Krier rids[0].sid_name_use = account.a_type; 735fe1c642dSBill Krier rids[0].rid = account.a_rid; 736fe1c642dSBill Krier rids[0].domain_index = 0; 737fe1c642dSBill Krier param->translated_sids.n_entry = 1; 738fe1c642dSBill Krier param->translated_sids.rids = rids; 739fe1c642dSBill Krier 740fe1c642dSBill Krier /* 741fe1c642dSBill Krier * Set up the domain table. 742fe1c642dSBill Krier */ 743fe1c642dSBill Krier domain_table->entries = domain_entry; 744fe1c642dSBill Krier domain_table->n_entry = 1; 745fe1c642dSBill Krier domain_table->max_n_entry = MLSVC_DOMAIN_MAX; 746fe1c642dSBill Krier 747fe1c642dSBill Krier rc = NDR_MSTRING(mxa, account.a_domain, 748fe1c642dSBill Krier (ndr_mstring_t *)&domain_entry->domain_name); 749fe1c642dSBill Krier domain_entry->domain_sid = 750fe1c642dSBill Krier (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid); 751fe1c642dSBill Krier 752fe1c642dSBill Krier if (rc == -1 || domain_entry->domain_sid == NULL) { 753fe1c642dSBill Krier smb_account_free(&account); 754fe1c642dSBill Krier bzero(param, sizeof (struct mslsa_LookupNames)); 755fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 756fe1c642dSBill Krier return (NDR_DRC_OK); 757fe1c642dSBill Krier } 758fe1c642dSBill Krier 759fe1c642dSBill Krier param->domain_table = domain_table; 760fe1c642dSBill Krier param->mapped_count = 1; 761fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 762fe1c642dSBill Krier 763fe1c642dSBill Krier smb_account_free(&account); 764fe1c642dSBill Krier return (NDR_DRC_OK); 765fe1c642dSBill Krier } 766fe1c642dSBill Krier 767fe1c642dSBill Krier /* 768fe1c642dSBill Krier * lsarpc_s_LookupSids 769fe1c642dSBill Krier * 770fe1c642dSBill Krier * This is the service side function for handling sid lookup requests. 771fe1c642dSBill Krier * We have to set up both the name table and the domain table in the 772fe1c642dSBill Krier * response. For each SID, we check for UNIX domain (local lookup) or 773fe1c642dSBill Krier * NT domain (DC lookup) and call the appropriate lookup function. This 774fe1c642dSBill Krier * should resolve the SID to a name. Then we need to update the domain 775fe1c642dSBill Krier * table and make the name entry point at the appropriate domain table 776fe1c642dSBill Krier * entry. 777fe1c642dSBill Krier * 778fe1c642dSBill Krier * 779fe1c642dSBill Krier * This RPC should behave as if LookupOptions is LSA_LOOKUP_OPT_ALL and 780fe1c642dSBill Krier * ClientRevision is LSA_CLIENT_REVISION_NT. 781fe1c642dSBill Krier * 782fe1c642dSBill Krier * On success return 0. Otherwise return an RPC specific error code. 783fe1c642dSBill Krier */ 784fd9ee8b5Sjoyce mcintosh 785fe1c642dSBill Krier static int 786fe1c642dSBill Krier lsarpc_s_LookupSids(void *arg, ndr_xa_t *mxa) 787fe1c642dSBill Krier { 788fe1c642dSBill Krier struct mslsa_LookupSids *param = arg; 789fe1c642dSBill Krier struct mslsa_domain_table *domain_table; 790fe1c642dSBill Krier struct mslsa_domain_entry *domain_entry; 791fe1c642dSBill Krier struct mslsa_name_entry *names; 792fe1c642dSBill Krier struct mslsa_name_entry *name; 793fe1c642dSBill Krier smb_account_t account; 794fe1c642dSBill Krier smb_sid_t *sid; 795fe1c642dSBill Krier DWORD n_entry; 796fd9ee8b5Sjoyce mcintosh DWORD n_mapped; 797fd9ee8b5Sjoyce mcintosh char sidstr[SMB_SID_STRSZ]; 798fe1c642dSBill Krier int result; 799fe1c642dSBill Krier int i; 800fe1c642dSBill Krier 801fd9ee8b5Sjoyce mcintosh bzero(&account, sizeof (smb_account_t)); 802fd9ee8b5Sjoyce mcintosh n_mapped = 0; 803fe1c642dSBill Krier n_entry = param->lup_sid_table.n_entry; 804fd9ee8b5Sjoyce mcintosh 805fe1c642dSBill Krier names = NDR_NEWN(mxa, struct mslsa_name_entry, n_entry); 806fe1c642dSBill Krier domain_table = NDR_NEW(mxa, struct mslsa_domain_table); 807fe1c642dSBill Krier domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry, 808fe1c642dSBill Krier MLSVC_DOMAIN_MAX); 809fe1c642dSBill Krier 810fd9ee8b5Sjoyce mcintosh if (names == NULL || domain_table == NULL || domain_entry == NULL) 811fd9ee8b5Sjoyce mcintosh goto lookup_sid_failed; 812fe1c642dSBill Krier 813fe1c642dSBill Krier domain_table->entries = domain_entry; 814fe1c642dSBill Krier domain_table->n_entry = 0; 815fe1c642dSBill Krier domain_table->max_n_entry = MLSVC_DOMAIN_MAX; 816fe1c642dSBill Krier 817fe1c642dSBill Krier name = names; 818fe1c642dSBill Krier for (i = 0; i < n_entry; ++i, name++) { 819fd9ee8b5Sjoyce mcintosh bzero(name, sizeof (struct mslsa_name_entry)); 820fe1c642dSBill Krier sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid; 821fe1c642dSBill Krier 822fe1c642dSBill Krier result = lsa_lookup_sid(sid, &account); 823fd9ee8b5Sjoyce mcintosh if ((result != NT_STATUS_SUCCESS) || 824fd9ee8b5Sjoyce mcintosh (account.a_name == NULL) || (*account.a_name == '\0')) { 825fd9ee8b5Sjoyce mcintosh account.a_type = SidTypeUnknown; 826fd9ee8b5Sjoyce mcintosh smb_sid_tostr(sid, sidstr); 827fd9ee8b5Sjoyce mcintosh 828fd9ee8b5Sjoyce mcintosh if (NDR_MSTRING(mxa, sidstr, 829fd9ee8b5Sjoyce mcintosh (ndr_mstring_t *)&name->name) == -1) 830fe1c642dSBill Krier goto lookup_sid_failed; 831fe1c642dSBill Krier 832fd9ee8b5Sjoyce mcintosh } else { 833fe1c642dSBill Krier if (NDR_MSTRING(mxa, account.a_name, 834fd9ee8b5Sjoyce mcintosh (ndr_mstring_t *)&name->name) == -1) 835fe1c642dSBill Krier goto lookup_sid_failed; 836fd9ee8b5Sjoyce mcintosh 837fd9ee8b5Sjoyce mcintosh ++n_mapped; 838fe1c642dSBill Krier } 839fd9ee8b5Sjoyce mcintosh 840fe1c642dSBill Krier name->sid_name_use = account.a_type; 841fe1c642dSBill Krier 842fe1c642dSBill Krier result = lsarpc_s_UpdateDomainTable(mxa, &account, 843fe1c642dSBill Krier domain_table, &name->domain_ix); 844fd9ee8b5Sjoyce mcintosh if (result == -1) 845fe1c642dSBill Krier goto lookup_sid_failed; 846fe1c642dSBill Krier 847fe1c642dSBill Krier smb_account_free(&account); 848fe1c642dSBill Krier } 849fe1c642dSBill Krier 850fe1c642dSBill Krier param->domain_table = domain_table; 851fe1c642dSBill Krier param->name_table.n_entry = n_entry; 852fe1c642dSBill Krier param->name_table.entries = names; 853fd9ee8b5Sjoyce mcintosh param->mapped_count = n_mapped; 854fd9ee8b5Sjoyce mcintosh 855fd9ee8b5Sjoyce mcintosh if (n_mapped == n_entry) 856fd9ee8b5Sjoyce mcintosh param->status = NT_STATUS_SUCCESS; 857fd9ee8b5Sjoyce mcintosh else if (n_mapped == 0) 858fd9ee8b5Sjoyce mcintosh param->status = NT_STATUS_NONE_MAPPED; 859fd9ee8b5Sjoyce mcintosh else 860fd9ee8b5Sjoyce mcintosh param->status = NT_STATUS_SOME_NOT_MAPPED; 861fe1c642dSBill Krier 862fe1c642dSBill Krier return (NDR_DRC_OK); 863fe1c642dSBill Krier 864fe1c642dSBill Krier lookup_sid_failed: 865fe1c642dSBill Krier smb_account_free(&account); 866fd9ee8b5Sjoyce mcintosh bzero(param, sizeof (struct mslsa_LookupSids)); 867fd9ee8b5Sjoyce mcintosh return (NDR_DRC_FAULT_OUT_OF_MEMORY); 868fe1c642dSBill Krier } 869fe1c642dSBill Krier 870fe1c642dSBill Krier /* 871fe1c642dSBill Krier * lsarpc_s_UpdateDomainTable 872fe1c642dSBill Krier * 873fe1c642dSBill Krier * This routine is responsible for maintaining the domain table which 874fe1c642dSBill Krier * will be returned from a SID lookup. Whenever a name is added to the 875fe1c642dSBill Krier * name table, this function should be called with the corresponding 876fe1c642dSBill Krier * domain name. If the domain information is not already in the table, 877fe1c642dSBill Krier * it is added. On success return 0; Otherwise -1 is returned. 878fe1c642dSBill Krier */ 879fe1c642dSBill Krier static int 880fe1c642dSBill Krier lsarpc_s_UpdateDomainTable(ndr_xa_t *mxa, 881fe1c642dSBill Krier smb_account_t *account, struct mslsa_domain_table *domain_table, 882fe1c642dSBill Krier DWORD *domain_idx) 883fe1c642dSBill Krier { 884fe1c642dSBill Krier struct mslsa_domain_entry *dentry; 885fe1c642dSBill Krier DWORD n_entry; 886fe1c642dSBill Krier DWORD i; 887fe1c642dSBill Krier int rc; 888fe1c642dSBill Krier 889fe1c642dSBill Krier if (account->a_type == SidTypeUnknown || 890fe1c642dSBill Krier account->a_type == SidTypeInvalid) { 891fe1c642dSBill Krier /* 892fe1c642dSBill Krier * These types don't need to reference an entry in the 893fe1c642dSBill Krier * domain table. So return -1. 894fe1c642dSBill Krier */ 895fe1c642dSBill Krier *domain_idx = (DWORD)-1; 896fe1c642dSBill Krier return (0); 897fe1c642dSBill Krier } 898fe1c642dSBill Krier 899fe1c642dSBill Krier if ((dentry = domain_table->entries) == NULL) 900fe1c642dSBill Krier return (-1); 901fe1c642dSBill Krier 902fe1c642dSBill Krier if ((n_entry = domain_table->n_entry) >= MLSVC_DOMAIN_MAX) 903fe1c642dSBill Krier return (-1); 904fe1c642dSBill Krier 905fe1c642dSBill Krier for (i = 0; i < n_entry; ++i) { 906fe1c642dSBill Krier if (smb_sid_cmp((smb_sid_t *)dentry[i].domain_sid, 907fe1c642dSBill Krier account->a_domsid)) { 908fe1c642dSBill Krier *domain_idx = i; 909fe1c642dSBill Krier return (0); 910fe1c642dSBill Krier } 911fe1c642dSBill Krier } 912fe1c642dSBill Krier 913fe1c642dSBill Krier if (i == MLSVC_DOMAIN_MAX) 914fe1c642dSBill Krier return (-1); 915fe1c642dSBill Krier 916fe1c642dSBill Krier rc = NDR_MSTRING(mxa, account->a_domain, 917fe1c642dSBill Krier (ndr_mstring_t *)&dentry[i].domain_name); 918fe1c642dSBill Krier dentry[i].domain_sid = 919fe1c642dSBill Krier (struct mslsa_sid *)NDR_SIDDUP(mxa, account->a_domsid); 920fe1c642dSBill Krier 921fe1c642dSBill Krier if (rc == -1 || dentry[i].domain_sid == NULL) 922fe1c642dSBill Krier return (-1); 923fe1c642dSBill Krier 924fe1c642dSBill Krier ++domain_table->n_entry; 925fe1c642dSBill Krier *domain_idx = i; 926fe1c642dSBill Krier return (0); 927fe1c642dSBill Krier } 928fe1c642dSBill Krier 929fe1c642dSBill Krier /* 930fe1c642dSBill Krier * lsarpc_s_LookupSids2 931fe1c642dSBill Krier * 932fe1c642dSBill Krier * Other than the use of lsar_lookup_sids2 and lsar_name_entry2, this 933fe1c642dSBill Krier * is identical to lsarpc_s_LookupSids. 934fe1c642dSBill Krier * 935fe1c642dSBill Krier * Ignore lookup_level, it is reserved and should be zero. 936fe1c642dSBill Krier */ 937fe1c642dSBill Krier static int 938fe1c642dSBill Krier lsarpc_s_LookupSids2(void *arg, ndr_xa_t *mxa) 939fe1c642dSBill Krier { 940fe1c642dSBill Krier struct lsar_lookup_sids2 *param = arg; 941fe1c642dSBill Krier struct lsar_name_entry2 *names; 942fe1c642dSBill Krier struct lsar_name_entry2 *name; 943fe1c642dSBill Krier struct mslsa_domain_table *domain_table; 944fe1c642dSBill Krier struct mslsa_domain_entry *domain_entry; 945fe1c642dSBill Krier smb_account_t account; 946fe1c642dSBill Krier smb_sid_t *sid; 947fe1c642dSBill Krier DWORD n_entry; 948fd9ee8b5Sjoyce mcintosh DWORD n_mapped; 949fd9ee8b5Sjoyce mcintosh char sidstr[SMB_SID_STRSZ]; 950fe1c642dSBill Krier int result; 951fe1c642dSBill Krier int i; 952fe1c642dSBill Krier 953fd9ee8b5Sjoyce mcintosh bzero(&account, sizeof (smb_account_t)); 954fd9ee8b5Sjoyce mcintosh n_mapped = 0; 955fe1c642dSBill Krier n_entry = param->lup_sid_table.n_entry; 956fd9ee8b5Sjoyce mcintosh 957fe1c642dSBill Krier names = NDR_NEWN(mxa, struct lsar_name_entry2, n_entry); 958fe1c642dSBill Krier domain_table = NDR_NEW(mxa, struct mslsa_domain_table); 959fe1c642dSBill Krier domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry, 960fe1c642dSBill Krier MLSVC_DOMAIN_MAX); 961fe1c642dSBill Krier 962fd9ee8b5Sjoyce mcintosh if (names == NULL || domain_table == NULL || domain_entry == NULL) 963fd9ee8b5Sjoyce mcintosh goto lookup_sid_failed; 964fe1c642dSBill Krier 965fe1c642dSBill Krier domain_table->entries = domain_entry; 966fe1c642dSBill Krier domain_table->n_entry = 0; 967fe1c642dSBill Krier domain_table->max_n_entry = MLSVC_DOMAIN_MAX; 968fe1c642dSBill Krier 969fe1c642dSBill Krier name = names; 970fe1c642dSBill Krier for (i = 0; i < n_entry; ++i, name++) { 971fe1c642dSBill Krier bzero(name, sizeof (struct lsar_name_entry2)); 972fe1c642dSBill Krier sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid; 973fe1c642dSBill Krier 974fe1c642dSBill Krier result = lsa_lookup_sid(sid, &account); 975fd9ee8b5Sjoyce mcintosh if ((result != NT_STATUS_SUCCESS) || 976fd9ee8b5Sjoyce mcintosh (account.a_name == NULL) || (*account.a_name == '\0')) { 977fd9ee8b5Sjoyce mcintosh account.a_type = SidTypeUnknown; 978fd9ee8b5Sjoyce mcintosh smb_sid_tostr(sid, sidstr); 979fd9ee8b5Sjoyce mcintosh 980fd9ee8b5Sjoyce mcintosh if (NDR_MSTRING(mxa, sidstr, 981fd9ee8b5Sjoyce mcintosh (ndr_mstring_t *)&name->name) == -1) 982fe1c642dSBill Krier goto lookup_sid_failed; 983fe1c642dSBill Krier 984fd9ee8b5Sjoyce mcintosh } else { 985fe1c642dSBill Krier if (NDR_MSTRING(mxa, account.a_name, 986fd9ee8b5Sjoyce mcintosh (ndr_mstring_t *)&name->name) == -1) 987fe1c642dSBill Krier goto lookup_sid_failed; 988fd9ee8b5Sjoyce mcintosh 989fd9ee8b5Sjoyce mcintosh ++n_mapped; 990fe1c642dSBill Krier } 991fd9ee8b5Sjoyce mcintosh 992fe1c642dSBill Krier name->sid_name_use = account.a_type; 993fe1c642dSBill Krier 994fe1c642dSBill Krier result = lsarpc_s_UpdateDomainTable(mxa, &account, 995fe1c642dSBill Krier domain_table, &name->domain_ix); 996fd9ee8b5Sjoyce mcintosh if (result == -1) 997fe1c642dSBill Krier goto lookup_sid_failed; 998fe1c642dSBill Krier 999fe1c642dSBill Krier smb_account_free(&account); 1000fe1c642dSBill Krier } 1001fe1c642dSBill Krier 1002fe1c642dSBill Krier param->domain_table = domain_table; 1003fe1c642dSBill Krier param->name_table.n_entry = n_entry; 1004fe1c642dSBill Krier param->name_table.entries = names; 1005fd9ee8b5Sjoyce mcintosh param->mapped_count = n_mapped; 1006fd9ee8b5Sjoyce mcintosh 1007fd9ee8b5Sjoyce mcintosh if (n_mapped == n_entry) 1008fd9ee8b5Sjoyce mcintosh param->status = NT_STATUS_SUCCESS; 1009fd9ee8b5Sjoyce mcintosh else if (n_mapped == 0) 1010fd9ee8b5Sjoyce mcintosh param->status = NT_STATUS_NONE_MAPPED; 1011fd9ee8b5Sjoyce mcintosh else 1012fd9ee8b5Sjoyce mcintosh param->status = NT_STATUS_SOME_NOT_MAPPED; 1013fe1c642dSBill Krier 1014fe1c642dSBill Krier return (NDR_DRC_OK); 1015fe1c642dSBill Krier 1016fe1c642dSBill Krier lookup_sid_failed: 1017fe1c642dSBill Krier smb_account_free(&account); 1018fd9ee8b5Sjoyce mcintosh bzero(param, sizeof (struct lsar_lookup_sids2)); 1019fd9ee8b5Sjoyce mcintosh return (NDR_DRC_FAULT_OUT_OF_MEMORY); 1020fe1c642dSBill Krier } 1021fe1c642dSBill Krier 1022fe1c642dSBill Krier /* 1023fe1c642dSBill Krier * LookupSids3 is only valid on domain controllers. 1024fe1c642dSBill Krier * Other servers must return NT_STATUS_INVALID_SERVER_STATE. 1025fe1c642dSBill Krier */ 1026fe1c642dSBill Krier /*ARGSUSED*/ 1027fe1c642dSBill Krier static int 1028fe1c642dSBill Krier lsarpc_s_LookupSids3(void *arg, ndr_xa_t *mxa) 1029fe1c642dSBill Krier { 1030fe1c642dSBill Krier struct lsar_lookup_sids3 *param = arg; 1031fe1c642dSBill Krier 1032fe1c642dSBill Krier bzero(param, sizeof (struct lsar_lookup_sids3)); 1033fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_SERVER_STATE); 1034fe1c642dSBill Krier return (NDR_DRC_OK); 1035fe1c642dSBill Krier } 1036fe1c642dSBill Krier 1037fe1c642dSBill Krier /* 1038fe1c642dSBill Krier * lsarpc_s_LookupNames2 1039fe1c642dSBill Krier * 1040fe1c642dSBill Krier * Other than the use of lsar_LookupNames2 and lsar_rid_entry2, this 1041fe1c642dSBill Krier * is identical to lsarpc_s_LookupNames. 1042fe1c642dSBill Krier * 1043fe1c642dSBill Krier * If LookupOptions contains LSA_LOOKUP_OPT_LOCAL and LookupLevel is not 1044fe1c642dSBill Krier * LSA_LOOKUP_WKSTA, return STATUS_INVALID_PARAMETER. 1045fe1c642dSBill Krier */ 1046fe1c642dSBill Krier static int 1047fe1c642dSBill Krier lsarpc_s_LookupNames2(void *arg, ndr_xa_t *mxa) 1048fe1c642dSBill Krier { 1049fe1c642dSBill Krier struct lsar_LookupNames2 *param = arg; 1050fe1c642dSBill Krier struct lsar_rid_entry2 *rids; 1051fe1c642dSBill Krier struct mslsa_domain_table *domain_table; 1052fe1c642dSBill Krier struct mslsa_domain_entry *domain_entry; 1053fe1c642dSBill Krier smb_account_t account; 1054fe1c642dSBill Krier uint32_t status; 1055fe1c642dSBill Krier char *accname; 1056fe1c642dSBill Krier int rc = 0; 1057fe1c642dSBill Krier 1058fe1c642dSBill Krier if (param->name_table->n_entry != 1) 1059fe1c642dSBill Krier return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED); 1060fe1c642dSBill Krier 1061fe1c642dSBill Krier if ((param->lookup_options & LSA_LOOKUP_OPT_LOCAL) && 1062fe1c642dSBill Krier param->lookup_level != LSA_LOOKUP_WKSTA) { 1063fe1c642dSBill Krier bzero(param, sizeof (struct lsar_LookupNames2)); 1064fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 1065fe1c642dSBill Krier return (NDR_DRC_OK); 1066fe1c642dSBill Krier } 1067fe1c642dSBill Krier 1068fe1c642dSBill Krier rids = NDR_NEW(mxa, struct lsar_rid_entry2); 1069fe1c642dSBill Krier domain_table = NDR_NEW(mxa, struct mslsa_domain_table); 1070fe1c642dSBill Krier domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry); 1071fe1c642dSBill Krier 1072fe1c642dSBill Krier if (rids == NULL || domain_table == NULL || domain_entry == NULL) { 1073fe1c642dSBill Krier bzero(param, sizeof (struct lsar_LookupNames2)); 1074fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1075fe1c642dSBill Krier return (NDR_DRC_OK); 1076fe1c642dSBill Krier } 1077fe1c642dSBill Krier 1078fe1c642dSBill Krier accname = (char *)param->name_table->names->str; 1079fe1c642dSBill Krier status = lsa_lookup_name(accname, SidTypeUnknown, &account); 1080fe1c642dSBill Krier if (status != NT_STATUS_SUCCESS) { 1081fe1c642dSBill Krier bzero(param, sizeof (struct lsar_LookupNames2)); 1082fe1c642dSBill Krier param->status = NT_SC_ERROR(status); 1083fe1c642dSBill Krier return (NDR_DRC_OK); 1084fe1c642dSBill Krier } 1085fe1c642dSBill Krier 1086fe1c642dSBill Krier /* 1087fe1c642dSBill Krier * Set up the rid table. 1088fe1c642dSBill Krier */ 1089fe1c642dSBill Krier bzero(rids, sizeof (struct lsar_rid_entry2)); 1090fe1c642dSBill Krier rids[0].sid_name_use = account.a_type; 1091fe1c642dSBill Krier rids[0].rid = account.a_rid; 1092fe1c642dSBill Krier rids[0].domain_index = 0; 1093fe1c642dSBill Krier param->translated_sids.n_entry = 1; 1094fe1c642dSBill Krier param->translated_sids.rids = rids; 1095fe1c642dSBill Krier 1096fe1c642dSBill Krier /* 1097fe1c642dSBill Krier * Set up the domain table. 1098fe1c642dSBill Krier */ 1099fe1c642dSBill Krier domain_table->entries = domain_entry; 1100fe1c642dSBill Krier domain_table->n_entry = 1; 1101fe1c642dSBill Krier domain_table->max_n_entry = MLSVC_DOMAIN_MAX; 1102fe1c642dSBill Krier 1103fe1c642dSBill Krier rc = NDR_MSTRING(mxa, account.a_domain, 1104fe1c642dSBill Krier (ndr_mstring_t *)&domain_entry->domain_name); 1105fe1c642dSBill Krier 1106fe1c642dSBill Krier domain_entry->domain_sid = 1107fe1c642dSBill Krier (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid); 1108fe1c642dSBill Krier 1109fe1c642dSBill Krier if (rc == -1 || domain_entry->domain_sid == NULL) { 1110fe1c642dSBill Krier smb_account_free(&account); 1111fe1c642dSBill Krier bzero(param, sizeof (struct lsar_LookupNames2)); 1112fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1113fe1c642dSBill Krier return (NDR_DRC_OK); 1114fe1c642dSBill Krier } 1115fe1c642dSBill Krier 1116fe1c642dSBill Krier param->domain_table = domain_table; 1117fe1c642dSBill Krier param->mapped_count = 1; 1118fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 1119fe1c642dSBill Krier 1120fe1c642dSBill Krier smb_account_free(&account); 1121fe1c642dSBill Krier return (NDR_DRC_OK); 1122fe1c642dSBill Krier } 1123fe1c642dSBill Krier 1124fe1c642dSBill Krier /* 1125fe1c642dSBill Krier * Other than the use of lsar_LookupNames2 and lsar_rid_entry2, this 1126fe1c642dSBill Krier * is identical to lsarpc_s_LookupNames. 1127fe1c642dSBill Krier * 1128fe1c642dSBill Krier * If LookupOptions contains LSA_LOOKUP_OPT_LOCAL and LookupLevel is not 1129fe1c642dSBill Krier * LSA_LOOKUP_WKSTA, return STATUS_INVALID_PARAMETER. 1130fe1c642dSBill Krier */ 1131fe1c642dSBill Krier static int 1132fe1c642dSBill Krier lsarpc_s_LookupNames3(void *arg, ndr_xa_t *mxa) 1133fe1c642dSBill Krier { 1134fe1c642dSBill Krier struct lsar_LookupNames3 *param = arg; 1135fe1c642dSBill Krier struct lsar_translated_sid_ex2 *sids; 1136fe1c642dSBill Krier struct mslsa_domain_table *domain_table; 1137fe1c642dSBill Krier struct mslsa_domain_entry *domain_entry; 1138fe1c642dSBill Krier smb_account_t account; 1139fe1c642dSBill Krier uint32_t status; 1140fe1c642dSBill Krier char *accname; 1141fe1c642dSBill Krier int rc = 0; 1142fe1c642dSBill Krier 1143fe1c642dSBill Krier if (param->name_table->n_entry != 1) 1144fe1c642dSBill Krier return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED); 1145fe1c642dSBill Krier 1146fe1c642dSBill Krier if ((param->lookup_options & LSA_LOOKUP_OPT_LOCAL) && 1147fe1c642dSBill Krier param->lookup_level != LSA_LOOKUP_WKSTA) { 1148fe1c642dSBill Krier bzero(param, sizeof (struct lsar_LookupNames3)); 1149fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 1150fe1c642dSBill Krier return (NDR_DRC_OK); 1151fe1c642dSBill Krier } 1152fe1c642dSBill Krier 1153fe1c642dSBill Krier sids = NDR_NEW(mxa, struct lsar_translated_sid_ex2); 1154fe1c642dSBill Krier domain_table = NDR_NEW(mxa, struct mslsa_domain_table); 1155fe1c642dSBill Krier domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry); 1156fe1c642dSBill Krier 1157fe1c642dSBill Krier if (sids == NULL || domain_table == NULL || domain_entry == NULL) { 1158fe1c642dSBill Krier bzero(param, sizeof (struct lsar_LookupNames3)); 1159fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1160fe1c642dSBill Krier return (NDR_DRC_OK); 1161fe1c642dSBill Krier } 1162fe1c642dSBill Krier 1163fe1c642dSBill Krier accname = (char *)param->name_table->names->str; 1164fe1c642dSBill Krier status = lsa_lookup_name(accname, SidTypeUnknown, &account); 1165fe1c642dSBill Krier if (status != NT_STATUS_SUCCESS) { 1166fe1c642dSBill Krier bzero(param, sizeof (struct lsar_LookupNames3)); 1167fe1c642dSBill Krier param->status = NT_SC_ERROR(status); 1168fe1c642dSBill Krier return (NDR_DRC_OK); 1169fe1c642dSBill Krier } 1170fe1c642dSBill Krier 1171fe1c642dSBill Krier /* 1172fe1c642dSBill Krier * Set up the SID table. 1173fe1c642dSBill Krier */ 1174fe1c642dSBill Krier bzero(sids, sizeof (struct lsar_translated_sid_ex2)); 1175fe1c642dSBill Krier sids[0].sid_name_use = account.a_type; 1176fe1c642dSBill Krier sids[0].sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_sid); 1177fe1c642dSBill Krier sids[0].domain_index = 0; 1178fe1c642dSBill Krier param->translated_sids.n_entry = 1; 1179fe1c642dSBill Krier param->translated_sids.sids = sids; 1180fe1c642dSBill Krier 1181fe1c642dSBill Krier /* 1182fe1c642dSBill Krier * Set up the domain table. 1183fe1c642dSBill Krier */ 1184fe1c642dSBill Krier domain_table->entries = domain_entry; 1185fe1c642dSBill Krier domain_table->n_entry = 1; 1186fe1c642dSBill Krier domain_table->max_n_entry = MLSVC_DOMAIN_MAX; 1187fe1c642dSBill Krier 1188fe1c642dSBill Krier rc = NDR_MSTRING(mxa, account.a_domain, 1189fe1c642dSBill Krier (ndr_mstring_t *)&domain_entry->domain_name); 1190fe1c642dSBill Krier 1191fe1c642dSBill Krier domain_entry->domain_sid = 1192fe1c642dSBill Krier (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid); 1193fe1c642dSBill Krier 1194fe1c642dSBill Krier if (rc == -1 || domain_entry->domain_sid == NULL) { 1195fe1c642dSBill Krier smb_account_free(&account); 1196fe1c642dSBill Krier bzero(param, sizeof (struct lsar_LookupNames3)); 1197fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1198fe1c642dSBill Krier return (NDR_DRC_OK); 1199fe1c642dSBill Krier } 1200fe1c642dSBill Krier 1201fe1c642dSBill Krier param->domain_table = domain_table; 1202fe1c642dSBill Krier param->mapped_count = 1; 1203fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS; 1204fe1c642dSBill Krier 1205fe1c642dSBill Krier smb_account_free(&account); 1206fe1c642dSBill Krier return (NDR_DRC_OK); 1207fe1c642dSBill Krier } 1208fe1c642dSBill Krier 1209fe1c642dSBill Krier /* 1210fe1c642dSBill Krier * LookupNames4 is only valid on domain controllers. 1211fe1c642dSBill Krier * Other servers must return NT_STATUS_INVALID_SERVER_STATE. 1212fe1c642dSBill Krier */ 1213fe1c642dSBill Krier /*ARGSUSED*/ 1214fe1c642dSBill Krier static int 1215fe1c642dSBill Krier lsarpc_s_LookupNames4(void *arg, ndr_xa_t *mxa) 1216fe1c642dSBill Krier { 1217fe1c642dSBill Krier struct lsar_LookupNames4 *param = arg; 1218fe1c642dSBill Krier 1219fe1c642dSBill Krier bzero(param, sizeof (struct lsar_LookupNames4)); 1220fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_SERVER_STATE); 1221fe1c642dSBill Krier return (NDR_DRC_OK); 1222fe1c642dSBill Krier } 1223fe1c642dSBill Krier 1224fe1c642dSBill Krier /* 1225fe1c642dSBill Krier * There is a bug in the way that ndrgen and the marshalling code handles 1226fe1c642dSBill Krier * unions so we need to fix some of the data offsets at runtime. The 1227fe1c642dSBill Krier * following macros and the fixup functions handle the corrections. 1228fe1c642dSBill Krier */ 1229fe1c642dSBill Krier 1230fe1c642dSBill Krier DECL_FIXUP_STRUCT(mslsa_PolicyInfoResUnion); 1231fe1c642dSBill Krier DECL_FIXUP_STRUCT(mslsa_PolicyInfoRes); 1232fe1c642dSBill Krier DECL_FIXUP_STRUCT(mslsa_QueryInfoPolicy); 1233fe1c642dSBill Krier void 1234fe1c642dSBill Krier fixup_mslsa_QueryInfoPolicy(struct mslsa_QueryInfoPolicy *val) 1235fe1c642dSBill Krier { 1236fe1c642dSBill Krier unsigned short size1 = 0; 1237fe1c642dSBill Krier unsigned short size2 = 0; 1238fe1c642dSBill Krier unsigned short size3 = 0; 1239fe1c642dSBill Krier 1240fe1c642dSBill Krier switch (val->info_class) { 1241fe1c642dSBill Krier case MSLSA_POLICY_AUDIT_EVENTS_INFO: 1242fe1c642dSBill Krier size1 = sizeof (struct mslsa_AuditEventsInfo); 1243fe1c642dSBill Krier break; 1244fe1c642dSBill Krier 1245fe1c642dSBill Krier case MSLSA_POLICY_PRIMARY_DOMAIN_INFO: 1246fe1c642dSBill Krier size1 = sizeof (struct mslsa_PrimaryDomainInfo); 1247fe1c642dSBill Krier break; 1248fe1c642dSBill Krier 1249fe1c642dSBill Krier case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO: 1250fe1c642dSBill Krier size1 = sizeof (struct mslsa_AccountDomainInfo); 1251fe1c642dSBill Krier break; 1252fe1c642dSBill Krier 1253fe1c642dSBill Krier case MSLSA_POLICY_SERVER_ROLE_INFO: 1254fe1c642dSBill Krier size1 = sizeof (struct mslsa_ServerRoleInfo); 1255fe1c642dSBill Krier break; 1256fe1c642dSBill Krier 1257fe1c642dSBill Krier case MSLSA_POLICY_DNS_DOMAIN_INFO: 1258fe1c642dSBill Krier size1 = sizeof (struct mslsa_DnsDomainInfo); 1259fe1c642dSBill Krier break; 1260fe1c642dSBill Krier 1261fe1c642dSBill Krier default: 1262fe1c642dSBill Krier return; 1263fe1c642dSBill Krier }; 1264fe1c642dSBill Krier 1265fe1c642dSBill Krier size2 = size1 + (2 * sizeof (DWORD)); 1266fe1c642dSBill Krier size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 1267fe1c642dSBill Krier 1268fe1c642dSBill Krier FIXUP_PDU_SIZE(mslsa_PolicyInfoResUnion, size1); 1269fe1c642dSBill Krier FIXUP_PDU_SIZE(mslsa_PolicyInfoRes, size2); 1270fe1c642dSBill Krier FIXUP_PDU_SIZE(mslsa_QueryInfoPolicy, size3); 1271fe1c642dSBill Krier } 1272