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