xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c (revision 13082:81ec56bf6147)
111337SWilliam.Krier@Sun.COM /*
211337SWilliam.Krier@Sun.COM  * CDDL HEADER START
311337SWilliam.Krier@Sun.COM  *
411337SWilliam.Krier@Sun.COM  * The contents of this file are subject to the terms of the
511337SWilliam.Krier@Sun.COM  * Common Development and Distribution License (the "License").
611337SWilliam.Krier@Sun.COM  * You may not use this file except in compliance with the License.
711337SWilliam.Krier@Sun.COM  *
811337SWilliam.Krier@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911337SWilliam.Krier@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1011337SWilliam.Krier@Sun.COM  * See the License for the specific language governing permissions
1111337SWilliam.Krier@Sun.COM  * and limitations under the License.
1211337SWilliam.Krier@Sun.COM  *
1311337SWilliam.Krier@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1411337SWilliam.Krier@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511337SWilliam.Krier@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1611337SWilliam.Krier@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1711337SWilliam.Krier@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1811337SWilliam.Krier@Sun.COM  *
1911337SWilliam.Krier@Sun.COM  * CDDL HEADER END
2011337SWilliam.Krier@Sun.COM  */
2112508Samw@Sun.COM 
2211337SWilliam.Krier@Sun.COM /*
2312508Samw@Sun.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2411337SWilliam.Krier@Sun.COM  */
2511337SWilliam.Krier@Sun.COM 
2611337SWilliam.Krier@Sun.COM /*
2711337SWilliam.Krier@Sun.COM  * Local Security Authority RPC (LSAR) server-side interface.
2811337SWilliam.Krier@Sun.COM  */
2911337SWilliam.Krier@Sun.COM 
3011337SWilliam.Krier@Sun.COM #include <unistd.h>
3111337SWilliam.Krier@Sun.COM #include <strings.h>
3211337SWilliam.Krier@Sun.COM #include <pwd.h>
3311337SWilliam.Krier@Sun.COM #include <grp.h>
3411337SWilliam.Krier@Sun.COM 
3511337SWilliam.Krier@Sun.COM #include <smbsrv/libsmb.h>
3611337SWilliam.Krier@Sun.COM #include <smbsrv/libmlrpc.h>
3711337SWilliam.Krier@Sun.COM #include <smbsrv/libmlsvc.h>
3811337SWilliam.Krier@Sun.COM #include <smbsrv/ndl/lsarpc.ndl>
3911337SWilliam.Krier@Sun.COM #include <lsalib.h>
4011337SWilliam.Krier@Sun.COM #include <smbsrv/smbinfo.h>
4111337SWilliam.Krier@Sun.COM #include <smbsrv/nmpipes.h>
4211337SWilliam.Krier@Sun.COM #include <smbsrv/ntlocale.h>
4311337SWilliam.Krier@Sun.COM 
4411337SWilliam.Krier@Sun.COM struct local_group_table {
4511337SWilliam.Krier@Sun.COM 	WORD sid_name_use;
4611337SWilliam.Krier@Sun.COM 	WORD domain_ix;
4711337SWilliam.Krier@Sun.COM 	char *sid;
4811337SWilliam.Krier@Sun.COM 	char *name;
4911337SWilliam.Krier@Sun.COM };
5011337SWilliam.Krier@Sun.COM 
5111337SWilliam.Krier@Sun.COM static int lsarpc_key_domain;
5211337SWilliam.Krier@Sun.COM static int lsarpc_key_account;
5311337SWilliam.Krier@Sun.COM 
5411337SWilliam.Krier@Sun.COM static int lsarpc_call_stub(ndr_xa_t *mxa);
5511337SWilliam.Krier@Sun.COM 
5611337SWilliam.Krier@Sun.COM static int lsarpc_s_CloseHandle(void *, ndr_xa_t *);
5711337SWilliam.Krier@Sun.COM static int lsarpc_s_QuerySecurityObject(void *, ndr_xa_t *);
5811337SWilliam.Krier@Sun.COM static int lsarpc_s_EnumAccounts(void *, ndr_xa_t *);
5911337SWilliam.Krier@Sun.COM static int lsarpc_s_EnumTrustedDomain(void *, ndr_xa_t *);
6011337SWilliam.Krier@Sun.COM static int lsarpc_s_EnumTrustedDomainsEx(void *, ndr_xa_t *);
6111337SWilliam.Krier@Sun.COM static int lsarpc_s_OpenAccount(void *, ndr_xa_t *);
6211337SWilliam.Krier@Sun.COM static int lsarpc_s_EnumPrivsAccount(void *, ndr_xa_t *);
6311337SWilliam.Krier@Sun.COM static int lsarpc_s_LookupPrivValue(void *, ndr_xa_t *);
6411337SWilliam.Krier@Sun.COM static int lsarpc_s_LookupPrivName(void *, ndr_xa_t *);
6511337SWilliam.Krier@Sun.COM static int lsarpc_s_LookupPrivDisplayName(void *, ndr_xa_t *);
6611337SWilliam.Krier@Sun.COM static int lsarpc_s_CreateSecret(void *, ndr_xa_t *);
6711337SWilliam.Krier@Sun.COM static int lsarpc_s_OpenSecret(void *, ndr_xa_t *);
6811337SWilliam.Krier@Sun.COM static int lsarpc_s_QueryInfoPolicy(void *, ndr_xa_t *);
6911337SWilliam.Krier@Sun.COM static int lsarpc_s_OpenDomainHandle(void *, ndr_xa_t *);
7011337SWilliam.Krier@Sun.COM static int lsarpc_s_OpenDomainHandle(void *, ndr_xa_t *);
7111337SWilliam.Krier@Sun.COM static int lsarpc_s_LookupSids(void *, ndr_xa_t *);
7211337SWilliam.Krier@Sun.COM static int lsarpc_s_LookupNames(void *, ndr_xa_t *);
7311337SWilliam.Krier@Sun.COM static int lsarpc_s_GetConnectedUser(void *, ndr_xa_t *);
7411337SWilliam.Krier@Sun.COM static int lsarpc_s_LookupSids2(void *, ndr_xa_t *);
7511337SWilliam.Krier@Sun.COM static int lsarpc_s_LookupSids3(void *, ndr_xa_t *);
7611337SWilliam.Krier@Sun.COM static int lsarpc_s_LookupNames2(void *, ndr_xa_t *);
7711337SWilliam.Krier@Sun.COM static int lsarpc_s_LookupNames3(void *, ndr_xa_t *);
7811337SWilliam.Krier@Sun.COM static int lsarpc_s_LookupNames4(void *, ndr_xa_t *);
7911337SWilliam.Krier@Sun.COM 
8011337SWilliam.Krier@Sun.COM static DWORD lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *,
8111337SWilliam.Krier@Sun.COM     ndr_xa_t *);
8211337SWilliam.Krier@Sun.COM static DWORD lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *,
8311337SWilliam.Krier@Sun.COM     ndr_xa_t *);
8411337SWilliam.Krier@Sun.COM static int lsarpc_s_UpdateDomainTable(ndr_xa_t *,
8511337SWilliam.Krier@Sun.COM     smb_account_t *, struct mslsa_domain_table *, DWORD *);
8611337SWilliam.Krier@Sun.COM 
8711337SWilliam.Krier@Sun.COM static ndr_stub_table_t lsarpc_stub_table[] = {
8811337SWilliam.Krier@Sun.COM 	{ lsarpc_s_CloseHandle,		  LSARPC_OPNUM_CloseHandle },
8911337SWilliam.Krier@Sun.COM 	{ lsarpc_s_QuerySecurityObject,	  LSARPC_OPNUM_QuerySecurityObject },
9011337SWilliam.Krier@Sun.COM 	{ lsarpc_s_EnumAccounts,	  LSARPC_OPNUM_EnumerateAccounts },
9111337SWilliam.Krier@Sun.COM 	{ lsarpc_s_EnumTrustedDomain,	  LSARPC_OPNUM_EnumTrustedDomain },
9211337SWilliam.Krier@Sun.COM 	{ lsarpc_s_EnumTrustedDomainsEx,  LSARPC_OPNUM_EnumTrustedDomainsEx },
9311337SWilliam.Krier@Sun.COM 	{ lsarpc_s_OpenAccount,		  LSARPC_OPNUM_OpenAccount },
9411337SWilliam.Krier@Sun.COM 	{ lsarpc_s_EnumPrivsAccount,	  LSARPC_OPNUM_EnumPrivsAccount },
9511337SWilliam.Krier@Sun.COM 	{ lsarpc_s_LookupPrivValue,	  LSARPC_OPNUM_LookupPrivValue },
9611337SWilliam.Krier@Sun.COM 	{ lsarpc_s_LookupPrivName,	  LSARPC_OPNUM_LookupPrivName },
9711337SWilliam.Krier@Sun.COM 	{ lsarpc_s_LookupPrivDisplayName, LSARPC_OPNUM_LookupPrivDisplayName },
9811337SWilliam.Krier@Sun.COM 	{ lsarpc_s_CreateSecret,	  LSARPC_OPNUM_CreateSecret },
9911337SWilliam.Krier@Sun.COM 	{ lsarpc_s_OpenSecret,		  LSARPC_OPNUM_OpenSecret },
10011337SWilliam.Krier@Sun.COM 	{ lsarpc_s_QueryInfoPolicy,	  LSARPC_OPNUM_QueryInfoPolicy },
10111337SWilliam.Krier@Sun.COM 	{ lsarpc_s_OpenDomainHandle,	  LSARPC_OPNUM_OpenPolicy },
10211337SWilliam.Krier@Sun.COM 	{ lsarpc_s_OpenDomainHandle,	  LSARPC_OPNUM_OpenPolicy2 },
10311337SWilliam.Krier@Sun.COM 	{ lsarpc_s_LookupSids,		  LSARPC_OPNUM_LookupSids },
10411337SWilliam.Krier@Sun.COM 	{ lsarpc_s_LookupNames,		  LSARPC_OPNUM_LookupNames },
10511337SWilliam.Krier@Sun.COM 	{ lsarpc_s_GetConnectedUser,	  LSARPC_OPNUM_GetConnectedUser },
10611337SWilliam.Krier@Sun.COM 	{ lsarpc_s_LookupSids2,		  LSARPC_OPNUM_LookupSids2 },
10711337SWilliam.Krier@Sun.COM 	{ lsarpc_s_LookupSids3,		  LSARPC_OPNUM_LookupSids3 },
10811337SWilliam.Krier@Sun.COM 	{ lsarpc_s_LookupNames2,	  LSARPC_OPNUM_LookupNames2 },
10911337SWilliam.Krier@Sun.COM 	{ lsarpc_s_LookupNames3,	  LSARPC_OPNUM_LookupNames3 },
11011337SWilliam.Krier@Sun.COM 	{ lsarpc_s_LookupNames4,	  LSARPC_OPNUM_LookupNames4 },
11111337SWilliam.Krier@Sun.COM 	{0}
11211337SWilliam.Krier@Sun.COM };
11311337SWilliam.Krier@Sun.COM 
11411337SWilliam.Krier@Sun.COM static ndr_service_t lsarpc_service = {
11511337SWilliam.Krier@Sun.COM 	"LSARPC",			/* name */
11611337SWilliam.Krier@Sun.COM 	"Local Security Authority",	/* desc */
11711337SWilliam.Krier@Sun.COM 	"\\lsarpc",			/* endpoint */
11811337SWilliam.Krier@Sun.COM 	PIPE_LSASS,			/* sec_addr_port */
11911337SWilliam.Krier@Sun.COM 	"12345778-1234-abcd-ef00-0123456789ab", 0,	/* abstract */
12011337SWilliam.Krier@Sun.COM 	NDR_TRANSFER_SYNTAX_UUID,		2,	/* transfer */
12111337SWilliam.Krier@Sun.COM 	0,				/* no bind_instance_size */
12211337SWilliam.Krier@Sun.COM 	NULL,				/* no bind_req() */
12311337SWilliam.Krier@Sun.COM 	NULL,				/* no unbind_and_close() */
12411337SWilliam.Krier@Sun.COM 	lsarpc_call_stub,		/* call_stub() */
12511337SWilliam.Krier@Sun.COM 	&TYPEINFO(lsarpc_interface),	/* interface ti */
12611337SWilliam.Krier@Sun.COM 	lsarpc_stub_table		/* stub_table */
12711337SWilliam.Krier@Sun.COM };
12811337SWilliam.Krier@Sun.COM 
12911337SWilliam.Krier@Sun.COM /*
13011337SWilliam.Krier@Sun.COM  * lsarpc_initialize
13111337SWilliam.Krier@Sun.COM  *
13211337SWilliam.Krier@Sun.COM  * This function registers the LSA RPC interface with the RPC runtime
13311337SWilliam.Krier@Sun.COM  * library. It must be called in order to use either the client side
13411337SWilliam.Krier@Sun.COM  * or the server side functions.
13511337SWilliam.Krier@Sun.COM  */
13611337SWilliam.Krier@Sun.COM void
lsarpc_initialize(void)13711337SWilliam.Krier@Sun.COM lsarpc_initialize(void)
13811337SWilliam.Krier@Sun.COM {
13911337SWilliam.Krier@Sun.COM 	(void) ndr_svc_register(&lsarpc_service);
14011337SWilliam.Krier@Sun.COM }
14111337SWilliam.Krier@Sun.COM 
14211337SWilliam.Krier@Sun.COM /*
14311337SWilliam.Krier@Sun.COM  * Custom call_stub to set the stream string policy.
14411337SWilliam.Krier@Sun.COM  */
14511337SWilliam.Krier@Sun.COM static int
lsarpc_call_stub(ndr_xa_t * mxa)14611337SWilliam.Krier@Sun.COM lsarpc_call_stub(ndr_xa_t *mxa)
14711337SWilliam.Krier@Sun.COM {
14811337SWilliam.Krier@Sun.COM 	NDS_SETF(&mxa->send_nds, NDS_F_NOTERM);
14911337SWilliam.Krier@Sun.COM 	NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM);
15011337SWilliam.Krier@Sun.COM 
15111337SWilliam.Krier@Sun.COM 	return (ndr_generic_call_stub(mxa));
15211337SWilliam.Krier@Sun.COM }
15311337SWilliam.Krier@Sun.COM 
15411337SWilliam.Krier@Sun.COM /*
15511337SWilliam.Krier@Sun.COM  * lsarpc_s_OpenDomainHandle opnum=0x06
15611337SWilliam.Krier@Sun.COM  *
15711337SWilliam.Krier@Sun.COM  * This is a request to open the LSA (OpenPolicy and OpenPolicy2).
15811337SWilliam.Krier@Sun.COM  * The client is looking for an LSA domain handle.
15911337SWilliam.Krier@Sun.COM  */
16011337SWilliam.Krier@Sun.COM static int
lsarpc_s_OpenDomainHandle(void * arg,ndr_xa_t * mxa)16111337SWilliam.Krier@Sun.COM lsarpc_s_OpenDomainHandle(void *arg, ndr_xa_t *mxa)
16211337SWilliam.Krier@Sun.COM {
16311337SWilliam.Krier@Sun.COM 	struct mslsa_OpenPolicy2 *param = arg;
16411337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id;
16511337SWilliam.Krier@Sun.COM 
16611337SWilliam.Krier@Sun.COM 	if ((id = ndr_hdalloc(mxa, &lsarpc_key_domain)) != NULL) {
16711337SWilliam.Krier@Sun.COM 		bcopy(id, &param->domain_handle, sizeof (mslsa_handle_t));
16811337SWilliam.Krier@Sun.COM 		param->status = NT_STATUS_SUCCESS;
16911337SWilliam.Krier@Sun.COM 	} else {
17011337SWilliam.Krier@Sun.COM 		bzero(&param->domain_handle, sizeof (mslsa_handle_t));
17111337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
17211337SWilliam.Krier@Sun.COM 	}
17311337SWilliam.Krier@Sun.COM 
17411337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
17511337SWilliam.Krier@Sun.COM }
17611337SWilliam.Krier@Sun.COM 
17711337SWilliam.Krier@Sun.COM /*
17811337SWilliam.Krier@Sun.COM  * lsarpc_s_CloseHandle opnum=0x00
17911337SWilliam.Krier@Sun.COM  *
18011337SWilliam.Krier@Sun.COM  * This is a request to close the LSA interface specified by the handle.
18111337SWilliam.Krier@Sun.COM  * We don't track handles (yet), so just zero out the handle and return
18211337SWilliam.Krier@Sun.COM  * NDR_DRC_OK. Setting the handle to zero appears to be standard
18311337SWilliam.Krier@Sun.COM  * behaviour and someone may rely on it, i.e. we do on the client side.
18411337SWilliam.Krier@Sun.COM  */
18511337SWilliam.Krier@Sun.COM static int
lsarpc_s_CloseHandle(void * arg,ndr_xa_t * mxa)18611337SWilliam.Krier@Sun.COM lsarpc_s_CloseHandle(void *arg, ndr_xa_t *mxa)
18711337SWilliam.Krier@Sun.COM {
18811337SWilliam.Krier@Sun.COM 	struct mslsa_CloseHandle *param = arg;
18911337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
19011337SWilliam.Krier@Sun.COM 
19111337SWilliam.Krier@Sun.COM 	ndr_hdfree(mxa, id);
19211337SWilliam.Krier@Sun.COM 
19311337SWilliam.Krier@Sun.COM 	bzero(&param->result_handle, sizeof (param->result_handle));
19411337SWilliam.Krier@Sun.COM 	param->status = NT_STATUS_SUCCESS;
19511337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
19611337SWilliam.Krier@Sun.COM }
19711337SWilliam.Krier@Sun.COM 
19811337SWilliam.Krier@Sun.COM /*
19911337SWilliam.Krier@Sun.COM  * lsarpc_s_QuerySecurityObject
20011337SWilliam.Krier@Sun.COM  */
20111337SWilliam.Krier@Sun.COM /*ARGSUSED*/
20211337SWilliam.Krier@Sun.COM static int
lsarpc_s_QuerySecurityObject(void * arg,ndr_xa_t * mxa)20311337SWilliam.Krier@Sun.COM lsarpc_s_QuerySecurityObject(void *arg, ndr_xa_t *mxa)
20411337SWilliam.Krier@Sun.COM {
20511337SWilliam.Krier@Sun.COM 	struct mslsa_QuerySecurityObject *param = arg;
20611337SWilliam.Krier@Sun.COM 
20711337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct mslsa_QuerySecurityObject));
20811337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
20911337SWilliam.Krier@Sun.COM 
21011337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
21111337SWilliam.Krier@Sun.COM }
21211337SWilliam.Krier@Sun.COM 
21311337SWilliam.Krier@Sun.COM /*
21411337SWilliam.Krier@Sun.COM  * lsarpc_s_EnumAccounts
21511337SWilliam.Krier@Sun.COM  *
21611337SWilliam.Krier@Sun.COM  * Enumerate the list of local accounts SIDs. The client should supply
21711337SWilliam.Krier@Sun.COM  * a valid OpenPolicy2 handle. The enum_context is used to support
21811337SWilliam.Krier@Sun.COM  * multiple enumeration calls to obtain the complete list of SIDs.
21911337SWilliam.Krier@Sun.COM  * It should be set to 0 on the first call and passed unchanged on
22011337SWilliam.Krier@Sun.COM  * subsequent calls until there are no more accounts - the server will
22112508Samw@Sun.COM  * return STATUS_NO_MORE_ENTRIES.
22211337SWilliam.Krier@Sun.COM  *
22311337SWilliam.Krier@Sun.COM  * For now just set the status to access-denied. Note that we still have
22411337SWilliam.Krier@Sun.COM  * to provide a valid address for enum_buf because it's a reference and
22511337SWilliam.Krier@Sun.COM  * the marshalling rules require that references must not be null.
22611337SWilliam.Krier@Sun.COM  * The enum_context is used to support multiple
22711337SWilliam.Krier@Sun.COM  */
22811337SWilliam.Krier@Sun.COM static int
lsarpc_s_EnumAccounts(void * arg,ndr_xa_t * mxa)22911337SWilliam.Krier@Sun.COM lsarpc_s_EnumAccounts(void *arg, ndr_xa_t *mxa)
23011337SWilliam.Krier@Sun.COM {
23111337SWilliam.Krier@Sun.COM 	struct mslsa_EnumerateAccounts *param = arg;
23211337SWilliam.Krier@Sun.COM 	struct mslsa_EnumAccountBuf *enum_buf;
23311337SWilliam.Krier@Sun.COM 
23411337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct mslsa_EnumerateAccounts));
23511337SWilliam.Krier@Sun.COM 
23611337SWilliam.Krier@Sun.COM 	enum_buf = NDR_NEW(mxa, struct mslsa_EnumAccountBuf);
23711337SWilliam.Krier@Sun.COM 	if (enum_buf == NULL) {
23811337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
23911337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
24011337SWilliam.Krier@Sun.COM 	}
24111337SWilliam.Krier@Sun.COM 
24211337SWilliam.Krier@Sun.COM 	bzero(enum_buf, sizeof (struct mslsa_EnumAccountBuf));
24311337SWilliam.Krier@Sun.COM 	param->enum_buf = enum_buf;
24411337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
24511337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
24611337SWilliam.Krier@Sun.COM }
24711337SWilliam.Krier@Sun.COM 
24811337SWilliam.Krier@Sun.COM 
24911337SWilliam.Krier@Sun.COM /*
25011337SWilliam.Krier@Sun.COM  * lsarpc_s_EnumTrustedDomain
25111337SWilliam.Krier@Sun.COM  *
25211337SWilliam.Krier@Sun.COM  * This is the server side function for handling requests to enumerate
25311337SWilliam.Krier@Sun.COM  * the list of trusted domains: currently held in the NT domain database.
25411337SWilliam.Krier@Sun.COM  * This call requires an OpenPolicy2 handle. The enum_context is used to
25511337SWilliam.Krier@Sun.COM  * support multiple enumeration calls to obtain the complete list.
25611337SWilliam.Krier@Sun.COM  * It should be set to 0 on the first call and passed unchanged on
25711337SWilliam.Krier@Sun.COM  * subsequent calls until there are no more accounts - the server will
25812508Samw@Sun.COM  * return STATUS_NO_MORE_ENTRIES.
25911337SWilliam.Krier@Sun.COM  *
26011337SWilliam.Krier@Sun.COM  * For now just set the status to access-denied. Note that we still have
26111337SWilliam.Krier@Sun.COM  * to provide a valid address for enum_buf because it's a reference and
26211337SWilliam.Krier@Sun.COM  * the marshalling rules require that references must not be null.
26311337SWilliam.Krier@Sun.COM  */
26411337SWilliam.Krier@Sun.COM static int
lsarpc_s_EnumTrustedDomain(void * arg,ndr_xa_t * mxa)26511337SWilliam.Krier@Sun.COM lsarpc_s_EnumTrustedDomain(void *arg, ndr_xa_t *mxa)
26611337SWilliam.Krier@Sun.COM {
26711337SWilliam.Krier@Sun.COM 	struct mslsa_EnumTrustedDomain *param = arg;
26811337SWilliam.Krier@Sun.COM 	struct mslsa_EnumTrustedDomainBuf *enum_buf;
26911337SWilliam.Krier@Sun.COM 
27011337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct mslsa_EnumTrustedDomain));
27111337SWilliam.Krier@Sun.COM 
27211337SWilliam.Krier@Sun.COM 	enum_buf = NDR_NEW(mxa, struct mslsa_EnumTrustedDomainBuf);
27311337SWilliam.Krier@Sun.COM 	if (enum_buf == NULL) {
27411337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
27511337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
27611337SWilliam.Krier@Sun.COM 	}
27711337SWilliam.Krier@Sun.COM 
27811337SWilliam.Krier@Sun.COM 	bzero(enum_buf, sizeof (struct mslsa_EnumTrustedDomainBuf));
27911337SWilliam.Krier@Sun.COM 	param->enum_buf = enum_buf;
28011337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
28111337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
28211337SWilliam.Krier@Sun.COM }
28311337SWilliam.Krier@Sun.COM 
28411337SWilliam.Krier@Sun.COM /*
28511337SWilliam.Krier@Sun.COM  * lsarpc_s_EnumTrustedDomainsEx
28611337SWilliam.Krier@Sun.COM  *
28711337SWilliam.Krier@Sun.COM  * This is the server side function for handling requests to enumerate
28811337SWilliam.Krier@Sun.COM  * the list of trusted domains: currently held in the NT domain database.
28911337SWilliam.Krier@Sun.COM  * This call requires an OpenPolicy2 handle. The enum_context is used to
29011337SWilliam.Krier@Sun.COM  * support multiple enumeration calls to obtain the complete list.
29111337SWilliam.Krier@Sun.COM  * It should be set to 0 on the first call and passed unchanged on
29211337SWilliam.Krier@Sun.COM  * subsequent calls until there are no more accounts - the server will
29312508Samw@Sun.COM  * return STATUS_NO_MORE_ENTRIES.
29411337SWilliam.Krier@Sun.COM  *
29511337SWilliam.Krier@Sun.COM  * For now just set the status to access-denied. Note that we still have
29611337SWilliam.Krier@Sun.COM  * to provide a valid address for enum_buf because it's a reference and
29711337SWilliam.Krier@Sun.COM  * the marshalling rules require that references must not be null.
29811337SWilliam.Krier@Sun.COM  */
29911337SWilliam.Krier@Sun.COM static int
lsarpc_s_EnumTrustedDomainsEx(void * arg,ndr_xa_t * mxa)30011337SWilliam.Krier@Sun.COM lsarpc_s_EnumTrustedDomainsEx(void *arg, ndr_xa_t *mxa)
30111337SWilliam.Krier@Sun.COM {
30211337SWilliam.Krier@Sun.COM 	struct mslsa_EnumTrustedDomainEx *param = arg;
30311337SWilliam.Krier@Sun.COM 	struct mslsa_EnumTrustedDomainBufEx *enum_buf;
30411337SWilliam.Krier@Sun.COM 
30511337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct mslsa_EnumTrustedDomainEx));
30611337SWilliam.Krier@Sun.COM 
30711337SWilliam.Krier@Sun.COM 	enum_buf = NDR_NEW(mxa, struct mslsa_EnumTrustedDomainBufEx);
30811337SWilliam.Krier@Sun.COM 	if (enum_buf == NULL) {
30911337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
31011337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
31111337SWilliam.Krier@Sun.COM 	}
31211337SWilliam.Krier@Sun.COM 
31311337SWilliam.Krier@Sun.COM 	bzero(enum_buf, sizeof (struct mslsa_EnumTrustedDomainBufEx));
31411337SWilliam.Krier@Sun.COM 	param->enum_buf = enum_buf;
31511337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
31611337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
31711337SWilliam.Krier@Sun.COM }
31811337SWilliam.Krier@Sun.COM 
31911337SWilliam.Krier@Sun.COM /*
32011337SWilliam.Krier@Sun.COM  * lsarpc_s_OpenAccount
32111337SWilliam.Krier@Sun.COM  *
32211337SWilliam.Krier@Sun.COM  * This is a request to open an account handle.
32311337SWilliam.Krier@Sun.COM  */
32411337SWilliam.Krier@Sun.COM static int
lsarpc_s_OpenAccount(void * arg,ndr_xa_t * mxa)32511337SWilliam.Krier@Sun.COM lsarpc_s_OpenAccount(void *arg, ndr_xa_t *mxa)
32611337SWilliam.Krier@Sun.COM {
32711337SWilliam.Krier@Sun.COM 	struct mslsa_OpenAccount *param = arg;
32811337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
32911337SWilliam.Krier@Sun.COM 	ndr_handle_t *hd;
33011337SWilliam.Krier@Sun.COM 
33111337SWilliam.Krier@Sun.COM 	hd = ndr_hdlookup(mxa, id);
33211337SWilliam.Krier@Sun.COM 	if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) {
33311337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_OpenAccount));
33411337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
33511337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
33611337SWilliam.Krier@Sun.COM 	}
33711337SWilliam.Krier@Sun.COM 
33811337SWilliam.Krier@Sun.COM 	if ((id = ndr_hdalloc(mxa, &lsarpc_key_account)) != NULL) {
33911337SWilliam.Krier@Sun.COM 		bcopy(id, &param->account_handle, sizeof (mslsa_handle_t));
34011337SWilliam.Krier@Sun.COM 		param->status = NT_STATUS_SUCCESS;
34111337SWilliam.Krier@Sun.COM 	} else {
34211337SWilliam.Krier@Sun.COM 		bzero(&param->account_handle, sizeof (mslsa_handle_t));
34311337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
34411337SWilliam.Krier@Sun.COM 	}
34511337SWilliam.Krier@Sun.COM 
34611337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
34711337SWilliam.Krier@Sun.COM }
34811337SWilliam.Krier@Sun.COM 
34911337SWilliam.Krier@Sun.COM 
35011337SWilliam.Krier@Sun.COM /*
35111337SWilliam.Krier@Sun.COM  * lsarpc_s_EnumPrivsAccount
35211337SWilliam.Krier@Sun.COM  *
35311337SWilliam.Krier@Sun.COM  * This is the server side function for handling requests for account
35411337SWilliam.Krier@Sun.COM  * privileges. For now just set the status to not-supported status and
35511337SWilliam.Krier@Sun.COM  * return NDR_DRC_OK. Note that we still have to provide a valid
35611337SWilliam.Krier@Sun.COM  * address for enum_buf because it's a reference and the marshalling
35711337SWilliam.Krier@Sun.COM  * rules require that references must not be null.
35811337SWilliam.Krier@Sun.COM  */
35911337SWilliam.Krier@Sun.COM /*ARGSUSED*/
36011337SWilliam.Krier@Sun.COM static int
lsarpc_s_EnumPrivsAccount(void * arg,ndr_xa_t * mxa)36111337SWilliam.Krier@Sun.COM lsarpc_s_EnumPrivsAccount(void *arg, ndr_xa_t *mxa)
36211337SWilliam.Krier@Sun.COM {
36311337SWilliam.Krier@Sun.COM 	struct mslsa_EnumPrivsAccount *param = arg;
36411337SWilliam.Krier@Sun.COM 
36511337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct mslsa_EnumPrivsAccount));
36611337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED);
36711337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
36811337SWilliam.Krier@Sun.COM }
36911337SWilliam.Krier@Sun.COM 
37011337SWilliam.Krier@Sun.COM /*
37111337SWilliam.Krier@Sun.COM  * lsarpc_s_LookupPrivValue
37211337SWilliam.Krier@Sun.COM  *
37311337SWilliam.Krier@Sun.COM  * Server side function used to map a privilege name to a locally unique
37411337SWilliam.Krier@Sun.COM  * identifier (LUID).
37511337SWilliam.Krier@Sun.COM  */
37611337SWilliam.Krier@Sun.COM /*ARGSUSED*/
37711337SWilliam.Krier@Sun.COM static int
lsarpc_s_LookupPrivValue(void * arg,ndr_xa_t * mxa)37811337SWilliam.Krier@Sun.COM lsarpc_s_LookupPrivValue(void *arg, ndr_xa_t *mxa)
37911337SWilliam.Krier@Sun.COM {
38011337SWilliam.Krier@Sun.COM 	struct mslsa_LookupPrivValue *param = arg;
38111337SWilliam.Krier@Sun.COM 	smb_privinfo_t *pi;
38211337SWilliam.Krier@Sun.COM 
38311337SWilliam.Krier@Sun.COM 	if ((pi = smb_priv_getbyname((char *)param->name.str)) == NULL) {
38411337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_LookupPrivValue));
38511337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE);
38611337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
38711337SWilliam.Krier@Sun.COM 	}
38811337SWilliam.Krier@Sun.COM 
38911337SWilliam.Krier@Sun.COM 	param->luid.low_part = pi->id;
39011337SWilliam.Krier@Sun.COM 	param->luid.high_part = 0;
39111337SWilliam.Krier@Sun.COM 	param->status = NT_STATUS_SUCCESS;
39211337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
39311337SWilliam.Krier@Sun.COM }
39411337SWilliam.Krier@Sun.COM 
39511337SWilliam.Krier@Sun.COM /*
39611337SWilliam.Krier@Sun.COM  * lsarpc_s_LookupPrivName
39711337SWilliam.Krier@Sun.COM  *
39811337SWilliam.Krier@Sun.COM  * Server side function used to map a locally unique identifier (LUID)
39911337SWilliam.Krier@Sun.COM  * to the appropriate privilege name string.
40011337SWilliam.Krier@Sun.COM  */
40111337SWilliam.Krier@Sun.COM static int
lsarpc_s_LookupPrivName(void * arg,ndr_xa_t * mxa)40211337SWilliam.Krier@Sun.COM lsarpc_s_LookupPrivName(void *arg, ndr_xa_t *mxa)
40311337SWilliam.Krier@Sun.COM {
40411337SWilliam.Krier@Sun.COM 	struct mslsa_LookupPrivName *param = arg;
40511337SWilliam.Krier@Sun.COM 	smb_privinfo_t *pi;
40611337SWilliam.Krier@Sun.COM 	int rc;
40711337SWilliam.Krier@Sun.COM 
40811337SWilliam.Krier@Sun.COM 	if ((pi = smb_priv_getbyvalue(param->luid.low_part)) == NULL) {
40911337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_LookupPrivName));
41011337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE);
41111337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
41211337SWilliam.Krier@Sun.COM 	}
41311337SWilliam.Krier@Sun.COM 
41411337SWilliam.Krier@Sun.COM 	param->name = NDR_NEW(mxa, mslsa_string_t);
41511337SWilliam.Krier@Sun.COM 	if (param->name == NULL) {
41611337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_LookupPrivName));
41711337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
41811337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
41911337SWilliam.Krier@Sun.COM 	}
42011337SWilliam.Krier@Sun.COM 
42111337SWilliam.Krier@Sun.COM 	rc = NDR_MSTRING(mxa, pi->name, (ndr_mstring_t *)param->name);
42211337SWilliam.Krier@Sun.COM 	if (rc == -1) {
42311337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_LookupPrivName));
42411337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
42511337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
42611337SWilliam.Krier@Sun.COM 	}
42711337SWilliam.Krier@Sun.COM 
42811337SWilliam.Krier@Sun.COM 	param->status = NT_STATUS_SUCCESS;
42911337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
43011337SWilliam.Krier@Sun.COM }
43111337SWilliam.Krier@Sun.COM 
43211337SWilliam.Krier@Sun.COM /*
43311337SWilliam.Krier@Sun.COM  * lsarpc_s_LookupPrivDisplayName
43411337SWilliam.Krier@Sun.COM  *
43511337SWilliam.Krier@Sun.COM  * This is the server side function for handling requests for account
43611337SWilliam.Krier@Sun.COM  * privileges. For now just set the status to not-supported status and
43711337SWilliam.Krier@Sun.COM  * return NDR_DRC_OK.
43811337SWilliam.Krier@Sun.COM  */
43911337SWilliam.Krier@Sun.COM static int
lsarpc_s_LookupPrivDisplayName(void * arg,ndr_xa_t * mxa)44011337SWilliam.Krier@Sun.COM lsarpc_s_LookupPrivDisplayName(void *arg, ndr_xa_t *mxa)
44111337SWilliam.Krier@Sun.COM {
44211337SWilliam.Krier@Sun.COM 	struct mslsa_LookupPrivDisplayName *param = arg;
44311337SWilliam.Krier@Sun.COM 	smb_privinfo_t *pi;
44411337SWilliam.Krier@Sun.COM 	int rc;
44511337SWilliam.Krier@Sun.COM 
44611337SWilliam.Krier@Sun.COM 	if ((pi = smb_priv_getbyname((char *)param->name.str)) == NULL) {
44711337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_LookupPrivDisplayName));
44811337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_PRIVILEGE);
44911337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
45011337SWilliam.Krier@Sun.COM 	}
45111337SWilliam.Krier@Sun.COM 
45211337SWilliam.Krier@Sun.COM 	param->display_name = NDR_NEW(mxa, mslsa_string_t);
45311337SWilliam.Krier@Sun.COM 	if (param->display_name == NULL) {
45411337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_LookupPrivDisplayName));
45511337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
45611337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
45711337SWilliam.Krier@Sun.COM 	}
45811337SWilliam.Krier@Sun.COM 
45911337SWilliam.Krier@Sun.COM 	rc = NDR_MSTRING(mxa, pi->display_name,
46011337SWilliam.Krier@Sun.COM 	    (ndr_mstring_t *)param->display_name);
46111337SWilliam.Krier@Sun.COM 	if (rc == -1) {
46211337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_LookupPrivDisplayName));
46311337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
46411337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
46511337SWilliam.Krier@Sun.COM 	}
46611337SWilliam.Krier@Sun.COM 
46711337SWilliam.Krier@Sun.COM 	param->language_ret = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
46811337SWilliam.Krier@Sun.COM 	param->status = NT_STATUS_SUCCESS;
46911337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
47011337SWilliam.Krier@Sun.COM }
47111337SWilliam.Krier@Sun.COM 
47211337SWilliam.Krier@Sun.COM static int
lsarpc_s_CreateSecret(void * arg,ndr_xa_t * mxa)47311337SWilliam.Krier@Sun.COM lsarpc_s_CreateSecret(void *arg, ndr_xa_t *mxa)
47411337SWilliam.Krier@Sun.COM {
47511337SWilliam.Krier@Sun.COM 	struct mslsa_CreateSecret *param = arg;
47611337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
47711337SWilliam.Krier@Sun.COM 	ndr_handle_t *hd;
47811337SWilliam.Krier@Sun.COM 
47911337SWilliam.Krier@Sun.COM 	hd = ndr_hdlookup(mxa, id);
48011337SWilliam.Krier@Sun.COM 	if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) {
48111337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_OpenAccount));
48211337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
48311337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
48411337SWilliam.Krier@Sun.COM 	}
48511337SWilliam.Krier@Sun.COM 
48611337SWilliam.Krier@Sun.COM 	bzero(&param->secret_handle, sizeof (mslsa_handle_t));
48711337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
48811337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
48911337SWilliam.Krier@Sun.COM }
49011337SWilliam.Krier@Sun.COM 
49111337SWilliam.Krier@Sun.COM static int
lsarpc_s_OpenSecret(void * arg,ndr_xa_t * mxa)49211337SWilliam.Krier@Sun.COM lsarpc_s_OpenSecret(void *arg, ndr_xa_t *mxa)
49311337SWilliam.Krier@Sun.COM {
49411337SWilliam.Krier@Sun.COM 	struct mslsa_OpenSecret *param = arg;
49511337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
49611337SWilliam.Krier@Sun.COM 	ndr_handle_t *hd;
49711337SWilliam.Krier@Sun.COM 
49811337SWilliam.Krier@Sun.COM 	hd = ndr_hdlookup(mxa, id);
49911337SWilliam.Krier@Sun.COM 	if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) {
50011337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_OpenAccount));
50111337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
50211337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
50311337SWilliam.Krier@Sun.COM 	}
50411337SWilliam.Krier@Sun.COM 
50511337SWilliam.Krier@Sun.COM 	bzero(&param->secret_handle, sizeof (mslsa_handle_t));
50611337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
50711337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
50811337SWilliam.Krier@Sun.COM }
50911337SWilliam.Krier@Sun.COM 
51011337SWilliam.Krier@Sun.COM /*
51111337SWilliam.Krier@Sun.COM  * lsarpc_s_GetConnectedUser
51211337SWilliam.Krier@Sun.COM  *
51311337SWilliam.Krier@Sun.COM  * Return the account name and NetBIOS domain name for the user making
51411337SWilliam.Krier@Sun.COM  * the request.  The hostname field should be ignored by the server.
51511337SWilliam.Krier@Sun.COM  */
51611337SWilliam.Krier@Sun.COM static int
lsarpc_s_GetConnectedUser(void * arg,ndr_xa_t * mxa)51711337SWilliam.Krier@Sun.COM lsarpc_s_GetConnectedUser(void *arg, ndr_xa_t *mxa)
51811337SWilliam.Krier@Sun.COM {
51911337SWilliam.Krier@Sun.COM 	struct mslsa_GetConnectedUser *param = arg;
52011337SWilliam.Krier@Sun.COM 	smb_netuserinfo_t *user = &mxa->pipe->np_user;
52111337SWilliam.Krier@Sun.COM 	DWORD status = NT_STATUS_SUCCESS;
52211337SWilliam.Krier@Sun.COM 	smb_domainex_t di;
52311337SWilliam.Krier@Sun.COM 	int rc1;
52411337SWilliam.Krier@Sun.COM 	int rc2;
52511337SWilliam.Krier@Sun.COM 
52611337SWilliam.Krier@Sun.COM 	if (!smb_domain_getinfo(&di)) {
52711337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_GetConnectedUser));
52811337SWilliam.Krier@Sun.COM 		status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
52911337SWilliam.Krier@Sun.COM 		param->status = status;
53011337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
53111337SWilliam.Krier@Sun.COM 	}
53211337SWilliam.Krier@Sun.COM 
53311337SWilliam.Krier@Sun.COM 	param->owner = NDR_NEW(mxa, struct mslsa_string_desc);
53411337SWilliam.Krier@Sun.COM 	param->domain = NDR_NEW(mxa, struct mslsa_DomainName);
53511337SWilliam.Krier@Sun.COM 	if (param->owner == NULL || param->domain == NULL) {
53611337SWilliam.Krier@Sun.COM 		status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
53711337SWilliam.Krier@Sun.COM 		param->status = status;
53811337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
53911337SWilliam.Krier@Sun.COM 	}
54011337SWilliam.Krier@Sun.COM 
54111337SWilliam.Krier@Sun.COM 	param->domain->name = NDR_NEW(mxa, struct mslsa_string_desc);
54211337SWilliam.Krier@Sun.COM 	if (param->domain->name == NULL) {
54311337SWilliam.Krier@Sun.COM 		status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
54411337SWilliam.Krier@Sun.COM 		param->status = status;
54511337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
54611337SWilliam.Krier@Sun.COM 	}
54711337SWilliam.Krier@Sun.COM 
54811337SWilliam.Krier@Sun.COM 	rc1 = NDR_MSTRING(mxa, user->ui_account,
54911337SWilliam.Krier@Sun.COM 	    (ndr_mstring_t *)param->owner);
55011337SWilliam.Krier@Sun.COM 	rc2 = NDR_MSTRING(mxa, user->ui_domain,
55111337SWilliam.Krier@Sun.COM 	    (ndr_mstring_t *)param->domain->name);
55211337SWilliam.Krier@Sun.COM 
55311337SWilliam.Krier@Sun.COM 	if (rc1 == -1 || rc2 == -1)
55411337SWilliam.Krier@Sun.COM 		status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
55511337SWilliam.Krier@Sun.COM 
55611337SWilliam.Krier@Sun.COM 	param->status = status;
55711337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
55811337SWilliam.Krier@Sun.COM }
55911337SWilliam.Krier@Sun.COM 
56011337SWilliam.Krier@Sun.COM 
56111337SWilliam.Krier@Sun.COM /*
56211337SWilliam.Krier@Sun.COM  * lsarpc_s_QueryInfoPolicy
56311337SWilliam.Krier@Sun.COM  *
56411337SWilliam.Krier@Sun.COM  * This is the server side function for handling LSA information policy
56511337SWilliam.Krier@Sun.COM  * queries. Currently, we only support primary domain and account
56611337SWilliam.Krier@Sun.COM  * domain queries. This is just a front end to switch on the request
56711337SWilliam.Krier@Sun.COM  * and hand it off to the appropriate function to actually deal with
56811337SWilliam.Krier@Sun.COM  * obtaining and building the response.
56911337SWilliam.Krier@Sun.COM  */
57011337SWilliam.Krier@Sun.COM static int
lsarpc_s_QueryInfoPolicy(void * arg,ndr_xa_t * mxa)57111337SWilliam.Krier@Sun.COM lsarpc_s_QueryInfoPolicy(void *arg, ndr_xa_t *mxa)
57211337SWilliam.Krier@Sun.COM {
57311337SWilliam.Krier@Sun.COM 	struct mslsa_QueryInfoPolicy *param = arg;
57411337SWilliam.Krier@Sun.COM 	union mslsa_PolicyInfoResUnion *ru = &param->ru;
57511337SWilliam.Krier@Sun.COM 	int security_mode;
57611337SWilliam.Krier@Sun.COM 	DWORD status;
57711337SWilliam.Krier@Sun.COM 
57811337SWilliam.Krier@Sun.COM 	param->switch_value = param->info_class;
57911337SWilliam.Krier@Sun.COM 
58011337SWilliam.Krier@Sun.COM 	switch (param->info_class) {
58111337SWilliam.Krier@Sun.COM 	case MSLSA_POLICY_AUDIT_EVENTS_INFO:
58211337SWilliam.Krier@Sun.COM 		ru->audit_events.enabled = 0;
58311337SWilliam.Krier@Sun.COM 		ru->audit_events.count = 1;
58411337SWilliam.Krier@Sun.COM 		ru->audit_events.settings
58511337SWilliam.Krier@Sun.COM 		    = NDR_MALLOC(mxa, sizeof (DWORD));
58611337SWilliam.Krier@Sun.COM 		bzero(ru->audit_events.settings, sizeof (DWORD));
58711337SWilliam.Krier@Sun.COM 		status = NT_STATUS_SUCCESS;
58811337SWilliam.Krier@Sun.COM 		break;
58911337SWilliam.Krier@Sun.COM 
59011337SWilliam.Krier@Sun.COM 	case MSLSA_POLICY_PRIMARY_DOMAIN_INFO:
59111337SWilliam.Krier@Sun.COM 		status = lsarpc_s_PrimaryDomainInfo(&ru->pd_info, mxa);
59211337SWilliam.Krier@Sun.COM 		break;
59311337SWilliam.Krier@Sun.COM 
59411337SWilliam.Krier@Sun.COM 	case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO:
59511337SWilliam.Krier@Sun.COM 		status = lsarpc_s_AccountDomainInfo(&ru->ad_info, mxa);
59611337SWilliam.Krier@Sun.COM 		break;
59711337SWilliam.Krier@Sun.COM 
59811337SWilliam.Krier@Sun.COM 	case MSLSA_POLICY_SERVER_ROLE_INFO:
59911337SWilliam.Krier@Sun.COM 		security_mode = smb_config_get_secmode();
60011337SWilliam.Krier@Sun.COM 
60111337SWilliam.Krier@Sun.COM 		if (security_mode == SMB_SECMODE_DOMAIN)
60211337SWilliam.Krier@Sun.COM 			ru->server_role.role = LSA_ROLE_MEMBER_SERVER;
60311337SWilliam.Krier@Sun.COM 		else
60411337SWilliam.Krier@Sun.COM 			ru->server_role.role = LSA_ROLE_STANDALONE_SERVER;
60511337SWilliam.Krier@Sun.COM 
60611337SWilliam.Krier@Sun.COM 		ru->server_role.pad = 0;
60711337SWilliam.Krier@Sun.COM 		status = NT_STATUS_SUCCESS;
60811337SWilliam.Krier@Sun.COM 		break;
60911337SWilliam.Krier@Sun.COM 
61011337SWilliam.Krier@Sun.COM 	default:
61111337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_QueryInfoPolicy));
61211337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_INFO_CLASS);
61311337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
61411337SWilliam.Krier@Sun.COM 	}
61511337SWilliam.Krier@Sun.COM 
61611337SWilliam.Krier@Sun.COM 	if (status != NT_STATUS_SUCCESS)
61711337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(status);
61811337SWilliam.Krier@Sun.COM 	else
61911337SWilliam.Krier@Sun.COM 		param->status = NT_STATUS_SUCCESS;
62011337SWilliam.Krier@Sun.COM 	param->address = (DWORD)(uintptr_t)ru;
62111337SWilliam.Krier@Sun.COM 
62211337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
62311337SWilliam.Krier@Sun.COM }
62411337SWilliam.Krier@Sun.COM 
62511337SWilliam.Krier@Sun.COM 
62611337SWilliam.Krier@Sun.COM /*
62711337SWilliam.Krier@Sun.COM  * lsarpc_s_PrimaryDomainInfo
62811337SWilliam.Krier@Sun.COM  *
62911337SWilliam.Krier@Sun.COM  * Service primary domain policy queries.  In domain mode, return the
63011337SWilliam.Krier@Sun.COM  * primary domain name and SID.   In workgroup mode, return the local
63111337SWilliam.Krier@Sun.COM  * hostname and local domain SID.
63211337SWilliam.Krier@Sun.COM  *
63311337SWilliam.Krier@Sun.COM  * Note: info is zeroed on entry to ensure the SID and name do not
63411337SWilliam.Krier@Sun.COM  * contain spurious values if an error is returned.
63511337SWilliam.Krier@Sun.COM  */
63611337SWilliam.Krier@Sun.COM static DWORD
lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo * info,ndr_xa_t * mxa)63711337SWilliam.Krier@Sun.COM lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *info,
63811337SWilliam.Krier@Sun.COM     ndr_xa_t *mxa)
63911337SWilliam.Krier@Sun.COM {
64011337SWilliam.Krier@Sun.COM 	smb_domain_t di;
64111337SWilliam.Krier@Sun.COM 	boolean_t found;
64211337SWilliam.Krier@Sun.COM 	int rc;
64311337SWilliam.Krier@Sun.COM 
64411337SWilliam.Krier@Sun.COM 	bzero(info, sizeof (struct mslsa_PrimaryDomainInfo));
64511337SWilliam.Krier@Sun.COM 
64611337SWilliam.Krier@Sun.COM 	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
64711337SWilliam.Krier@Sun.COM 		found = smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di);
64811337SWilliam.Krier@Sun.COM 	else
64911337SWilliam.Krier@Sun.COM 		found = smb_domain_lookup_type(SMB_DOMAIN_PRIMARY, &di);
65011337SWilliam.Krier@Sun.COM 
65111337SWilliam.Krier@Sun.COM 	if (!found)
65211337SWilliam.Krier@Sun.COM 		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
65311337SWilliam.Krier@Sun.COM 
65411337SWilliam.Krier@Sun.COM 	rc = NDR_MSTRING(mxa, di.di_nbname, (ndr_mstring_t *)&info->name);
65511337SWilliam.Krier@Sun.COM 	info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, di.di_binsid);
65611337SWilliam.Krier@Sun.COM 
65711337SWilliam.Krier@Sun.COM 	if ((rc == -1) || (info->sid == NULL))
65811337SWilliam.Krier@Sun.COM 		return (NT_STATUS_NO_MEMORY);
65911337SWilliam.Krier@Sun.COM 
66011337SWilliam.Krier@Sun.COM 	return (NT_STATUS_SUCCESS);
66111337SWilliam.Krier@Sun.COM }
66211337SWilliam.Krier@Sun.COM 
66311337SWilliam.Krier@Sun.COM 
66411337SWilliam.Krier@Sun.COM /*
66511337SWilliam.Krier@Sun.COM  * lsarpc_s_AccountDomainInfo
66611337SWilliam.Krier@Sun.COM  *
66711337SWilliam.Krier@Sun.COM  * Service account domain policy queries.  We return our local domain
66811337SWilliam.Krier@Sun.COM  * information so that the client knows who to query for information
66911337SWilliam.Krier@Sun.COM  * on local names and SIDs.  The domain name is the local hostname.
67011337SWilliam.Krier@Sun.COM  *
67111337SWilliam.Krier@Sun.COM  * Note: info is zeroed on entry to ensure the SID and name do not
67211337SWilliam.Krier@Sun.COM  * contain spurious values if an error is returned.
67311337SWilliam.Krier@Sun.COM  */
67411337SWilliam.Krier@Sun.COM static DWORD
lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo * info,ndr_xa_t * mxa)67511337SWilliam.Krier@Sun.COM lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *info,
67611337SWilliam.Krier@Sun.COM     ndr_xa_t *mxa)
67711337SWilliam.Krier@Sun.COM {
67811337SWilliam.Krier@Sun.COM 	smb_domain_t di;
67911337SWilliam.Krier@Sun.COM 	int rc;
68011337SWilliam.Krier@Sun.COM 
68111337SWilliam.Krier@Sun.COM 	bzero(info, sizeof (struct mslsa_AccountDomainInfo));
68211337SWilliam.Krier@Sun.COM 
68311337SWilliam.Krier@Sun.COM 	if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di))
68411337SWilliam.Krier@Sun.COM 		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
68511337SWilliam.Krier@Sun.COM 
68611337SWilliam.Krier@Sun.COM 	rc = NDR_MSTRING(mxa, di.di_nbname, (ndr_mstring_t *)&info->name);
68711337SWilliam.Krier@Sun.COM 	info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, di.di_binsid);
68811337SWilliam.Krier@Sun.COM 
68911337SWilliam.Krier@Sun.COM 	if ((rc == -1) || (info->sid == NULL))
69011337SWilliam.Krier@Sun.COM 		return (NT_STATUS_NO_MEMORY);
69111337SWilliam.Krier@Sun.COM 
69211337SWilliam.Krier@Sun.COM 	return (NT_STATUS_SUCCESS);
69311337SWilliam.Krier@Sun.COM }
69411337SWilliam.Krier@Sun.COM 
69511337SWilliam.Krier@Sun.COM /*
69611337SWilliam.Krier@Sun.COM  * lsarpc_s_LookupNames
69711337SWilliam.Krier@Sun.COM  *
69811337SWilliam.Krier@Sun.COM  * This is the service side function for handling name lookup requests.
69911337SWilliam.Krier@Sun.COM  * Currently, we only support lookups of a single name. This is also a
70011337SWilliam.Krier@Sun.COM  * pass through interface so all we do is act as a proxy between the
70111337SWilliam.Krier@Sun.COM  * client and the DC.
70211337SWilliam.Krier@Sun.COM  */
70311337SWilliam.Krier@Sun.COM static int
lsarpc_s_LookupNames(void * arg,ndr_xa_t * mxa)70411337SWilliam.Krier@Sun.COM lsarpc_s_LookupNames(void *arg, ndr_xa_t *mxa)
70511337SWilliam.Krier@Sun.COM {
70611337SWilliam.Krier@Sun.COM 	struct mslsa_LookupNames *param = arg;
70711337SWilliam.Krier@Sun.COM 	struct mslsa_rid_entry *rids;
70811337SWilliam.Krier@Sun.COM 	struct mslsa_domain_table *domain_table;
70911337SWilliam.Krier@Sun.COM 	struct mslsa_domain_entry *domain_entry;
71011337SWilliam.Krier@Sun.COM 	smb_account_t account;
71111337SWilliam.Krier@Sun.COM 	uint32_t status;
71211337SWilliam.Krier@Sun.COM 	char *accname;
71311337SWilliam.Krier@Sun.COM 	int rc = 0;
71411337SWilliam.Krier@Sun.COM 
71511337SWilliam.Krier@Sun.COM 	if (param->name_table->n_entry != 1)
71611337SWilliam.Krier@Sun.COM 		return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED);
71711337SWilliam.Krier@Sun.COM 
71811337SWilliam.Krier@Sun.COM 	rids = NDR_NEW(mxa, struct mslsa_rid_entry);
71911337SWilliam.Krier@Sun.COM 	domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
72011337SWilliam.Krier@Sun.COM 	domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry);
72111337SWilliam.Krier@Sun.COM 
72211337SWilliam.Krier@Sun.COM 	if (rids == NULL || domain_table == NULL || domain_entry == NULL) {
72311337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_LookupNames));
72411337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
72511337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
72611337SWilliam.Krier@Sun.COM 	}
72711337SWilliam.Krier@Sun.COM 
72811337SWilliam.Krier@Sun.COM 	accname = (char *)param->name_table->names->str;
72911337SWilliam.Krier@Sun.COM 	status = lsa_lookup_name(accname, SidTypeUnknown, &account);
73011337SWilliam.Krier@Sun.COM 	if (status != NT_STATUS_SUCCESS) {
73111337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_LookupNames));
73211337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(status);
73311337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
73411337SWilliam.Krier@Sun.COM 	}
73511337SWilliam.Krier@Sun.COM 
73611337SWilliam.Krier@Sun.COM 	/*
73711337SWilliam.Krier@Sun.COM 	 * Set up the rid table.
73811337SWilliam.Krier@Sun.COM 	 */
73911337SWilliam.Krier@Sun.COM 	rids[0].sid_name_use = account.a_type;
74011337SWilliam.Krier@Sun.COM 	rids[0].rid = account.a_rid;
74111337SWilliam.Krier@Sun.COM 	rids[0].domain_index = 0;
74211337SWilliam.Krier@Sun.COM 	param->translated_sids.n_entry = 1;
74311337SWilliam.Krier@Sun.COM 	param->translated_sids.rids = rids;
74411337SWilliam.Krier@Sun.COM 
74511337SWilliam.Krier@Sun.COM 	/*
74611337SWilliam.Krier@Sun.COM 	 * Set up the domain table.
74711337SWilliam.Krier@Sun.COM 	 */
74811337SWilliam.Krier@Sun.COM 	domain_table->entries = domain_entry;
74911337SWilliam.Krier@Sun.COM 	domain_table->n_entry = 1;
75011337SWilliam.Krier@Sun.COM 	domain_table->max_n_entry = MLSVC_DOMAIN_MAX;
75111337SWilliam.Krier@Sun.COM 
75211337SWilliam.Krier@Sun.COM 	rc = NDR_MSTRING(mxa, account.a_domain,
75311337SWilliam.Krier@Sun.COM 	    (ndr_mstring_t *)&domain_entry->domain_name);
75411337SWilliam.Krier@Sun.COM 	domain_entry->domain_sid =
75511337SWilliam.Krier@Sun.COM 	    (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid);
75611337SWilliam.Krier@Sun.COM 
75711337SWilliam.Krier@Sun.COM 	if (rc == -1 || domain_entry->domain_sid == NULL) {
75811337SWilliam.Krier@Sun.COM 		smb_account_free(&account);
75911337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct mslsa_LookupNames));
76011337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
76111337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
76211337SWilliam.Krier@Sun.COM 	}
76311337SWilliam.Krier@Sun.COM 
76411337SWilliam.Krier@Sun.COM 	param->domain_table = domain_table;
76511337SWilliam.Krier@Sun.COM 	param->mapped_count = 1;
76611337SWilliam.Krier@Sun.COM 	param->status = NT_STATUS_SUCCESS;
76711337SWilliam.Krier@Sun.COM 
76811337SWilliam.Krier@Sun.COM 	smb_account_free(&account);
76911337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
77011337SWilliam.Krier@Sun.COM }
77111337SWilliam.Krier@Sun.COM 
77211337SWilliam.Krier@Sun.COM /*
77311337SWilliam.Krier@Sun.COM  * lsarpc_s_LookupSids
77411337SWilliam.Krier@Sun.COM  *
77511337SWilliam.Krier@Sun.COM  * This is the service side function for handling sid lookup requests.
77611337SWilliam.Krier@Sun.COM  * We have to set up both the name table and the domain table in the
77711337SWilliam.Krier@Sun.COM  * response. For each SID, we check for UNIX domain (local lookup) or
77811337SWilliam.Krier@Sun.COM  * NT domain (DC lookup) and call the appropriate lookup function. This
77911337SWilliam.Krier@Sun.COM  * should resolve the SID to a name. Then we need to update the domain
78011337SWilliam.Krier@Sun.COM  * table and make the name entry point at the appropriate domain table
78111337SWilliam.Krier@Sun.COM  * entry.
78211337SWilliam.Krier@Sun.COM  *
78311337SWilliam.Krier@Sun.COM  *
78411337SWilliam.Krier@Sun.COM  * This RPC should behave as if LookupOptions is LSA_LOOKUP_OPT_ALL and
78511337SWilliam.Krier@Sun.COM  * ClientRevision is LSA_CLIENT_REVISION_NT.
78611337SWilliam.Krier@Sun.COM  *
78711337SWilliam.Krier@Sun.COM  * On success return 0. Otherwise return an RPC specific error code.
78811337SWilliam.Krier@Sun.COM  */
789*13082SJoyce.McIntosh@Sun.COM 
79011337SWilliam.Krier@Sun.COM static int
lsarpc_s_LookupSids(void * arg,ndr_xa_t * mxa)79111337SWilliam.Krier@Sun.COM lsarpc_s_LookupSids(void *arg, ndr_xa_t *mxa)
79211337SWilliam.Krier@Sun.COM {
79311337SWilliam.Krier@Sun.COM 	struct mslsa_LookupSids *param = arg;
79411337SWilliam.Krier@Sun.COM 	struct mslsa_domain_table *domain_table;
79511337SWilliam.Krier@Sun.COM 	struct mslsa_domain_entry *domain_entry;
79611337SWilliam.Krier@Sun.COM 	struct mslsa_name_entry *names;
79711337SWilliam.Krier@Sun.COM 	struct mslsa_name_entry *name;
79811337SWilliam.Krier@Sun.COM 	smb_account_t account;
79911337SWilliam.Krier@Sun.COM 	smb_sid_t *sid;
80011337SWilliam.Krier@Sun.COM 	DWORD n_entry;
801*13082SJoyce.McIntosh@Sun.COM 	DWORD n_mapped;
802*13082SJoyce.McIntosh@Sun.COM 	char sidstr[SMB_SID_STRSZ];
80311337SWilliam.Krier@Sun.COM 	int result;
80411337SWilliam.Krier@Sun.COM 	int i;
80511337SWilliam.Krier@Sun.COM 
806*13082SJoyce.McIntosh@Sun.COM 	bzero(&account, sizeof (smb_account_t));
807*13082SJoyce.McIntosh@Sun.COM 	n_mapped = 0;
80811337SWilliam.Krier@Sun.COM 	n_entry = param->lup_sid_table.n_entry;
809*13082SJoyce.McIntosh@Sun.COM 
81011337SWilliam.Krier@Sun.COM 	names = NDR_NEWN(mxa, struct mslsa_name_entry, n_entry);
81111337SWilliam.Krier@Sun.COM 	domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
81211337SWilliam.Krier@Sun.COM 	domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry,
81311337SWilliam.Krier@Sun.COM 	    MLSVC_DOMAIN_MAX);
81411337SWilliam.Krier@Sun.COM 
815*13082SJoyce.McIntosh@Sun.COM 	if (names == NULL || domain_table == NULL || domain_entry == NULL)
816*13082SJoyce.McIntosh@Sun.COM 		goto lookup_sid_failed;
81711337SWilliam.Krier@Sun.COM 
81811337SWilliam.Krier@Sun.COM 	domain_table->entries = domain_entry;
81911337SWilliam.Krier@Sun.COM 	domain_table->n_entry = 0;
82011337SWilliam.Krier@Sun.COM 	domain_table->max_n_entry = MLSVC_DOMAIN_MAX;
82111337SWilliam.Krier@Sun.COM 
82211337SWilliam.Krier@Sun.COM 	name = names;
82311337SWilliam.Krier@Sun.COM 	for (i = 0; i < n_entry; ++i, name++) {
824*13082SJoyce.McIntosh@Sun.COM 		bzero(name, sizeof (struct mslsa_name_entry));
82511337SWilliam.Krier@Sun.COM 		sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid;
82611337SWilliam.Krier@Sun.COM 
82711337SWilliam.Krier@Sun.COM 		result = lsa_lookup_sid(sid, &account);
828*13082SJoyce.McIntosh@Sun.COM 		if ((result != NT_STATUS_SUCCESS) ||
829*13082SJoyce.McIntosh@Sun.COM 		    (account.a_name == NULL) || (*account.a_name == '\0')) {
830*13082SJoyce.McIntosh@Sun.COM 			account.a_type = SidTypeUnknown;
831*13082SJoyce.McIntosh@Sun.COM 			smb_sid_tostr(sid, sidstr);
83211337SWilliam.Krier@Sun.COM 
833*13082SJoyce.McIntosh@Sun.COM 			if (NDR_MSTRING(mxa, sidstr,
834*13082SJoyce.McIntosh@Sun.COM 			    (ndr_mstring_t *)&name->name) == -1)
835*13082SJoyce.McIntosh@Sun.COM 				goto lookup_sid_failed;
836*13082SJoyce.McIntosh@Sun.COM 
837*13082SJoyce.McIntosh@Sun.COM 		} else {
83811337SWilliam.Krier@Sun.COM 			if (NDR_MSTRING(mxa, account.a_name,
839*13082SJoyce.McIntosh@Sun.COM 			    (ndr_mstring_t *)&name->name) == -1)
84011337SWilliam.Krier@Sun.COM 				goto lookup_sid_failed;
841*13082SJoyce.McIntosh@Sun.COM 
842*13082SJoyce.McIntosh@Sun.COM 			++n_mapped;
84311337SWilliam.Krier@Sun.COM 		}
844*13082SJoyce.McIntosh@Sun.COM 
84511337SWilliam.Krier@Sun.COM 		name->sid_name_use = account.a_type;
84611337SWilliam.Krier@Sun.COM 
84711337SWilliam.Krier@Sun.COM 		result = lsarpc_s_UpdateDomainTable(mxa, &account,
84811337SWilliam.Krier@Sun.COM 		    domain_table, &name->domain_ix);
849*13082SJoyce.McIntosh@Sun.COM 		if (result == -1)
85011337SWilliam.Krier@Sun.COM 			goto lookup_sid_failed;
85111337SWilliam.Krier@Sun.COM 
85211337SWilliam.Krier@Sun.COM 		smb_account_free(&account);
85311337SWilliam.Krier@Sun.COM 	}
85411337SWilliam.Krier@Sun.COM 
85511337SWilliam.Krier@Sun.COM 	param->domain_table = domain_table;
85611337SWilliam.Krier@Sun.COM 	param->name_table.n_entry = n_entry;
85711337SWilliam.Krier@Sun.COM 	param->name_table.entries = names;
858*13082SJoyce.McIntosh@Sun.COM 	param->mapped_count = n_mapped;
859*13082SJoyce.McIntosh@Sun.COM 
860*13082SJoyce.McIntosh@Sun.COM 	if (n_mapped == n_entry)
861*13082SJoyce.McIntosh@Sun.COM 		param->status = NT_STATUS_SUCCESS;
862*13082SJoyce.McIntosh@Sun.COM 	else if (n_mapped == 0)
863*13082SJoyce.McIntosh@Sun.COM 		param->status = NT_STATUS_NONE_MAPPED;
864*13082SJoyce.McIntosh@Sun.COM 	else
865*13082SJoyce.McIntosh@Sun.COM 		param->status = NT_STATUS_SOME_NOT_MAPPED;
86611337SWilliam.Krier@Sun.COM 
86711337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
86811337SWilliam.Krier@Sun.COM 
86911337SWilliam.Krier@Sun.COM lookup_sid_failed:
87011337SWilliam.Krier@Sun.COM 	smb_account_free(&account);
871*13082SJoyce.McIntosh@Sun.COM 	bzero(param, sizeof (struct mslsa_LookupSids));
872*13082SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_FAULT_OUT_OF_MEMORY);
87311337SWilliam.Krier@Sun.COM }
87411337SWilliam.Krier@Sun.COM 
87511337SWilliam.Krier@Sun.COM /*
87611337SWilliam.Krier@Sun.COM  * lsarpc_s_UpdateDomainTable
87711337SWilliam.Krier@Sun.COM  *
87811337SWilliam.Krier@Sun.COM  * This routine is responsible for maintaining the domain table which
87911337SWilliam.Krier@Sun.COM  * will be returned from a SID lookup. Whenever a name is added to the
88011337SWilliam.Krier@Sun.COM  * name table, this function should be called with the corresponding
88111337SWilliam.Krier@Sun.COM  * domain name. If the domain information is not already in the table,
88211337SWilliam.Krier@Sun.COM  * it is added. On success return 0; Otherwise -1 is returned.
88311337SWilliam.Krier@Sun.COM  */
88411337SWilliam.Krier@Sun.COM static int
lsarpc_s_UpdateDomainTable(ndr_xa_t * mxa,smb_account_t * account,struct mslsa_domain_table * domain_table,DWORD * domain_idx)88511337SWilliam.Krier@Sun.COM lsarpc_s_UpdateDomainTable(ndr_xa_t *mxa,
88611337SWilliam.Krier@Sun.COM     smb_account_t *account, struct mslsa_domain_table *domain_table,
88711337SWilliam.Krier@Sun.COM     DWORD *domain_idx)
88811337SWilliam.Krier@Sun.COM {
88911337SWilliam.Krier@Sun.COM 	struct mslsa_domain_entry *dentry;
89011337SWilliam.Krier@Sun.COM 	DWORD n_entry;
89111337SWilliam.Krier@Sun.COM 	DWORD i;
89211337SWilliam.Krier@Sun.COM 	int rc;
89311337SWilliam.Krier@Sun.COM 
89411337SWilliam.Krier@Sun.COM 	if (account->a_type == SidTypeUnknown ||
89511337SWilliam.Krier@Sun.COM 	    account->a_type == SidTypeInvalid) {
89611337SWilliam.Krier@Sun.COM 		/*
89711337SWilliam.Krier@Sun.COM 		 * These types don't need to reference an entry in the
89811337SWilliam.Krier@Sun.COM 		 * domain table. So return -1.
89911337SWilliam.Krier@Sun.COM 		 */
90011337SWilliam.Krier@Sun.COM 		*domain_idx = (DWORD)-1;
90111337SWilliam.Krier@Sun.COM 		return (0);
90211337SWilliam.Krier@Sun.COM 	}
90311337SWilliam.Krier@Sun.COM 
90411337SWilliam.Krier@Sun.COM 	if ((dentry = domain_table->entries) == NULL)
90511337SWilliam.Krier@Sun.COM 		return (-1);
90611337SWilliam.Krier@Sun.COM 
90711337SWilliam.Krier@Sun.COM 	if ((n_entry = domain_table->n_entry) >= MLSVC_DOMAIN_MAX)
90811337SWilliam.Krier@Sun.COM 		return (-1);
90911337SWilliam.Krier@Sun.COM 
91011337SWilliam.Krier@Sun.COM 	for (i = 0; i < n_entry; ++i) {
91111337SWilliam.Krier@Sun.COM 		if (smb_sid_cmp((smb_sid_t *)dentry[i].domain_sid,
91211337SWilliam.Krier@Sun.COM 		    account->a_domsid)) {
91311337SWilliam.Krier@Sun.COM 			*domain_idx = i;
91411337SWilliam.Krier@Sun.COM 			return (0);
91511337SWilliam.Krier@Sun.COM 		}
91611337SWilliam.Krier@Sun.COM 	}
91711337SWilliam.Krier@Sun.COM 
91811337SWilliam.Krier@Sun.COM 	if (i == MLSVC_DOMAIN_MAX)
91911337SWilliam.Krier@Sun.COM 		return (-1);
92011337SWilliam.Krier@Sun.COM 
92111337SWilliam.Krier@Sun.COM 	rc = NDR_MSTRING(mxa, account->a_domain,
92211337SWilliam.Krier@Sun.COM 	    (ndr_mstring_t *)&dentry[i].domain_name);
92311337SWilliam.Krier@Sun.COM 	dentry[i].domain_sid =
92411337SWilliam.Krier@Sun.COM 	    (struct mslsa_sid *)NDR_SIDDUP(mxa, account->a_domsid);
92511337SWilliam.Krier@Sun.COM 
92611337SWilliam.Krier@Sun.COM 	if (rc == -1 || dentry[i].domain_sid == NULL)
92711337SWilliam.Krier@Sun.COM 		return (-1);
92811337SWilliam.Krier@Sun.COM 
92911337SWilliam.Krier@Sun.COM 	++domain_table->n_entry;
93011337SWilliam.Krier@Sun.COM 	*domain_idx = i;
93111337SWilliam.Krier@Sun.COM 	return (0);
93211337SWilliam.Krier@Sun.COM }
93311337SWilliam.Krier@Sun.COM 
93411337SWilliam.Krier@Sun.COM /*
93511337SWilliam.Krier@Sun.COM  * lsarpc_s_LookupSids2
93611337SWilliam.Krier@Sun.COM  *
93711337SWilliam.Krier@Sun.COM  * Other than the use of lsar_lookup_sids2 and lsar_name_entry2, this
93811337SWilliam.Krier@Sun.COM  * is identical to lsarpc_s_LookupSids.
93911337SWilliam.Krier@Sun.COM  *
94011337SWilliam.Krier@Sun.COM  * Ignore lookup_level, it is reserved and should be zero.
94111337SWilliam.Krier@Sun.COM  */
94211337SWilliam.Krier@Sun.COM static int
lsarpc_s_LookupSids2(void * arg,ndr_xa_t * mxa)94311337SWilliam.Krier@Sun.COM lsarpc_s_LookupSids2(void *arg, ndr_xa_t *mxa)
94411337SWilliam.Krier@Sun.COM {
94511337SWilliam.Krier@Sun.COM 	struct lsar_lookup_sids2 *param = arg;
94611337SWilliam.Krier@Sun.COM 	struct lsar_name_entry2 *names;
94711337SWilliam.Krier@Sun.COM 	struct lsar_name_entry2 *name;
94811337SWilliam.Krier@Sun.COM 	struct mslsa_domain_table *domain_table;
94911337SWilliam.Krier@Sun.COM 	struct mslsa_domain_entry *domain_entry;
95011337SWilliam.Krier@Sun.COM 	smb_account_t account;
95111337SWilliam.Krier@Sun.COM 	smb_sid_t *sid;
95211337SWilliam.Krier@Sun.COM 	DWORD n_entry;
953*13082SJoyce.McIntosh@Sun.COM 	DWORD n_mapped;
954*13082SJoyce.McIntosh@Sun.COM 	char sidstr[SMB_SID_STRSZ];
95511337SWilliam.Krier@Sun.COM 	int result;
95611337SWilliam.Krier@Sun.COM 	int i;
95711337SWilliam.Krier@Sun.COM 
958*13082SJoyce.McIntosh@Sun.COM 	bzero(&account, sizeof (smb_account_t));
959*13082SJoyce.McIntosh@Sun.COM 	n_mapped = 0;
96011337SWilliam.Krier@Sun.COM 	n_entry = param->lup_sid_table.n_entry;
961*13082SJoyce.McIntosh@Sun.COM 
96211337SWilliam.Krier@Sun.COM 	names = NDR_NEWN(mxa, struct lsar_name_entry2, n_entry);
96311337SWilliam.Krier@Sun.COM 	domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
96411337SWilliam.Krier@Sun.COM 	domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry,
96511337SWilliam.Krier@Sun.COM 	    MLSVC_DOMAIN_MAX);
96611337SWilliam.Krier@Sun.COM 
967*13082SJoyce.McIntosh@Sun.COM 	if (names == NULL || domain_table == NULL || domain_entry == NULL)
968*13082SJoyce.McIntosh@Sun.COM 		goto lookup_sid_failed;
96911337SWilliam.Krier@Sun.COM 
97011337SWilliam.Krier@Sun.COM 	domain_table->entries = domain_entry;
97111337SWilliam.Krier@Sun.COM 	domain_table->n_entry = 0;
97211337SWilliam.Krier@Sun.COM 	domain_table->max_n_entry = MLSVC_DOMAIN_MAX;
97311337SWilliam.Krier@Sun.COM 
97411337SWilliam.Krier@Sun.COM 	name = names;
97511337SWilliam.Krier@Sun.COM 	for (i = 0; i < n_entry; ++i, name++) {
97611337SWilliam.Krier@Sun.COM 		bzero(name, sizeof (struct lsar_name_entry2));
97711337SWilliam.Krier@Sun.COM 		sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid;
97811337SWilliam.Krier@Sun.COM 
97911337SWilliam.Krier@Sun.COM 		result = lsa_lookup_sid(sid, &account);
980*13082SJoyce.McIntosh@Sun.COM 		if ((result != NT_STATUS_SUCCESS) ||
981*13082SJoyce.McIntosh@Sun.COM 		    (account.a_name == NULL) || (*account.a_name == '\0')) {
982*13082SJoyce.McIntosh@Sun.COM 			account.a_type = SidTypeUnknown;
983*13082SJoyce.McIntosh@Sun.COM 			smb_sid_tostr(sid, sidstr);
98411337SWilliam.Krier@Sun.COM 
985*13082SJoyce.McIntosh@Sun.COM 			if (NDR_MSTRING(mxa, sidstr,
986*13082SJoyce.McIntosh@Sun.COM 			    (ndr_mstring_t *)&name->name) == -1)
987*13082SJoyce.McIntosh@Sun.COM 				goto lookup_sid_failed;
988*13082SJoyce.McIntosh@Sun.COM 
989*13082SJoyce.McIntosh@Sun.COM 		} else {
99011337SWilliam.Krier@Sun.COM 			if (NDR_MSTRING(mxa, account.a_name,
991*13082SJoyce.McIntosh@Sun.COM 			    (ndr_mstring_t *)&name->name) == -1)
99211337SWilliam.Krier@Sun.COM 				goto lookup_sid_failed;
993*13082SJoyce.McIntosh@Sun.COM 
994*13082SJoyce.McIntosh@Sun.COM 			++n_mapped;
99511337SWilliam.Krier@Sun.COM 		}
996*13082SJoyce.McIntosh@Sun.COM 
99711337SWilliam.Krier@Sun.COM 		name->sid_name_use = account.a_type;
99811337SWilliam.Krier@Sun.COM 
99911337SWilliam.Krier@Sun.COM 		result = lsarpc_s_UpdateDomainTable(mxa, &account,
100011337SWilliam.Krier@Sun.COM 		    domain_table, &name->domain_ix);
1001*13082SJoyce.McIntosh@Sun.COM 		if (result == -1)
100211337SWilliam.Krier@Sun.COM 			goto lookup_sid_failed;
100311337SWilliam.Krier@Sun.COM 
100411337SWilliam.Krier@Sun.COM 		smb_account_free(&account);
100511337SWilliam.Krier@Sun.COM 	}
100611337SWilliam.Krier@Sun.COM 
100711337SWilliam.Krier@Sun.COM 	param->domain_table = domain_table;
100811337SWilliam.Krier@Sun.COM 	param->name_table.n_entry = n_entry;
100911337SWilliam.Krier@Sun.COM 	param->name_table.entries = names;
1010*13082SJoyce.McIntosh@Sun.COM 	param->mapped_count = n_mapped;
1011*13082SJoyce.McIntosh@Sun.COM 
1012*13082SJoyce.McIntosh@Sun.COM 	if (n_mapped == n_entry)
1013*13082SJoyce.McIntosh@Sun.COM 		param->status = NT_STATUS_SUCCESS;
1014*13082SJoyce.McIntosh@Sun.COM 	else if (n_mapped == 0)
1015*13082SJoyce.McIntosh@Sun.COM 		param->status = NT_STATUS_NONE_MAPPED;
1016*13082SJoyce.McIntosh@Sun.COM 	else
1017*13082SJoyce.McIntosh@Sun.COM 		param->status = NT_STATUS_SOME_NOT_MAPPED;
101811337SWilliam.Krier@Sun.COM 
101911337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
102011337SWilliam.Krier@Sun.COM 
102111337SWilliam.Krier@Sun.COM lookup_sid_failed:
102211337SWilliam.Krier@Sun.COM 	smb_account_free(&account);
1023*13082SJoyce.McIntosh@Sun.COM 	bzero(param, sizeof (struct lsar_lookup_sids2));
1024*13082SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_FAULT_OUT_OF_MEMORY);
102511337SWilliam.Krier@Sun.COM }
102611337SWilliam.Krier@Sun.COM 
102711337SWilliam.Krier@Sun.COM /*
102811337SWilliam.Krier@Sun.COM  * LookupSids3 is only valid on domain controllers.
102911337SWilliam.Krier@Sun.COM  * Other servers must return NT_STATUS_INVALID_SERVER_STATE.
103011337SWilliam.Krier@Sun.COM  */
103111337SWilliam.Krier@Sun.COM /*ARGSUSED*/
103211337SWilliam.Krier@Sun.COM static int
lsarpc_s_LookupSids3(void * arg,ndr_xa_t * mxa)103311337SWilliam.Krier@Sun.COM lsarpc_s_LookupSids3(void *arg, ndr_xa_t *mxa)
103411337SWilliam.Krier@Sun.COM {
103511337SWilliam.Krier@Sun.COM 	struct lsar_lookup_sids3 *param = arg;
103611337SWilliam.Krier@Sun.COM 
103711337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct lsar_lookup_sids3));
103811337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_INVALID_SERVER_STATE);
103911337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
104011337SWilliam.Krier@Sun.COM }
104111337SWilliam.Krier@Sun.COM 
104211337SWilliam.Krier@Sun.COM /*
104311337SWilliam.Krier@Sun.COM  * lsarpc_s_LookupNames2
104411337SWilliam.Krier@Sun.COM  *
104511337SWilliam.Krier@Sun.COM  * Other than the use of lsar_LookupNames2 and lsar_rid_entry2, this
104611337SWilliam.Krier@Sun.COM  * is identical to lsarpc_s_LookupNames.
104711337SWilliam.Krier@Sun.COM  *
104811337SWilliam.Krier@Sun.COM  * If LookupOptions contains LSA_LOOKUP_OPT_LOCAL and LookupLevel is not
104911337SWilliam.Krier@Sun.COM  * LSA_LOOKUP_WKSTA, return STATUS_INVALID_PARAMETER.
105011337SWilliam.Krier@Sun.COM  */
105111337SWilliam.Krier@Sun.COM static int
lsarpc_s_LookupNames2(void * arg,ndr_xa_t * mxa)105211337SWilliam.Krier@Sun.COM lsarpc_s_LookupNames2(void *arg, ndr_xa_t *mxa)
105311337SWilliam.Krier@Sun.COM {
105411337SWilliam.Krier@Sun.COM 	struct lsar_LookupNames2 *param = arg;
105511337SWilliam.Krier@Sun.COM 	struct lsar_rid_entry2 *rids;
105611337SWilliam.Krier@Sun.COM 	struct mslsa_domain_table *domain_table;
105711337SWilliam.Krier@Sun.COM 	struct mslsa_domain_entry *domain_entry;
105811337SWilliam.Krier@Sun.COM 	smb_account_t account;
105911337SWilliam.Krier@Sun.COM 	uint32_t status;
106011337SWilliam.Krier@Sun.COM 	char *accname;
106111337SWilliam.Krier@Sun.COM 	int rc = 0;
106211337SWilliam.Krier@Sun.COM 
106311337SWilliam.Krier@Sun.COM 	if (param->name_table->n_entry != 1)
106411337SWilliam.Krier@Sun.COM 		return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED);
106511337SWilliam.Krier@Sun.COM 
106611337SWilliam.Krier@Sun.COM 	if ((param->lookup_options & LSA_LOOKUP_OPT_LOCAL) &&
106711337SWilliam.Krier@Sun.COM 	    param->lookup_level != LSA_LOOKUP_WKSTA) {
106811337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct lsar_LookupNames2));
106911337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
107011337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
107111337SWilliam.Krier@Sun.COM 	}
107211337SWilliam.Krier@Sun.COM 
107311337SWilliam.Krier@Sun.COM 	rids = NDR_NEW(mxa, struct lsar_rid_entry2);
107411337SWilliam.Krier@Sun.COM 	domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
107511337SWilliam.Krier@Sun.COM 	domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry);
107611337SWilliam.Krier@Sun.COM 
107711337SWilliam.Krier@Sun.COM 	if (rids == NULL || domain_table == NULL || domain_entry == NULL) {
107811337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct lsar_LookupNames2));
107911337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
108011337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
108111337SWilliam.Krier@Sun.COM 	}
108211337SWilliam.Krier@Sun.COM 
108311337SWilliam.Krier@Sun.COM 	accname = (char *)param->name_table->names->str;
108411337SWilliam.Krier@Sun.COM 	status = lsa_lookup_name(accname, SidTypeUnknown, &account);
108511337SWilliam.Krier@Sun.COM 	if (status != NT_STATUS_SUCCESS) {
108611337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct lsar_LookupNames2));
108711337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(status);
108811337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
108911337SWilliam.Krier@Sun.COM 	}
109011337SWilliam.Krier@Sun.COM 
109111337SWilliam.Krier@Sun.COM 	/*
109211337SWilliam.Krier@Sun.COM 	 * Set up the rid table.
109311337SWilliam.Krier@Sun.COM 	 */
109411337SWilliam.Krier@Sun.COM 	bzero(rids, sizeof (struct lsar_rid_entry2));
109511337SWilliam.Krier@Sun.COM 	rids[0].sid_name_use = account.a_type;
109611337SWilliam.Krier@Sun.COM 	rids[0].rid = account.a_rid;
109711337SWilliam.Krier@Sun.COM 	rids[0].domain_index = 0;
109811337SWilliam.Krier@Sun.COM 	param->translated_sids.n_entry = 1;
109911337SWilliam.Krier@Sun.COM 	param->translated_sids.rids = rids;
110011337SWilliam.Krier@Sun.COM 
110111337SWilliam.Krier@Sun.COM 	/*
110211337SWilliam.Krier@Sun.COM 	 * Set up the domain table.
110311337SWilliam.Krier@Sun.COM 	 */
110411337SWilliam.Krier@Sun.COM 	domain_table->entries = domain_entry;
110511337SWilliam.Krier@Sun.COM 	domain_table->n_entry = 1;
110611337SWilliam.Krier@Sun.COM 	domain_table->max_n_entry = MLSVC_DOMAIN_MAX;
110711337SWilliam.Krier@Sun.COM 
110811337SWilliam.Krier@Sun.COM 	rc = NDR_MSTRING(mxa, account.a_domain,
110911337SWilliam.Krier@Sun.COM 	    (ndr_mstring_t *)&domain_entry->domain_name);
111011337SWilliam.Krier@Sun.COM 
111111337SWilliam.Krier@Sun.COM 	domain_entry->domain_sid =
111211337SWilliam.Krier@Sun.COM 	    (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid);
111311337SWilliam.Krier@Sun.COM 
111411337SWilliam.Krier@Sun.COM 	if (rc == -1 || domain_entry->domain_sid == NULL) {
111511337SWilliam.Krier@Sun.COM 		smb_account_free(&account);
111611337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct lsar_LookupNames2));
111711337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
111811337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
111911337SWilliam.Krier@Sun.COM 	}
112011337SWilliam.Krier@Sun.COM 
112111337SWilliam.Krier@Sun.COM 	param->domain_table = domain_table;
112211337SWilliam.Krier@Sun.COM 	param->mapped_count = 1;
112311337SWilliam.Krier@Sun.COM 	param->status = NT_STATUS_SUCCESS;
112411337SWilliam.Krier@Sun.COM 
112511337SWilliam.Krier@Sun.COM 	smb_account_free(&account);
112611337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
112711337SWilliam.Krier@Sun.COM }
112811337SWilliam.Krier@Sun.COM 
112911337SWilliam.Krier@Sun.COM /*
113011337SWilliam.Krier@Sun.COM  * Other than the use of lsar_LookupNames2 and lsar_rid_entry2, this
113111337SWilliam.Krier@Sun.COM  * is identical to lsarpc_s_LookupNames.
113211337SWilliam.Krier@Sun.COM  *
113311337SWilliam.Krier@Sun.COM  * If LookupOptions contains LSA_LOOKUP_OPT_LOCAL and LookupLevel is not
113411337SWilliam.Krier@Sun.COM  * LSA_LOOKUP_WKSTA, return STATUS_INVALID_PARAMETER.
113511337SWilliam.Krier@Sun.COM  */
113611337SWilliam.Krier@Sun.COM static int
lsarpc_s_LookupNames3(void * arg,ndr_xa_t * mxa)113711337SWilliam.Krier@Sun.COM lsarpc_s_LookupNames3(void *arg, ndr_xa_t *mxa)
113811337SWilliam.Krier@Sun.COM {
113911337SWilliam.Krier@Sun.COM 	struct lsar_LookupNames3	*param = arg;
114011337SWilliam.Krier@Sun.COM 	struct lsar_translated_sid_ex2	*sids;
114111337SWilliam.Krier@Sun.COM 	struct mslsa_domain_table	*domain_table;
114211337SWilliam.Krier@Sun.COM 	struct mslsa_domain_entry	*domain_entry;
114311337SWilliam.Krier@Sun.COM 	smb_account_t			account;
114411337SWilliam.Krier@Sun.COM 	uint32_t			status;
114511337SWilliam.Krier@Sun.COM 	char				*accname;
114611337SWilliam.Krier@Sun.COM 	int				rc = 0;
114711337SWilliam.Krier@Sun.COM 
114811337SWilliam.Krier@Sun.COM 	if (param->name_table->n_entry != 1)
114911337SWilliam.Krier@Sun.COM 		return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED);
115011337SWilliam.Krier@Sun.COM 
115111337SWilliam.Krier@Sun.COM 	if ((param->lookup_options & LSA_LOOKUP_OPT_LOCAL) &&
115211337SWilliam.Krier@Sun.COM 	    param->lookup_level != LSA_LOOKUP_WKSTA) {
115311337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct lsar_LookupNames3));
115411337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
115511337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
115611337SWilliam.Krier@Sun.COM 	}
115711337SWilliam.Krier@Sun.COM 
115811337SWilliam.Krier@Sun.COM 	sids = NDR_NEW(mxa, struct lsar_translated_sid_ex2);
115911337SWilliam.Krier@Sun.COM 	domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
116011337SWilliam.Krier@Sun.COM 	domain_entry = NDR_NEW(mxa, struct mslsa_domain_entry);
116111337SWilliam.Krier@Sun.COM 
116211337SWilliam.Krier@Sun.COM 	if (sids == NULL || domain_table == NULL || domain_entry == NULL) {
116311337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct lsar_LookupNames3));
116411337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
116511337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
116611337SWilliam.Krier@Sun.COM 	}
116711337SWilliam.Krier@Sun.COM 
116811337SWilliam.Krier@Sun.COM 	accname = (char *)param->name_table->names->str;
116911337SWilliam.Krier@Sun.COM 	status = lsa_lookup_name(accname, SidTypeUnknown, &account);
117011337SWilliam.Krier@Sun.COM 	if (status != NT_STATUS_SUCCESS) {
117111337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct lsar_LookupNames3));
117211337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(status);
117311337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
117411337SWilliam.Krier@Sun.COM 	}
117511337SWilliam.Krier@Sun.COM 
117611337SWilliam.Krier@Sun.COM 	/*
117711337SWilliam.Krier@Sun.COM 	 * Set up the SID table.
117811337SWilliam.Krier@Sun.COM 	 */
117911337SWilliam.Krier@Sun.COM 	bzero(sids, sizeof (struct lsar_translated_sid_ex2));
118011337SWilliam.Krier@Sun.COM 	sids[0].sid_name_use = account.a_type;
118111337SWilliam.Krier@Sun.COM 	sids[0].sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_sid);
118211337SWilliam.Krier@Sun.COM 	sids[0].domain_index = 0;
118311337SWilliam.Krier@Sun.COM 	param->translated_sids.n_entry = 1;
118411337SWilliam.Krier@Sun.COM 	param->translated_sids.sids = sids;
118511337SWilliam.Krier@Sun.COM 
118611337SWilliam.Krier@Sun.COM 	/*
118711337SWilliam.Krier@Sun.COM 	 * Set up the domain table.
118811337SWilliam.Krier@Sun.COM 	 */
118911337SWilliam.Krier@Sun.COM 	domain_table->entries = domain_entry;
119011337SWilliam.Krier@Sun.COM 	domain_table->n_entry = 1;
119111337SWilliam.Krier@Sun.COM 	domain_table->max_n_entry = MLSVC_DOMAIN_MAX;
119211337SWilliam.Krier@Sun.COM 
119311337SWilliam.Krier@Sun.COM 	rc = NDR_MSTRING(mxa, account.a_domain,
119411337SWilliam.Krier@Sun.COM 	    (ndr_mstring_t *)&domain_entry->domain_name);
119511337SWilliam.Krier@Sun.COM 
119611337SWilliam.Krier@Sun.COM 	domain_entry->domain_sid =
119711337SWilliam.Krier@Sun.COM 	    (struct mslsa_sid *)NDR_SIDDUP(mxa, account.a_domsid);
119811337SWilliam.Krier@Sun.COM 
119911337SWilliam.Krier@Sun.COM 	if (rc == -1 || domain_entry->domain_sid == NULL) {
120011337SWilliam.Krier@Sun.COM 		smb_account_free(&account);
120111337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct lsar_LookupNames3));
120211337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
120311337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
120411337SWilliam.Krier@Sun.COM 	}
120511337SWilliam.Krier@Sun.COM 
120611337SWilliam.Krier@Sun.COM 	param->domain_table = domain_table;
120711337SWilliam.Krier@Sun.COM 	param->mapped_count = 1;
120811337SWilliam.Krier@Sun.COM 	param->status = NT_STATUS_SUCCESS;
120911337SWilliam.Krier@Sun.COM 
121011337SWilliam.Krier@Sun.COM 	smb_account_free(&account);
121111337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
121211337SWilliam.Krier@Sun.COM }
121311337SWilliam.Krier@Sun.COM 
121411337SWilliam.Krier@Sun.COM /*
121511337SWilliam.Krier@Sun.COM  * LookupNames4 is only valid on domain controllers.
121611337SWilliam.Krier@Sun.COM  * Other servers must return NT_STATUS_INVALID_SERVER_STATE.
121711337SWilliam.Krier@Sun.COM  */
121811337SWilliam.Krier@Sun.COM /*ARGSUSED*/
121911337SWilliam.Krier@Sun.COM static int
lsarpc_s_LookupNames4(void * arg,ndr_xa_t * mxa)122011337SWilliam.Krier@Sun.COM lsarpc_s_LookupNames4(void *arg, ndr_xa_t *mxa)
122111337SWilliam.Krier@Sun.COM {
122211337SWilliam.Krier@Sun.COM 	struct lsar_LookupNames4 *param = arg;
122311337SWilliam.Krier@Sun.COM 
122411337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct lsar_LookupNames4));
122511337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_INVALID_SERVER_STATE);
122611337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
122711337SWilliam.Krier@Sun.COM }
122811337SWilliam.Krier@Sun.COM 
122911337SWilliam.Krier@Sun.COM /*
123011337SWilliam.Krier@Sun.COM  * There is a bug in the way that ndrgen and the marshalling code handles
123111337SWilliam.Krier@Sun.COM  * unions so we need to fix some of the data offsets at runtime. The
123211337SWilliam.Krier@Sun.COM  * following macros and the fixup functions handle the corrections.
123311337SWilliam.Krier@Sun.COM  */
123411337SWilliam.Krier@Sun.COM 
123511337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(mslsa_PolicyInfoResUnion);
123611337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(mslsa_PolicyInfoRes);
123711337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(mslsa_QueryInfoPolicy);
123811337SWilliam.Krier@Sun.COM void
fixup_mslsa_QueryInfoPolicy(struct mslsa_QueryInfoPolicy * val)123911337SWilliam.Krier@Sun.COM fixup_mslsa_QueryInfoPolicy(struct mslsa_QueryInfoPolicy *val)
124011337SWilliam.Krier@Sun.COM {
124111337SWilliam.Krier@Sun.COM 	unsigned short size1 = 0;
124211337SWilliam.Krier@Sun.COM 	unsigned short size2 = 0;
124311337SWilliam.Krier@Sun.COM 	unsigned short size3 = 0;
124411337SWilliam.Krier@Sun.COM 
124511337SWilliam.Krier@Sun.COM 	switch (val->info_class) {
124611337SWilliam.Krier@Sun.COM 		case MSLSA_POLICY_AUDIT_EVENTS_INFO:
124711337SWilliam.Krier@Sun.COM 			size1 = sizeof (struct mslsa_AuditEventsInfo);
124811337SWilliam.Krier@Sun.COM 			break;
124911337SWilliam.Krier@Sun.COM 
125011337SWilliam.Krier@Sun.COM 		case MSLSA_POLICY_PRIMARY_DOMAIN_INFO:
125111337SWilliam.Krier@Sun.COM 			size1 = sizeof (struct mslsa_PrimaryDomainInfo);
125211337SWilliam.Krier@Sun.COM 			break;
125311337SWilliam.Krier@Sun.COM 
125411337SWilliam.Krier@Sun.COM 		case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO:
125511337SWilliam.Krier@Sun.COM 			size1 = sizeof (struct mslsa_AccountDomainInfo);
125611337SWilliam.Krier@Sun.COM 			break;
125711337SWilliam.Krier@Sun.COM 
125811337SWilliam.Krier@Sun.COM 		case MSLSA_POLICY_SERVER_ROLE_INFO:
125911337SWilliam.Krier@Sun.COM 			size1 = sizeof (struct mslsa_ServerRoleInfo);
126011337SWilliam.Krier@Sun.COM 			break;
126111337SWilliam.Krier@Sun.COM 
126211337SWilliam.Krier@Sun.COM 		case MSLSA_POLICY_DNS_DOMAIN_INFO:
126311337SWilliam.Krier@Sun.COM 			size1 = sizeof (struct mslsa_DnsDomainInfo);
126411337SWilliam.Krier@Sun.COM 			break;
126511337SWilliam.Krier@Sun.COM 
126611337SWilliam.Krier@Sun.COM 		default:
126711337SWilliam.Krier@Sun.COM 			return;
126811337SWilliam.Krier@Sun.COM 	};
126911337SWilliam.Krier@Sun.COM 
127011337SWilliam.Krier@Sun.COM 	size2 = size1 + (2 * sizeof (DWORD));
127111337SWilliam.Krier@Sun.COM 	size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
127211337SWilliam.Krier@Sun.COM 
127311337SWilliam.Krier@Sun.COM 	FIXUP_PDU_SIZE(mslsa_PolicyInfoResUnion, size1);
127411337SWilliam.Krier@Sun.COM 	FIXUP_PDU_SIZE(mslsa_PolicyInfoRes, size2);
127511337SWilliam.Krier@Sun.COM 	FIXUP_PDU_SIZE(mslsa_QueryInfoPolicy, size3);
127611337SWilliam.Krier@Sun.COM }
1277