1da6c28aaSamw /*
2da6c28aaSamw * CDDL HEADER START
3da6c28aaSamw *
4da6c28aaSamw * The contents of this file are subject to the terms of the
5da6c28aaSamw * Common Development and Distribution License (the "License").
6da6c28aaSamw * You may not use this file except in compliance with the License.
7da6c28aaSamw *
8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw * See the License for the specific language governing permissions
11da6c28aaSamw * and limitations under the License.
12da6c28aaSamw *
13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw *
19da6c28aaSamw * CDDL HEADER END
20da6c28aaSamw */
21148c5f43SAlan Wright
22da6c28aaSamw /*
23c5866007SKeyur Desai * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24*9242c919SMatt Barden * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
25da6c28aaSamw */
26da6c28aaSamw
27da6c28aaSamw /*
28fe1c642dSBill Krier * Security Accounts Manager RPC (SAMR) server-side interface.
29fe1c642dSBill Krier *
30fe1c642dSBill Krier * The SAM is a hierarchical database:
31fe1c642dSBill Krier * - If you want to talk to the SAM you need a SAM handle.
32fe1c642dSBill Krier * - If you want to work with a domain, use the SAM handle.
33fe1c642dSBill Krier * to obtain a domain handle.
34fe1c642dSBill Krier * - Use domain handles to obtain user handles etc.
35da6c28aaSamw */
36da6c28aaSamw
37da6c28aaSamw #include <strings.h>
38da6c28aaSamw #include <unistd.h>
39da6c28aaSamw #include <netdb.h>
403db3f65cSamw #include <assert.h>
41c5866007SKeyur Desai #include <grp.h>
423299f39fSGordon Ross #include <libmlrpc/libmlrpc.h>
43da6c28aaSamw #include <smbsrv/libsmb.h>
446537f381Sas #include <smbsrv/libmlsvc.h>
45da6c28aaSamw #include <smbsrv/smbinfo.h>
46da6c28aaSamw #include <smbsrv/nmpipes.h>
47da6c28aaSamw #include <smbsrv/ndl/samrpc.ndl>
488d7e4166Sjose borrego #include <samlib.h>
49da6c28aaSamw
50da6c28aaSamw /*
51dc20a302Sas * The keys associated with the various handles dispensed by the SAMR
52dc20a302Sas * server. These keys can be used to validate client activity.
53dc20a302Sas * These values are never passed over the wire so security shouldn't
54dc20a302Sas * be an issue.
55da6c28aaSamw */
56dc20a302Sas typedef enum {
57dc20a302Sas SAMR_KEY_NULL = 0,
58dc20a302Sas SAMR_KEY_CONNECT,
59dc20a302Sas SAMR_KEY_DOMAIN,
60dc20a302Sas SAMR_KEY_USER,
61dc20a302Sas SAMR_KEY_GROUP,
62dc20a302Sas SAMR_KEY_ALIAS
63dc20a302Sas } samr_key_t;
64dc20a302Sas
65dc20a302Sas typedef struct samr_keydata {
66dc20a302Sas samr_key_t kd_key;
67a0aa776eSAlan Wright smb_domain_type_t kd_type;
68dc20a302Sas DWORD kd_rid;
69dc20a302Sas } samr_keydata_t;
70dc20a302Sas
713db3f65cSamw /*
723db3f65cSamw * DomainDisplayUser All user objects (or those derived from user) with
73*9242c919SMatt Barden * userAccountControl containing the UF_NORMAL_ACCOUNT bit.
743db3f65cSamw *
753db3f65cSamw * DomainDisplayMachine All user objects (or those derived from user) with
76*9242c919SMatt Barden * userAccountControl containing the
77*9242c919SMatt Barden * UF_WORKSTATION_TRUST_ACCOUNT or UF_SERVER_TRUST_ACCOUNT
78*9242c919SMatt Barden * bit.
793db3f65cSamw *
803db3f65cSamw * DomainDisplayGroup All group objects (or those derived from group) with
81*9242c919SMatt Barden * groupType equal to GROUP_TYPE_SECURITY_UNIVERSAL or
82*9242c919SMatt Barden * GROUP_TYPE_SECURITY_ACCOUNT.
833db3f65cSamw *
843db3f65cSamw * DomainDisplayOemUser Same as DomainDisplayUser with OEM strings
853db3f65cSamw *
863db3f65cSamw * DomainDisplayOemGroup Same as DomainDisplayGroup with OEM strings
873db3f65cSamw */
883db3f65cSamw typedef enum {
893db3f65cSamw DomainDisplayUser = 1,
903db3f65cSamw DomainDisplayMachine,
913db3f65cSamw DomainDispalyGroup,
923db3f65cSamw DomainDisplayOemUser,
933db3f65cSamw DomainDisplayOemGroup
943db3f65cSamw } samr_displvl_t;
953db3f65cSamw
963db3f65cSamw #define SAMR_VALID_DISPLEVEL(lvl) \
973db3f65cSamw (((lvl) >= DomainDisplayUser) && ((lvl) <= DomainDisplayOemGroup))
983db3f65cSamw
993db3f65cSamw #define SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser)
1003db3f65cSamw
101a0aa776eSAlan Wright static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t,
102dc20a302Sas DWORD);
103dc20a302Sas static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *);
104dc20a302Sas static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t);
105*9242c919SMatt Barden static ndr_handle_t *samr_hdlookup_any(ndr_xa_t *, ndr_hdid_t *);
1068d7e4166Sjose borrego static int samr_call_stub(ndr_xa_t *mxa);
107da6c28aaSamw static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *,
1088d7e4166Sjose borrego ndr_xa_t *);
109da6c28aaSamw
1108d7e4166Sjose borrego static ndr_stub_table_t samr_stub_table[];
111da6c28aaSamw
1128d7e4166Sjose borrego static ndr_service_t samr_service = {
113da6c28aaSamw "SAMR", /* name */
114da6c28aaSamw "Security Accounts Manager", /* desc */
115da6c28aaSamw "\\samr", /* endpoint */
116da6c28aaSamw PIPE_LSASS, /* sec_addr_port */
1178d7e4166Sjose borrego "12345778-1234-abcd-ef00-0123456789ac", 1, /* abstract */
1188d7e4166Sjose borrego NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */
119da6c28aaSamw 0, /* no bind_instance_size */
12055bf511dSas NULL, /* no bind_req() */
12155bf511dSas NULL, /* no unbind_and_close() */
12255bf511dSas samr_call_stub, /* call_stub() */
123da6c28aaSamw &TYPEINFO(samr_interface), /* interface ti */
124da6c28aaSamw samr_stub_table /* stub_table */
125da6c28aaSamw };
126da6c28aaSamw
127da6c28aaSamw /*
128da6c28aaSamw * samr_initialize
129da6c28aaSamw *
130da6c28aaSamw * This function registers the SAM RPC interface with the RPC runtime
131da6c28aaSamw * library. It must be called in order to use either the client side
132da6c28aaSamw * or the server side functions.
133da6c28aaSamw */
134da6c28aaSamw void
samr_initialize(void)135da6c28aaSamw samr_initialize(void)
136da6c28aaSamw {
1378d7e4166Sjose borrego (void) ndr_svc_register(&samr_service);
138da6c28aaSamw }
139da6c28aaSamw
14055bf511dSas /*
14155bf511dSas * Custom call_stub to set the stream string policy.
14255bf511dSas */
14355bf511dSas static int
samr_call_stub(ndr_xa_t * mxa)1448d7e4166Sjose borrego samr_call_stub(ndr_xa_t *mxa)
14555bf511dSas {
1468d7e4166Sjose borrego NDS_SETF(&mxa->send_nds, NDS_F_NOTERM);
1478d7e4166Sjose borrego NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM);
14855bf511dSas
1498d7e4166Sjose borrego return (ndr_generic_call_stub(mxa));
15055bf511dSas }
15155bf511dSas
152dc20a302Sas /*
153dc20a302Sas * Handle allocation wrapper to setup the local context.
154dc20a302Sas */
155dc20a302Sas static ndr_hdid_t *
samr_hdalloc(ndr_xa_t * mxa,samr_key_t key,smb_domain_type_t domain_type,DWORD rid)156a0aa776eSAlan Wright samr_hdalloc(ndr_xa_t *mxa, samr_key_t key, smb_domain_type_t domain_type,
157dc20a302Sas DWORD rid)
158dc20a302Sas {
1599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_handle_t *hd;
1609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_hdid_t *id;
1619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States samr_keydata_t *data;
162dc20a302Sas
163dc20a302Sas if ((data = malloc(sizeof (samr_keydata_t))) == NULL)
164dc20a302Sas return (NULL);
165dc20a302Sas
166dc20a302Sas data->kd_key = key;
167dc20a302Sas data->kd_type = domain_type;
168dc20a302Sas data->kd_rid = rid;
169dc20a302Sas
1709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((id = ndr_hdalloc(mxa, data)) == NULL) {
1719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States free(data);
1729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NULL);
1739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
1759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((hd = ndr_hdlookup(mxa, id)) != NULL)
1769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States hd->nh_data_free = free;
1779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
1789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (id);
179dc20a302Sas }
180dc20a302Sas
181dc20a302Sas /*
182dc20a302Sas * Handle deallocation wrapper to free the local context.
183dc20a302Sas */
184dc20a302Sas static void
samr_hdfree(ndr_xa_t * mxa,ndr_hdid_t * id)185dc20a302Sas samr_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id)
186dc20a302Sas {
187dc20a302Sas ndr_handle_t *hd;
188dc20a302Sas
189dc20a302Sas if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
190dc20a302Sas free(hd->nh_data);
1919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States hd->nh_data = NULL;
192dc20a302Sas ndr_hdfree(mxa, id);
193dc20a302Sas }
194dc20a302Sas }
195dc20a302Sas
196dc20a302Sas /*
197dc20a302Sas * Handle lookup wrapper to validate the local context.
198dc20a302Sas */
199dc20a302Sas static ndr_handle_t *
samr_hdlookup(ndr_xa_t * mxa,ndr_hdid_t * id,samr_key_t key)200dc20a302Sas samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key)
201dc20a302Sas {
202dc20a302Sas ndr_handle_t *hd;
203dc20a302Sas samr_keydata_t *data;
204dc20a302Sas
205dc20a302Sas if ((hd = ndr_hdlookup(mxa, id)) == NULL)
206dc20a302Sas return (NULL);
207dc20a302Sas
208dc20a302Sas if ((data = (samr_keydata_t *)hd->nh_data) == NULL)
209dc20a302Sas return (NULL);
210dc20a302Sas
211dc20a302Sas if (data->kd_key != key)
212dc20a302Sas return (NULL);
213dc20a302Sas
214dc20a302Sas return (hd);
215dc20a302Sas }
216dc20a302Sas
217*9242c919SMatt Barden /*
218*9242c919SMatt Barden * Handle lookup wrapper to validate the local context,
219*9242c919SMatt Barden * but don't limit to one type.
220*9242c919SMatt Barden */
221*9242c919SMatt Barden static ndr_handle_t *
samr_hdlookup_any(ndr_xa_t * mxa,ndr_hdid_t * id)222*9242c919SMatt Barden samr_hdlookup_any(ndr_xa_t *mxa, ndr_hdid_t *id)
223*9242c919SMatt Barden {
224*9242c919SMatt Barden ndr_handle_t *hd;
225*9242c919SMatt Barden
226*9242c919SMatt Barden if ((hd = ndr_hdlookup(mxa, id)) == NULL)
227*9242c919SMatt Barden return (NULL);
228*9242c919SMatt Barden
229*9242c919SMatt Barden if (hd->nh_data == NULL)
230*9242c919SMatt Barden return (NULL);
231*9242c919SMatt Barden
232*9242c919SMatt Barden return (hd);
233*9242c919SMatt Barden }
234*9242c919SMatt Barden
235da6c28aaSamw /*
236cb174861Sjoyce mcintosh * samr_s_Connect
237da6c28aaSamw *
238da6c28aaSamw * This is a request to connect to the local SAM database. We don't
239da6c28aaSamw * support any form of update request and our database doesn't
240da6c28aaSamw * contain any private information, so there is little point in
241da6c28aaSamw * doing any access access checking here.
242da6c28aaSamw *
243da6c28aaSamw * Return a handle for use with subsequent SAM requests.
244da6c28aaSamw */
245da6c28aaSamw static int
samr_s_Connect(void * arg,ndr_xa_t * mxa)246cb174861Sjoyce mcintosh samr_s_Connect(void *arg, ndr_xa_t *mxa)
247da6c28aaSamw {
248cb174861Sjoyce mcintosh struct samr_Connect *param = arg;
249dc20a302Sas ndr_hdid_t *id;
250da6c28aaSamw
251a0aa776eSAlan Wright id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
252dc20a302Sas if (id) {
253dc20a302Sas bcopy(id, ¶m->handle, sizeof (samr_handle_t));
254dc20a302Sas param->status = 0;
255dc20a302Sas } else {
256dc20a302Sas bzero(¶m->handle, sizeof (samr_handle_t));
257dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
258dc20a302Sas }
259da6c28aaSamw
2608d7e4166Sjose borrego return (NDR_DRC_OK);
261da6c28aaSamw }
262da6c28aaSamw
263da6c28aaSamw /*
264da6c28aaSamw * samr_s_CloseHandle
265da6c28aaSamw *
266dc20a302Sas * Close the SAM interface specified by the handle.
267da6c28aaSamw * Free the handle and zero out the result handle for the client.
268da6c28aaSamw */
269da6c28aaSamw static int
samr_s_CloseHandle(void * arg,ndr_xa_t * mxa)2708d7e4166Sjose borrego samr_s_CloseHandle(void *arg, ndr_xa_t *mxa)
271da6c28aaSamw {
272da6c28aaSamw struct samr_CloseHandle *param = arg;
273dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
274da6c28aaSamw
275dc20a302Sas samr_hdfree(mxa, id);
276da6c28aaSamw
277da6c28aaSamw bzero(¶m->result_handle, sizeof (samr_handle_t));
278da6c28aaSamw param->status = 0;
2798d7e4166Sjose borrego return (NDR_DRC_OK);
280da6c28aaSamw }
281da6c28aaSamw
282*9242c919SMatt Barden /*
283*9242c919SMatt Barden * samr_s_QuerySecObject
284*9242c919SMatt Barden */
285*9242c919SMatt Barden static int
samr_s_QuerySecObject(void * arg,ndr_xa_t * mxa)286*9242c919SMatt Barden samr_s_QuerySecObject(void *arg, ndr_xa_t *mxa)
287*9242c919SMatt Barden {
288*9242c919SMatt Barden struct samr_QuerySecObject *param = arg;
289*9242c919SMatt Barden ndr_hdid_t *id;
290*9242c919SMatt Barden uint32_t status;
291*9242c919SMatt Barden struct samr_sec_desc *sd;
292*9242c919SMatt Barden
293*9242c919SMatt Barden id = (ndr_hdid_t *)¶m->obj_handle;
294*9242c919SMatt Barden if (samr_hdlookup_any(mxa, id) == NULL) {
295*9242c919SMatt Barden status = NT_STATUS_INVALID_HANDLE;
296*9242c919SMatt Barden goto QuerySecObjectError;
297*9242c919SMatt Barden }
298*9242c919SMatt Barden
299*9242c919SMatt Barden param->sd = NDR_MALLOC(mxa, sizeof (samr_sd_t));
300*9242c919SMatt Barden if (param->sd == NULL) {
301*9242c919SMatt Barden status = NT_STATUS_NO_MEMORY;
302*9242c919SMatt Barden goto QuerySecObjectError;
303*9242c919SMatt Barden }
304*9242c919SMatt Barden param->sd->length = sizeof (struct samr_sec_desc);
305*9242c919SMatt Barden
306*9242c919SMatt Barden sd = NDR_MALLOC(mxa, param->sd->length);
307*9242c919SMatt Barden if (sd == NULL) {
308*9242c919SMatt Barden status = NT_STATUS_NO_MEMORY;
309*9242c919SMatt Barden goto QuerySecObjectError;
310*9242c919SMatt Barden }
311*9242c919SMatt Barden bzero(sd, param->sd->length);
312*9242c919SMatt Barden sd->Revision = 1;
313*9242c919SMatt Barden sd->Control = SE_SELF_RELATIVE;
314*9242c919SMatt Barden
315*9242c919SMatt Barden param->sd->data = (void *)sd;
316*9242c919SMatt Barden param->status = NT_STATUS_SUCCESS;
317*9242c919SMatt Barden return (NDR_DRC_OK);
318*9242c919SMatt Barden
319*9242c919SMatt Barden QuerySecObjectError:
320*9242c919SMatt Barden bzero(param, sizeof (struct samr_QuerySecObject));
321*9242c919SMatt Barden param->status = NT_SC_ERROR(status);
322*9242c919SMatt Barden return (NDR_DRC_OK);
323*9242c919SMatt Barden }
324*9242c919SMatt Barden
325da6c28aaSamw /*
326da6c28aaSamw * samr_s_LookupDomain
327da6c28aaSamw *
328da6c28aaSamw * This is a request to map a domain name to a domain SID. We can map
329da6c28aaSamw * the primary domain name, our local domain name (hostname) and the
330da6c28aaSamw * builtin domain names to the appropriate SID. Anything else will be
331da6c28aaSamw * rejected.
332da6c28aaSamw */
333da6c28aaSamw static int
samr_s_LookupDomain(void * arg,ndr_xa_t * mxa)3348d7e4166Sjose borrego samr_s_LookupDomain(void *arg, ndr_xa_t *mxa)
335da6c28aaSamw {
336da6c28aaSamw struct samr_LookupDomain *param = arg;
337da6c28aaSamw char *domain_name;
338a0aa776eSAlan Wright smb_domain_t di;
339da6c28aaSamw
340da6c28aaSamw if ((domain_name = (char *)param->domain_name.str) == NULL) {
341da6c28aaSamw bzero(param, sizeof (struct samr_LookupDomain));
342da6c28aaSamw param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
3438d7e4166Sjose borrego return (NDR_DRC_OK);
344da6c28aaSamw }
345da6c28aaSamw
346a0aa776eSAlan Wright if (!smb_domain_lookup_name(domain_name, &di)) {
34729bd2886SAlan Wright bzero(param, sizeof (struct samr_LookupDomain));
34829bd2886SAlan Wright param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_DOMAIN);
34929bd2886SAlan Wright return (NDR_DRC_OK);
350da6c28aaSamw }
351da6c28aaSamw
35229bd2886SAlan Wright param->sid = (struct samr_sid *)NDR_SIDDUP(mxa, di.di_binsid);
35329bd2886SAlan Wright if (param->sid == NULL) {
35429bd2886SAlan Wright bzero(param, sizeof (struct samr_LookupDomain));
35529bd2886SAlan Wright param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
35629bd2886SAlan Wright return (NDR_DRC_OK);
357da6c28aaSamw }
358da6c28aaSamw
35929bd2886SAlan Wright param->status = NT_STATUS_SUCCESS;
3608d7e4166Sjose borrego return (NDR_DRC_OK);
361da6c28aaSamw }
362da6c28aaSamw
363da6c28aaSamw /*
364da6c28aaSamw * samr_s_EnumLocalDomains
365da6c28aaSamw *
366da6c28aaSamw * This is a request for the local domains supported by this server.
367da6c28aaSamw * All we do here is validate the handle and set the status. The real
368da6c28aaSamw * work is done in samr_s_enum_local_domains.
369da6c28aaSamw */
370da6c28aaSamw static int
samr_s_EnumLocalDomains(void * arg,ndr_xa_t * mxa)3718d7e4166Sjose borrego samr_s_EnumLocalDomains(void *arg, ndr_xa_t *mxa)
372da6c28aaSamw {
373da6c28aaSamw struct samr_EnumLocalDomain *param = arg;
374dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
375da6c28aaSamw DWORD status;
376da6c28aaSamw
377dc20a302Sas if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL)
378da6c28aaSamw status = NT_STATUS_ACCESS_DENIED;
379da6c28aaSamw else
380da6c28aaSamw status = samr_s_enum_local_domains(param, mxa);
381da6c28aaSamw
382da6c28aaSamw if (status == NT_STATUS_SUCCESS) {
383da6c28aaSamw param->enum_context = param->info->entries_read;
384da6c28aaSamw param->total_entries = param->info->entries_read;
385da6c28aaSamw param->status = NT_STATUS_SUCCESS;
386da6c28aaSamw } else {
387da6c28aaSamw bzero(param, sizeof (struct samr_EnumLocalDomain));
388da6c28aaSamw param->status = NT_SC_ERROR(status);
389da6c28aaSamw }
390da6c28aaSamw
3918d7e4166Sjose borrego return (NDR_DRC_OK);
392da6c28aaSamw }
393da6c28aaSamw
394da6c28aaSamw
395da6c28aaSamw /*
396da6c28aaSamw * samr_s_enum_local_domains
397da6c28aaSamw *
398da6c28aaSamw * This function should only be called via samr_s_EnumLocalDomains to
399da6c28aaSamw * ensure that the appropriate validation is performed. We will answer
400da6c28aaSamw * queries about two domains: the local domain, synonymous with the
401da6c28aaSamw * local hostname, and the BUILTIN domain. So we return these two
402da6c28aaSamw * strings.
403da6c28aaSamw *
404da6c28aaSamw * Returns NT status values.
405da6c28aaSamw */
406da6c28aaSamw static DWORD
samr_s_enum_local_domains(struct samr_EnumLocalDomain * param,ndr_xa_t * mxa)407da6c28aaSamw samr_s_enum_local_domains(struct samr_EnumLocalDomain *param,
4088d7e4166Sjose borrego ndr_xa_t *mxa)
409da6c28aaSamw {
410da6c28aaSamw struct samr_LocalDomainInfo *info;
411da6c28aaSamw struct samr_LocalDomainEntry *entry;
412da6c28aaSamw char *hostname;
413da6c28aaSamw
4148d7e4166Sjose borrego hostname = NDR_MALLOC(mxa, NETBIOS_NAME_SZ);
415da6c28aaSamw if (hostname == NULL)
416da6c28aaSamw return (NT_STATUS_NO_MEMORY);
417da6c28aaSamw
418b89a8333Snatalie li - Sun Microsystems - Irvine United States if (smb_getnetbiosname(hostname, NETBIOS_NAME_SZ) != 0)
419da6c28aaSamw return (NT_STATUS_NO_MEMORY);
420da6c28aaSamw
4218d7e4166Sjose borrego entry = NDR_NEWN(mxa, struct samr_LocalDomainEntry, 2);
422da6c28aaSamw if (entry == NULL)
423da6c28aaSamw return (NT_STATUS_NO_MEMORY);
424da6c28aaSamw
425da6c28aaSamw bzero(entry, (sizeof (struct samr_LocalDomainEntry) * 2));
4268d7e4166Sjose borrego (void) NDR_MSTRING(mxa, hostname, (ndr_mstring_t *)&entry[0].name);
4278d7e4166Sjose borrego (void) NDR_MSTRING(mxa, "Builtin", (ndr_mstring_t *)&entry[1].name);
428da6c28aaSamw
4298d7e4166Sjose borrego info = NDR_NEW(mxa, struct samr_LocalDomainInfo);
430da6c28aaSamw if (info == NULL)
431da6c28aaSamw return (NT_STATUS_NO_MEMORY);
432da6c28aaSamw
433da6c28aaSamw info->entries_read = 2;
434da6c28aaSamw info->entry = entry;
435da6c28aaSamw param->info = info;
436da6c28aaSamw return (NT_STATUS_SUCCESS);
437da6c28aaSamw }
438da6c28aaSamw
439da6c28aaSamw /*
440da6c28aaSamw * samr_s_OpenDomain
441da6c28aaSamw *
442da6c28aaSamw * This is a request to open a domain within the local SAM database.
443dc20a302Sas * The caller must supply a valid connect handle.
444dc20a302Sas * We return a handle to be used to access objects within this domain.
445da6c28aaSamw */
446da6c28aaSamw static int
samr_s_OpenDomain(void * arg,ndr_xa_t * mxa)4478d7e4166Sjose borrego samr_s_OpenDomain(void *arg, ndr_xa_t *mxa)
448da6c28aaSamw {
449da6c28aaSamw struct samr_OpenDomain *param = arg;
450dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
451a0aa776eSAlan Wright smb_domain_t domain;
452da6c28aaSamw
453dc20a302Sas if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) {
454da6c28aaSamw bzero(¶m->domain_handle, sizeof (samr_handle_t));
455da6c28aaSamw param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
4568d7e4166Sjose borrego return (NDR_DRC_OK);
457da6c28aaSamw }
458da6c28aaSamw
459a0aa776eSAlan Wright if (!smb_domain_lookup_sid((smb_sid_t *)param->sid, &domain)) {
460da6c28aaSamw bzero(¶m->domain_handle, sizeof (samr_handle_t));
461da6c28aaSamw param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
4628d7e4166Sjose borrego return (NDR_DRC_OK);
463da6c28aaSamw }
464da6c28aaSamw
465a0aa776eSAlan Wright if ((domain.di_type != SMB_DOMAIN_BUILTIN) &&
466a0aa776eSAlan Wright (domain.di_type != SMB_DOMAIN_LOCAL)) {
467dc20a302Sas bzero(¶m->domain_handle, sizeof (samr_handle_t));
468dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
4698d7e4166Sjose borrego return (NDR_DRC_OK);
470dc20a302Sas }
471da6c28aaSamw
47229bd2886SAlan Wright id = samr_hdalloc(mxa, SAMR_KEY_DOMAIN, domain.di_type, 0);
473dc20a302Sas if (id) {
474dc20a302Sas bcopy(id, ¶m->domain_handle, sizeof (samr_handle_t));
475da6c28aaSamw param->status = 0;
476dc20a302Sas } else {
477da6c28aaSamw bzero(¶m->domain_handle, sizeof (samr_handle_t));
478dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
479da6c28aaSamw }
480da6c28aaSamw
4818d7e4166Sjose borrego return (NDR_DRC_OK);
482da6c28aaSamw }
483da6c28aaSamw
484da6c28aaSamw /*
485da6c28aaSamw * samr_s_QueryDomainInfo
486da6c28aaSamw *
487da6c28aaSamw * The caller should pass a domain handle.
488da6c28aaSamw *
489da6c28aaSamw * Windows 95 Server Manager sends requests for levels 6 and 7 when
490da6c28aaSamw * the services menu item is selected. Level 2 is basically for getting
491da6c28aaSamw * number of users, groups, and aliases in a domain.
492da6c28aaSamw * We have no information on what the various information levels mean.
493da6c28aaSamw */
494da6c28aaSamw static int
samr_s_QueryDomainInfo(void * arg,ndr_xa_t * mxa)4958d7e4166Sjose borrego samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa)
496da6c28aaSamw {
497da6c28aaSamw struct samr_QueryDomainInfo *param = arg;
498faa1795aSjb struct samr_QueryDomainInfoRes *info;
499dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
500dc20a302Sas ndr_handle_t *hd;
501dc20a302Sas samr_keydata_t *data;
502dc20a302Sas char *domain;
503b89a8333Snatalie li - Sun Microsystems - Irvine United States char hostname[NETBIOS_NAME_SZ];
5043db3f65cSamw int alias_cnt, user_cnt;
5053db3f65cSamw int rc = 0;
506da6c28aaSamw
507dc20a302Sas if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
508dc20a302Sas bzero(param, sizeof (struct samr_QueryDomainInfo));
509dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
5108d7e4166Sjose borrego return (NDR_DRC_OK);
511dc20a302Sas }
512dc20a302Sas
5138d7e4166Sjose borrego info = NDR_NEW(mxa, struct samr_QueryDomainInfoRes);
514faa1795aSjb if (info == NULL) {
515faa1795aSjb bzero(param, sizeof (struct samr_QueryDomainInfo));
516faa1795aSjb param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
5178d7e4166Sjose borrego return (NDR_DRC_OK);
518faa1795aSjb }
519faa1795aSjb info->switch_value = param->info_level;
520faa1795aSjb param->info = info;
521faa1795aSjb
522dc20a302Sas data = (samr_keydata_t *)hd->nh_data;
523dc20a302Sas
524dc20a302Sas switch (data->kd_type) {
525a0aa776eSAlan Wright case SMB_DOMAIN_BUILTIN:
526faa1795aSjb domain = "BUILTIN";
5273db3f65cSamw user_cnt = 0;
5287f667e74Sjose borrego alias_cnt = smb_sam_grp_cnt(data->kd_type);
529dc20a302Sas break;
530dc20a302Sas
531a0aa776eSAlan Wright case SMB_DOMAIN_LOCAL:
532b89a8333Snatalie li - Sun Microsystems - Irvine United States rc = smb_getnetbiosname(hostname, sizeof (hostname));
5333db3f65cSamw if (rc == 0) {
5343db3f65cSamw domain = hostname;
5357f667e74Sjose borrego user_cnt = smb_sam_usr_cnt();
5367f667e74Sjose borrego alias_cnt = smb_sam_grp_cnt(data->kd_type);
537dc20a302Sas }
538dc20a302Sas break;
539dc20a302Sas
540dc20a302Sas default:
541da6c28aaSamw bzero(param, sizeof (struct samr_QueryDomainInfo));
542da6c28aaSamw param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
5438d7e4166Sjose borrego return (NDR_DRC_OK);
544da6c28aaSamw }
545da6c28aaSamw
5463db3f65cSamw if (rc != 0) {
5473db3f65cSamw bzero(param, sizeof (struct samr_QueryDomainInfo));
5483db3f65cSamw param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR);
5498d7e4166Sjose borrego return (NDR_DRC_OK);
5503db3f65cSamw }
5513db3f65cSamw
552da6c28aaSamw switch (param->info_level) {
553da6c28aaSamw case SAMR_QUERY_DOMAIN_INFO_6:
554faa1795aSjb info->ru.info6.unknown1 = 0x00000000;
555faa1795aSjb info->ru.info6.unknown2 = 0x00147FB0;
556faa1795aSjb info->ru.info6.unknown3 = 0x00000000;
557faa1795aSjb info->ru.info6.unknown4 = 0x00000000;
558faa1795aSjb info->ru.info6.unknown5 = 0x00000000;
559da6c28aaSamw param->status = NT_STATUS_SUCCESS;
560da6c28aaSamw break;
561da6c28aaSamw
562da6c28aaSamw case SAMR_QUERY_DOMAIN_INFO_7:
563faa1795aSjb info->ru.info7.unknown1 = 0x00000003;
564da6c28aaSamw param->status = NT_STATUS_SUCCESS;
565da6c28aaSamw break;
566da6c28aaSamw
567da6c28aaSamw case SAMR_QUERY_DOMAIN_INFO_2:
568faa1795aSjb info->ru.info2.unknown1 = 0x00000000;
569faa1795aSjb info->ru.info2.unknown2 = 0x80000000;
570da6c28aaSamw
5718d7e4166Sjose borrego (void) NDR_MSTRING(mxa, "",
5728d7e4166Sjose borrego (ndr_mstring_t *)&(info->ru.info2.s1));
5738d7e4166Sjose borrego (void) NDR_MSTRING(mxa, domain,
5748d7e4166Sjose borrego (ndr_mstring_t *)&(info->ru.info2.domain));
5758d7e4166Sjose borrego (void) NDR_MSTRING(mxa, "",
5768d7e4166Sjose borrego (ndr_mstring_t *)&(info->ru.info2.s2));
577da6c28aaSamw
578faa1795aSjb info->ru.info2.sequence_num = 0x0000002B;
579faa1795aSjb info->ru.info2.unknown3 = 0x00000000;
580faa1795aSjb info->ru.info2.unknown4 = 0x00000001;
581faa1795aSjb info->ru.info2.unknown5 = 0x00000003;
582faa1795aSjb info->ru.info2.unknown6 = 0x00000001;
5833db3f65cSamw info->ru.info2.num_users = user_cnt;
584faa1795aSjb info->ru.info2.num_groups = 0;
585faa1795aSjb info->ru.info2.num_aliases = alias_cnt;
586da6c28aaSamw param->status = NT_STATUS_SUCCESS;
587da6c28aaSamw break;
588da6c28aaSamw
589da6c28aaSamw default:
590da6c28aaSamw bzero(param, sizeof (struct samr_QueryDomainInfo));
5918d7e4166Sjose borrego return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
592da6c28aaSamw };
593da6c28aaSamw
5948d7e4166Sjose borrego return (NDR_DRC_OK);
595da6c28aaSamw }
596da6c28aaSamw
597f96bd5c8SAlan Wright /*
598f96bd5c8SAlan Wright * QueryInfoDomain2: Identical to QueryDomainInfo.
599f96bd5c8SAlan Wright */
600f96bd5c8SAlan Wright static int
samr_s_QueryInfoDomain2(void * arg,ndr_xa_t * mxa)601f96bd5c8SAlan Wright samr_s_QueryInfoDomain2(void *arg, ndr_xa_t *mxa)
602f96bd5c8SAlan Wright {
603f96bd5c8SAlan Wright return (samr_s_QueryDomainInfo(arg, mxa));
604f96bd5c8SAlan Wright }
605f96bd5c8SAlan Wright
606da6c28aaSamw /*
6077f667e74Sjose borrego * Looks up the given name in the specified domain which could
6087f667e74Sjose borrego * be either the built-in or local domain.
609da6c28aaSamw *
6107f667e74Sjose borrego * CAVEAT: this function should be able to handle a list of
6117f667e74Sjose borrego * names but currently it can only handle one name at a time.
612da6c28aaSamw */
613da6c28aaSamw static int
samr_s_LookupNames(void * arg,ndr_xa_t * mxa)6148d7e4166Sjose borrego samr_s_LookupNames(void *arg, ndr_xa_t *mxa)
615da6c28aaSamw {
616da6c28aaSamw struct samr_LookupNames *param = arg;
617dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
618dc20a302Sas ndr_handle_t *hd;
619dc20a302Sas samr_keydata_t *data;
6207f667e74Sjose borrego smb_account_t account;
6216537f381Sas smb_wka_t *wka;
622dc20a302Sas uint32_t status = NT_STATUS_SUCCESS;
623da6c28aaSamw
624dc20a302Sas if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL)
625dc20a302Sas status = NT_STATUS_INVALID_HANDLE;
626da6c28aaSamw
627dc20a302Sas if (param->n_entry != 1)
628dc20a302Sas status = NT_STATUS_ACCESS_DENIED;
629da6c28aaSamw
630da6c28aaSamw if (param->name.str == NULL) {
631da6c28aaSamw /*
632dc20a302Sas * Windows NT returns NT_STATUS_NONE_MAPPED.
633da6c28aaSamw * Windows 2000 returns STATUS_INVALID_ACCOUNT_NAME.
634da6c28aaSamw */
635dc20a302Sas status = NT_STATUS_NONE_MAPPED;
636dc20a302Sas }
637dc20a302Sas
638dc20a302Sas if (status != NT_STATUS_SUCCESS) {
639dc20a302Sas bzero(param, sizeof (struct samr_LookupNames));
640dc20a302Sas param->status = NT_SC_ERROR(status);
6418d7e4166Sjose borrego return (NDR_DRC_OK);
642da6c28aaSamw }
643da6c28aaSamw
6448d7e4166Sjose borrego param->rids.rid = NDR_NEW(mxa, DWORD);
6458d7e4166Sjose borrego param->rid_types.rid_type = NDR_NEW(mxa, DWORD);
646da6c28aaSamw
647dc20a302Sas data = (samr_keydata_t *)hd->nh_data;
648da6c28aaSamw
649dc20a302Sas switch (data->kd_type) {
650a0aa776eSAlan Wright case SMB_DOMAIN_BUILTIN:
651f96bd5c8SAlan Wright wka = smb_wka_lookup_builtin((char *)param->name.str);
652dc20a302Sas if (wka != NULL) {
653da6c28aaSamw param->rids.n_entry = 1;
6546537f381Sas (void) smb_sid_getrid(wka->wka_binsid,
6556537f381Sas ¶m->rids.rid[0]);
656da6c28aaSamw param->rid_types.n_entry = 1;
6576537f381Sas param->rid_types.rid_type[0] = wka->wka_type;
658da6c28aaSamw param->status = NT_STATUS_SUCCESS;
6598d7e4166Sjose borrego return (NDR_DRC_OK);
660da6c28aaSamw }
661dc20a302Sas break;
662da6c28aaSamw
663a0aa776eSAlan Wright case SMB_DOMAIN_LOCAL:
6647f667e74Sjose borrego status = smb_sam_lookup_name(NULL, (char *)param->name.str,
6657f667e74Sjose borrego SidTypeUnknown, &account);
6667f667e74Sjose borrego if (status == NT_STATUS_SUCCESS) {
667da6c28aaSamw param->rids.n_entry = 1;
6687f667e74Sjose borrego param->rids.rid[0] = account.a_rid;
669da6c28aaSamw param->rid_types.n_entry = 1;
6707f667e74Sjose borrego param->rid_types.rid_type[0] = account.a_type;
671da6c28aaSamw param->status = NT_STATUS_SUCCESS;
6727f667e74Sjose borrego smb_account_free(&account);
6738d7e4166Sjose borrego return (NDR_DRC_OK);
674da6c28aaSamw }
675dc20a302Sas break;
676da6c28aaSamw
677dc20a302Sas default:
678dc20a302Sas bzero(param, sizeof (struct samr_LookupNames));
679dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
6808d7e4166Sjose borrego return (NDR_DRC_OK);
681da6c28aaSamw }
682da6c28aaSamw
683da6c28aaSamw param->rids.n_entry = 0;
684da6c28aaSamw param->rid_types.n_entry = 0;
685da6c28aaSamw param->status = NT_SC_ERROR(NT_STATUS_NONE_MAPPED);
6868d7e4166Sjose borrego return (NDR_DRC_OK);
687da6c28aaSamw }
688da6c28aaSamw
689da6c28aaSamw /*
690da6c28aaSamw * samr_s_OpenUser
691da6c28aaSamw *
692da6c28aaSamw * This is a request to open a user within a specified domain in the
693da6c28aaSamw * local SAM database. The caller must supply a valid domain handle,
694da6c28aaSamw * obtained via a successful domain open request. The user is
695da6c28aaSamw * specified by the rid in the request.
696da6c28aaSamw */
697da6c28aaSamw static int
samr_s_OpenUser(void * arg,ndr_xa_t * mxa)6988d7e4166Sjose borrego samr_s_OpenUser(void *arg, ndr_xa_t *mxa)
699da6c28aaSamw {
700da6c28aaSamw struct samr_OpenUser *param = arg;
701dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
702dc20a302Sas ndr_handle_t *hd;
703dc20a302Sas samr_keydata_t *data;
704da6c28aaSamw
705dc20a302Sas if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
706da6c28aaSamw bzero(¶m->user_handle, sizeof (samr_handle_t));
707dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
7088d7e4166Sjose borrego return (NDR_DRC_OK);
709da6c28aaSamw }
710da6c28aaSamw
711dc20a302Sas data = (samr_keydata_t *)hd->nh_data;
712dc20a302Sas
713dc20a302Sas id = samr_hdalloc(mxa, SAMR_KEY_USER, data->kd_type, param->rid);
714dc20a302Sas if (id == NULL) {
715dc20a302Sas bzero(¶m->user_handle, sizeof (samr_handle_t));
716dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
717dc20a302Sas } else {
718dc20a302Sas bcopy(id, ¶m->user_handle, sizeof (samr_handle_t));
719fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
720dc20a302Sas }
721da6c28aaSamw
7228d7e4166Sjose borrego return (NDR_DRC_OK);
723da6c28aaSamw }
724da6c28aaSamw
725da6c28aaSamw /*
726da6c28aaSamw * samr_s_DeleteUser
727da6c28aaSamw *
728dc20a302Sas * Request to delete a user within a specified domain in the local
729dc20a302Sas * SAM database. The caller should supply a valid user handle.
730da6c28aaSamw */
731da6c28aaSamw /*ARGSUSED*/
732da6c28aaSamw static int
samr_s_DeleteUser(void * arg,ndr_xa_t * mxa)7338d7e4166Sjose borrego samr_s_DeleteUser(void *arg, ndr_xa_t *mxa)
734da6c28aaSamw {
735da6c28aaSamw struct samr_DeleteUser *param = arg;
736da6c28aaSamw
737dc20a302Sas bzero(param, sizeof (struct samr_DeleteUser));
738da6c28aaSamw param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
7398d7e4166Sjose borrego return (NDR_DRC_OK);
740da6c28aaSamw }
741da6c28aaSamw
742da6c28aaSamw /*
743da6c28aaSamw * samr_s_QueryUserInfo
744da6c28aaSamw *
745da6c28aaSamw * Returns:
746da6c28aaSamw * NT_STATUS_SUCCESS
747da6c28aaSamw * NT_STATUS_ACCESS_DENIED
748da6c28aaSamw * NT_STATUS_INVALID_INFO_CLASS
749da6c28aaSamw */
750da6c28aaSamw /*ARGSUSED*/
751da6c28aaSamw static int
samr_s_QueryUserInfo(void * arg,ndr_xa_t * mxa)7528d7e4166Sjose borrego samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa)
753da6c28aaSamw {
754fe1c642dSBill Krier struct samr_QueryUserInfo *param = arg;
755fe1c642dSBill Krier struct samr_QueryUserInfo21 *all_info;
756fe1c642dSBill Krier ndr_hdid_t *id;
757fe1c642dSBill Krier ndr_handle_t *hd;
758fe1c642dSBill Krier samr_keydata_t *data;
759fe1c642dSBill Krier smb_domain_t di;
760fe1c642dSBill Krier smb_account_t account;
761fe1c642dSBill Krier smb_sid_t *sid;
762fe1c642dSBill Krier uint32_t status;
763fe1c642dSBill Krier
764fe1c642dSBill Krier id = (ndr_hdid_t *)¶m->user_handle;
765fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) {
766fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
767fe1c642dSBill Krier goto QueryUserInfoError;
768fe1c642dSBill Krier }
769fe1c642dSBill Krier
770fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
771fe1c642dSBill Krier
772fe1c642dSBill Krier if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) {
773fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
774fe1c642dSBill Krier goto QueryUserInfoError;
775fe1c642dSBill Krier }
776da6c28aaSamw
777fe1c642dSBill Krier if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) {
778fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
779fe1c642dSBill Krier goto QueryUserInfoError;
780fe1c642dSBill Krier }
781fe1c642dSBill Krier
782fe1c642dSBill Krier if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) {
783fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
784fe1c642dSBill Krier goto QueryUserInfoError;
785fe1c642dSBill Krier }
786fe1c642dSBill Krier
787fe1c642dSBill Krier if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) {
788fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
789fe1c642dSBill Krier goto QueryUserInfoError;
790fe1c642dSBill Krier }
791fe1c642dSBill Krier
792fe1c642dSBill Krier all_info = ¶m->ru.info21;
793fe1c642dSBill Krier bzero(all_info, sizeof (struct samr_QueryUserInfo21));
794fe1c642dSBill Krier
795*9242c919SMatt Barden all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID |
796*9242c919SMatt Barden SAMR_USER_ALL_FULLNAME | SAMR_USER_ALL_USERACCOUNTCONTROL |
797*9242c919SMatt Barden SAMR_USER_ALL_ADMINCOMMENT;
798fe1c642dSBill Krier
799fe1c642dSBill Krier (void) NDR_MSTRING(mxa, account.a_name,
800fe1c642dSBill Krier (ndr_mstring_t *)&all_info->UserName);
801*9242c919SMatt Barden (void) NDR_MSTRING(mxa, account.a_name,
802*9242c919SMatt Barden (ndr_mstring_t *)&all_info->FullName);
803*9242c919SMatt Barden (void) NDR_MSTRING(mxa, "",
804*9242c919SMatt Barden (ndr_mstring_t *)&all_info->AdminComment);
805fe1c642dSBill Krier
806*9242c919SMatt Barden all_info->UserId = data->kd_rid;
807*9242c919SMatt Barden all_info->UserAccountControl = SAMR_AF_NORMAL_ACCOUNT |
808*9242c919SMatt Barden SAMR_AF_DONT_EXPIRE_PASSWD;
809*9242c919SMatt Barden if ((account.a_flags & SMB_PWF_DISABLE) != 0)
810*9242c919SMatt Barden all_info->UserAccountControl |= SAMR_AF_ACCOUNTDISABLE;
811fe1c642dSBill Krier
812fe1c642dSBill Krier param->address = 1;
813fe1c642dSBill Krier param->switch_index = SAMR_QUERY_USER_ALL_INFO;
814fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
8159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_account_free(&account);
8169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_sid_free(sid);
817fe1c642dSBill Krier return (NDR_DRC_OK);
818fe1c642dSBill Krier
819fe1c642dSBill Krier QueryUserInfoError:
8209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_sid_free(sid);
821da6c28aaSamw bzero(param, sizeof (struct samr_QueryUserInfo));
822fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
8238d7e4166Sjose borrego return (NDR_DRC_OK);
824da6c28aaSamw }
825da6c28aaSamw
826da6c28aaSamw /*
827da6c28aaSamw * samr_s_QueryUserGroups
828da6c28aaSamw *
829dc20a302Sas * Request the list of groups of which a user is a member.
830dc20a302Sas * The user is identified from the handle, which contains an
831dc20a302Sas * rid in the discriminator field. Note that this is a local user.
832da6c28aaSamw */
833da6c28aaSamw static int
samr_s_QueryUserGroups(void * arg,ndr_xa_t * mxa)8348d7e4166Sjose borrego samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa)
835da6c28aaSamw {
836da6c28aaSamw struct samr_QueryUserGroups *param = arg;
837da6c28aaSamw struct samr_UserGroupInfo *info;
838dc20a302Sas struct samr_UserGroups *group;
839dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->user_handle;
840dc20a302Sas ndr_handle_t *hd;
841dc20a302Sas samr_keydata_t *data;
8426537f381Sas smb_sid_t *user_sid = NULL;
843dc20a302Sas smb_group_t grp;
844dc20a302Sas smb_giter_t gi;
845a0aa776eSAlan Wright smb_domain_t di;
846dc20a302Sas uint32_t status;
847dc20a302Sas int size;
848dc20a302Sas int ngrp_max;
849dc20a302Sas
850dc20a302Sas if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) {
851dc20a302Sas status = NT_STATUS_ACCESS_DENIED;
852dc20a302Sas goto query_error;
853dc20a302Sas }
854da6c28aaSamw
855dc20a302Sas data = (samr_keydata_t *)hd->nh_data;
856dc20a302Sas switch (data->kd_type) {
857a0aa776eSAlan Wright case SMB_DOMAIN_BUILTIN:
858a0aa776eSAlan Wright case SMB_DOMAIN_LOCAL:
859a0aa776eSAlan Wright if (!smb_domain_lookup_type(data->kd_type, &di)) {
86029bd2886SAlan Wright status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
861dc20a302Sas goto query_error;
862dc20a302Sas }
863dc20a302Sas break;
864dc20a302Sas default:
865dc20a302Sas status = NT_STATUS_INVALID_HANDLE;
866dc20a302Sas goto query_error;
867dc20a302Sas }
868dc20a302Sas
86929bd2886SAlan Wright user_sid = smb_sid_splice(di.di_binsid, data->kd_rid);
870dc20a302Sas if (user_sid == NULL) {
871dc20a302Sas status = NT_STATUS_NO_MEMORY;
872dc20a302Sas goto query_error;
873da6c28aaSamw }
874da6c28aaSamw
8758d7e4166Sjose borrego info = NDR_NEW(mxa, struct samr_UserGroupInfo);
876dc20a302Sas if (info == NULL) {
877dc20a302Sas status = NT_STATUS_NO_MEMORY;
878dc20a302Sas goto query_error;
879dc20a302Sas }
880dc20a302Sas bzero(info, sizeof (struct samr_UserGroupInfo));
881da6c28aaSamw
882dc20a302Sas size = 32 * 1024;
8838d7e4166Sjose borrego info->groups = NDR_MALLOC(mxa, size);
884dc20a302Sas if (info->groups == NULL) {
885dc20a302Sas status = NT_STATUS_NO_MEMORY;
886dc20a302Sas goto query_error;
887dc20a302Sas }
888dc20a302Sas ngrp_max = size / sizeof (struct samr_UserGroups);
889da6c28aaSamw
890dc20a302Sas if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
891dc20a302Sas status = NT_STATUS_INTERNAL_ERROR;
892dc20a302Sas goto query_error;
893da6c28aaSamw }
894da6c28aaSamw
895dc20a302Sas info->n_entry = 0;
896dc20a302Sas group = info->groups;
897dc20a302Sas while ((info->n_entry < ngrp_max) &&
898dc20a302Sas (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS)) {
899dc20a302Sas if (smb_lgrp_is_member(&grp, user_sid)) {
900dc20a302Sas group->rid = grp.sg_rid;
901dc20a302Sas group->attr = grp.sg_attr;
902dc20a302Sas group++;
903dc20a302Sas info->n_entry++;
904dc20a302Sas }
905dc20a302Sas smb_lgrp_free(&grp);
906dc20a302Sas }
907dc20a302Sas smb_lgrp_iterclose(&gi);
908dc20a302Sas
909dc20a302Sas free(user_sid);
910dc20a302Sas param->info = info;
911dc20a302Sas param->status = NT_STATUS_SUCCESS;
9128d7e4166Sjose borrego return (NDR_DRC_OK);
913dc20a302Sas
914dc20a302Sas query_error:
915dc20a302Sas free(user_sid);
916dc20a302Sas bzero(param, sizeof (struct samr_QueryUserGroups));
917dc20a302Sas param->status = NT_SC_ERROR(status);
9188d7e4166Sjose borrego return (NDR_DRC_OK);
919da6c28aaSamw }
920da6c28aaSamw
921da6c28aaSamw /*
922da6c28aaSamw * samr_s_OpenGroup
923da6c28aaSamw *
924da6c28aaSamw * This is a request to open a group within the specified domain in the
925da6c28aaSamw * local SAM database. The caller must supply a valid domain handle,
926da6c28aaSamw * obtained via a successful domain open request. The group is
927da6c28aaSamw * specified by the rid in the request. If this is a local RID it
928da6c28aaSamw * should already be encoded with type information.
929da6c28aaSamw *
930da6c28aaSamw * We return a handle to be used to access information about this group.
931da6c28aaSamw */
932da6c28aaSamw static int
samr_s_OpenGroup(void * arg,ndr_xa_t * mxa)9338d7e4166Sjose borrego samr_s_OpenGroup(void *arg, ndr_xa_t *mxa)
934da6c28aaSamw {
935da6c28aaSamw struct samr_OpenGroup *param = arg;
936dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
937dc20a302Sas ndr_handle_t *hd;
938dc20a302Sas samr_keydata_t *data;
939da6c28aaSamw
940dc20a302Sas if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
941da6c28aaSamw bzero(¶m->group_handle, sizeof (samr_handle_t));
942dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
9438d7e4166Sjose borrego return (NDR_DRC_OK);
944da6c28aaSamw }
945da6c28aaSamw
946dc20a302Sas data = (samr_keydata_t *)hd->nh_data;
947dc20a302Sas id = samr_hdalloc(mxa, SAMR_KEY_GROUP, data->kd_type, param->rid);
948dc20a302Sas
949dc20a302Sas if (id) {
950dc20a302Sas bcopy(id, ¶m->group_handle, sizeof (samr_handle_t));
951dc20a302Sas param->status = 0;
952dc20a302Sas } else {
953dc20a302Sas bzero(¶m->group_handle, sizeof (samr_handle_t));
954dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
955dc20a302Sas }
956da6c28aaSamw
9578d7e4166Sjose borrego return (NDR_DRC_OK);
958da6c28aaSamw }
959da6c28aaSamw
960c5866007SKeyur Desai /*
961c5866007SKeyur Desai * samr_s_AddAliasMember
962c5866007SKeyur Desai *
963c5866007SKeyur Desai * Add a member to a local SAM group.
964c5866007SKeyur Desai * The caller must supply a valid group handle.
965c5866007SKeyur Desai * The member is specified by the sid in the request.
966c5866007SKeyur Desai */
967c5866007SKeyur Desai static int
samr_s_AddAliasMember(void * arg,ndr_xa_t * mxa)968c5866007SKeyur Desai samr_s_AddAliasMember(void *arg, ndr_xa_t *mxa)
969c5866007SKeyur Desai {
970c5866007SKeyur Desai struct samr_AddAliasMember *param = arg;
971c5866007SKeyur Desai ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
972c5866007SKeyur Desai ndr_handle_t *hd;
973c5866007SKeyur Desai samr_keydata_t *data;
974c5866007SKeyur Desai smb_group_t grp;
975c5866007SKeyur Desai uint32_t rc;
976c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS;
977c5866007SKeyur Desai
978c5866007SKeyur Desai if (param->sid == NULL) {
979c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember));
980c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
981c5866007SKeyur Desai return (NDR_DRC_OK);
982c5866007SKeyur Desai }
983c5866007SKeyur Desai
984c5866007SKeyur Desai if (!ndr_is_admin(mxa)) {
985c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember));
986c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
987c5866007SKeyur Desai return (NDR_DRC_OK);
988c5866007SKeyur Desai }
989c5866007SKeyur Desai
990c5866007SKeyur Desai
991c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
992c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember));
993c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
994c5866007SKeyur Desai return (NDR_DRC_OK);
995c5866007SKeyur Desai }
996c5866007SKeyur Desai
997c5866007SKeyur Desai data = (samr_keydata_t *)hd->nh_data;
998c5866007SKeyur Desai rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp);
999c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1000c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember));
1001c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1002c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
1003c5866007SKeyur Desai return (NDR_DRC_OK);
1004c5866007SKeyur Desai }
1005c5866007SKeyur Desai
1006c5866007SKeyur Desai rc = smb_lgrp_add_member(grp.sg_name,
1007c5866007SKeyur Desai (smb_sid_t *)param->sid, SidTypeUser);
1008c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1009c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember));
1010c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1011c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
1012c5866007SKeyur Desai }
1013c5866007SKeyur Desai smb_lgrp_free(&grp);
1014c5866007SKeyur Desai
1015c5866007SKeyur Desai param->status = status;
1016c5866007SKeyur Desai return (NDR_DRC_OK);
1017c5866007SKeyur Desai }
1018c5866007SKeyur Desai
1019c5866007SKeyur Desai /*
1020c5866007SKeyur Desai * samr_s_DeleteAliasMember
1021c5866007SKeyur Desai *
1022c5866007SKeyur Desai * Delete a member from a local SAM group.
1023c5866007SKeyur Desai * The caller must supply a valid group handle.
1024c5866007SKeyur Desai * The member is specified by the sid in the request.
1025c5866007SKeyur Desai */
1026c5866007SKeyur Desai static int
samr_s_DeleteAliasMember(void * arg,ndr_xa_t * mxa)1027c5866007SKeyur Desai samr_s_DeleteAliasMember(void *arg, ndr_xa_t *mxa)
1028c5866007SKeyur Desai {
1029c5866007SKeyur Desai struct samr_DeleteAliasMember *param = arg;
1030c5866007SKeyur Desai ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1031c5866007SKeyur Desai ndr_handle_t *hd;
1032c5866007SKeyur Desai samr_keydata_t *data;
1033c5866007SKeyur Desai smb_group_t grp;
1034c5866007SKeyur Desai uint32_t rc;
1035c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS;
1036c5866007SKeyur Desai
1037c5866007SKeyur Desai if (param->sid == NULL) {
1038c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember));
1039c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
1040c5866007SKeyur Desai return (NDR_DRC_OK);
1041c5866007SKeyur Desai }
1042c5866007SKeyur Desai
1043c5866007SKeyur Desai if (!ndr_is_admin(mxa)) {
1044c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember));
1045c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
1046c5866007SKeyur Desai return (NDR_DRC_OK);
1047c5866007SKeyur Desai }
1048c5866007SKeyur Desai
1049c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
1050c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember));
1051c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1052c5866007SKeyur Desai return (NDR_DRC_OK);
1053c5866007SKeyur Desai }
1054c5866007SKeyur Desai
1055c5866007SKeyur Desai data = (samr_keydata_t *)hd->nh_data;
1056c5866007SKeyur Desai rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp);
1057c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1058c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember));
1059c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1060c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
1061c5866007SKeyur Desai return (NDR_DRC_OK);
1062c5866007SKeyur Desai }
1063c5866007SKeyur Desai
1064c5866007SKeyur Desai rc = smb_lgrp_del_member(grp.sg_name,
1065c5866007SKeyur Desai (smb_sid_t *)param->sid, SidTypeUser);
1066c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1067c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember));
1068c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1069c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
1070c5866007SKeyur Desai }
1071c5866007SKeyur Desai smb_lgrp_free(&grp);
1072c5866007SKeyur Desai
1073c5866007SKeyur Desai param->status = status;
1074c5866007SKeyur Desai return (NDR_DRC_OK);
1075c5866007SKeyur Desai }
1076c5866007SKeyur Desai
1077c5866007SKeyur Desai /*
1078c5866007SKeyur Desai * samr_s_ListAliasMembers
1079c5866007SKeyur Desai *
1080c5866007SKeyur Desai * List members from a local SAM group.
1081c5866007SKeyur Desai * The caller must supply a valid group handle.
1082c5866007SKeyur Desai * A list of user SIDs in the specified group is returned to the caller.
1083c5866007SKeyur Desai */
1084c5866007SKeyur Desai static int
samr_s_ListAliasMembers(void * arg,ndr_xa_t * mxa)1085c5866007SKeyur Desai samr_s_ListAliasMembers(void *arg, ndr_xa_t *mxa)
1086c5866007SKeyur Desai {
1087c5866007SKeyur Desai struct samr_ListAliasMembers *param = arg;
1088c5866007SKeyur Desai ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1089c5866007SKeyur Desai ndr_handle_t *hd;
1090c5866007SKeyur Desai samr_keydata_t *data;
1091c5866007SKeyur Desai smb_group_t grp;
1092c5866007SKeyur Desai smb_gsid_t *members;
1093c5866007SKeyur Desai struct samr_SidInfo info;
1094c5866007SKeyur Desai struct samr_SidList *user;
1095c5866007SKeyur Desai uint32_t num = 0, size;
1096c5866007SKeyur Desai int i;
1097c5866007SKeyur Desai uint32_t rc;
1098c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS;
1099c5866007SKeyur Desai
1100c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
1101c5866007SKeyur Desai bzero(param, sizeof (struct samr_ListAliasMembers));
1102c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1103c5866007SKeyur Desai return (NDR_DRC_OK);
1104c5866007SKeyur Desai }
1105c5866007SKeyur Desai
1106c5866007SKeyur Desai bzero(&info, sizeof (struct samr_SidInfo));
1107c5866007SKeyur Desai data = (samr_keydata_t *)hd->nh_data;
1108c5866007SKeyur Desai rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp);
1109c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1110c5866007SKeyur Desai bzero(param, sizeof (struct samr_ListAliasMembers));
1111c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1112c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
1113c5866007SKeyur Desai return (NDR_DRC_OK);
1114c5866007SKeyur Desai }
1115c5866007SKeyur Desai
1116c5866007SKeyur Desai num = grp.sg_nmembers;
1117c5866007SKeyur Desai members = grp.sg_members;
1118c5866007SKeyur Desai size = num * sizeof (struct samr_SidList);
1119c5866007SKeyur Desai info.sidlist = NDR_MALLOC(mxa, size);
1120c5866007SKeyur Desai if (info.sidlist == NULL) {
1121c5866007SKeyur Desai bzero(param, sizeof (struct samr_ListAliasMembers));
1122c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1123c5866007SKeyur Desai smb_lgrp_free(&grp);
1124c5866007SKeyur Desai return (NDR_DRC_OK);
1125c5866007SKeyur Desai }
1126c5866007SKeyur Desai
1127c5866007SKeyur Desai info.n_entry = num;
1128c5866007SKeyur Desai user = info.sidlist;
1129c5866007SKeyur Desai for (i = 0; i < num; i++) {
1130c5866007SKeyur Desai user->sid = (struct samr_sid *)NDR_SIDDUP(mxa,
1131c5866007SKeyur Desai members[i].gs_sid);
1132c5866007SKeyur Desai if (user->sid == NULL) {
1133c5866007SKeyur Desai bzero(param, sizeof (struct samr_ListAliasMembers));
1134c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1135c5866007SKeyur Desai smb_lgrp_free(&grp);
1136c5866007SKeyur Desai return (NDR_DRC_OK);
1137c5866007SKeyur Desai }
1138c5866007SKeyur Desai user++;
1139c5866007SKeyur Desai }
1140c5866007SKeyur Desai smb_lgrp_free(&grp);
1141c5866007SKeyur Desai
1142c5866007SKeyur Desai param->info = info;
1143c5866007SKeyur Desai param->status = status;
1144c5866007SKeyur Desai return (NDR_DRC_OK);
1145c5866007SKeyur Desai }
1146c5866007SKeyur Desai
1147da6c28aaSamw /*
1148cb174861Sjoyce mcintosh * samr_s_Connect2
1149da6c28aaSamw *
1150dc20a302Sas * This is a request to connect to the local SAM database.
1151dc20a302Sas * We don't support any form of update request and our database doesn't
1152dc20a302Sas * contain any private information, so there is little point in doing
1153dc20a302Sas * any access access checking here.
1154da6c28aaSamw *
1155da6c28aaSamw * Return a handle for use with subsequent SAM requests.
1156da6c28aaSamw */
1157da6c28aaSamw static int
samr_s_Connect2(void * arg,ndr_xa_t * mxa)1158cb174861Sjoyce mcintosh samr_s_Connect2(void *arg, ndr_xa_t *mxa)
1159da6c28aaSamw {
1160cb174861Sjoyce mcintosh struct samr_Connect2 *param = arg;
1161dc20a302Sas ndr_hdid_t *id;
1162da6c28aaSamw
1163a0aa776eSAlan Wright id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
1164dc20a302Sas if (id) {
1165dc20a302Sas bcopy(id, ¶m->handle, sizeof (samr_handle_t));
1166dc20a302Sas param->status = 0;
1167dc20a302Sas } else {
1168dc20a302Sas bzero(¶m->handle, sizeof (samr_handle_t));
1169dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1170dc20a302Sas }
1171da6c28aaSamw
11728d7e4166Sjose borrego return (NDR_DRC_OK);
1173da6c28aaSamw }
1174da6c28aaSamw
1175da6c28aaSamw /*
1176da6c28aaSamw * samr_s_GetUserPwInfo
1177da6c28aaSamw *
1178f96bd5c8SAlan Wright * Request for a user's password policy information.
1179da6c28aaSamw */
1180da6c28aaSamw /*ARGSUSED*/
1181da6c28aaSamw static int
samr_s_GetUserPwInfo(void * arg,ndr_xa_t * mxa)11828d7e4166Sjose borrego samr_s_GetUserPwInfo(void *arg, ndr_xa_t *mxa)
1183da6c28aaSamw {
1184f96bd5c8SAlan Wright static samr_password_info_t pwinfo;
1185f96bd5c8SAlan Wright struct samr_GetUserPwInfo *param = arg;
1186da6c28aaSamw
1187f96bd5c8SAlan Wright param->pwinfo = &pwinfo;
1188f96bd5c8SAlan Wright param->status = NT_STATUS_SUCCESS;
11898d7e4166Sjose borrego return (NDR_DRC_OK);
1190da6c28aaSamw }
1191da6c28aaSamw
1192da6c28aaSamw /*
1193da6c28aaSamw * samr_s_CreateUser
1194da6c28aaSamw */
1195da6c28aaSamw /*ARGSUSED*/
1196da6c28aaSamw static int
samr_s_CreateUser(void * arg,ndr_xa_t * mxa)11978d7e4166Sjose borrego samr_s_CreateUser(void *arg, ndr_xa_t *mxa)
1198da6c28aaSamw {
1199da6c28aaSamw struct samr_CreateUser *param = arg;
1200da6c28aaSamw
1201da6c28aaSamw bzero(¶m->user_handle, sizeof (samr_handle_t));
1202da6c28aaSamw param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
12038d7e4166Sjose borrego return (NDR_DRC_OK);
1204da6c28aaSamw }
1205da6c28aaSamw
1206da6c28aaSamw /*
12071ed6b69aSGordon Ross * samr_s_ChangePasswordUser2
1208da6c28aaSamw */
1209da6c28aaSamw /*ARGSUSED*/
1210da6c28aaSamw static int
samr_s_ChangePasswordUser2(void * arg,ndr_xa_t * mxa)12111ed6b69aSGordon Ross samr_s_ChangePasswordUser2(void *arg, ndr_xa_t *mxa)
1212da6c28aaSamw {
12131ed6b69aSGordon Ross struct samr_ChangePasswordUser2 *param = arg;
1214da6c28aaSamw
12151ed6b69aSGordon Ross bzero(param, sizeof (*param));
1216da6c28aaSamw param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
12178d7e4166Sjose borrego return (NDR_DRC_OK);
1218da6c28aaSamw }
1219da6c28aaSamw
1220da6c28aaSamw /*
1221da6c28aaSamw * samr_s_GetDomainPwInfo
1222f96bd5c8SAlan Wright *
1223f96bd5c8SAlan Wright * Request for the domain password policy information.
1224da6c28aaSamw */
1225da6c28aaSamw /*ARGSUSED*/
1226da6c28aaSamw static int
samr_s_GetDomainPwInfo(void * arg,ndr_xa_t * mxa)12278d7e4166Sjose borrego samr_s_GetDomainPwInfo(void *arg, ndr_xa_t *mxa)
1228da6c28aaSamw {
1229f96bd5c8SAlan Wright static samr_password_info_t pwinfo;
1230f96bd5c8SAlan Wright struct samr_GetDomainPwInfo *param = arg;
1231da6c28aaSamw
1232f96bd5c8SAlan Wright param->pwinfo = &pwinfo;
1233f96bd5c8SAlan Wright param->status = NT_STATUS_SUCCESS;
12348d7e4166Sjose borrego return (NDR_DRC_OK);
1235da6c28aaSamw }
1236da6c28aaSamw
1237da6c28aaSamw /*
1238da6c28aaSamw * samr_s_SetUserInfo
1239da6c28aaSamw */
1240da6c28aaSamw /*ARGSUSED*/
1241da6c28aaSamw static int
samr_s_SetUserInfo(void * arg,ndr_xa_t * mxa)12428d7e4166Sjose borrego samr_s_SetUserInfo(void *arg, ndr_xa_t *mxa)
1243da6c28aaSamw {
1244da6c28aaSamw struct samr_SetUserInfo *param = arg;
1245da6c28aaSamw
1246da6c28aaSamw bzero(param, sizeof (struct samr_SetUserInfo));
1247da6c28aaSamw param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
12488d7e4166Sjose borrego return (NDR_DRC_OK);
1249da6c28aaSamw }
1250da6c28aaSamw
1251da6c28aaSamw /*
1252da6c28aaSamw * samr_s_QueryDispInfo
1253da6c28aaSamw *
12543db3f65cSamw * This function currently return local users' information only.
12553db3f65cSamw * This RPC is called repeatedly until all the users info are
12563db3f65cSamw * retrieved.
1257da6c28aaSamw *
12583db3f65cSamw * The total count and the returned count are returned as total size
12593db3f65cSamw * and returned size. The client doesn't seem to care.
1260da6c28aaSamw */
1261da6c28aaSamw static int
samr_s_QueryDispInfo(void * arg,ndr_xa_t * mxa)12628d7e4166Sjose borrego samr_s_QueryDispInfo(void *arg, ndr_xa_t *mxa)
1263da6c28aaSamw {
1264da6c28aaSamw struct samr_QueryDispInfo *param = arg;
1265dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
12663db3f65cSamw ndr_handle_t *hd;
12673db3f65cSamw samr_keydata_t *data;
12683db3f65cSamw DWORD status = NT_STATUS_SUCCESS;
12693db3f65cSamw struct user_acct_info *user;
12703db3f65cSamw smb_pwditer_t pwi;
12713db3f65cSamw smb_luser_t *uinfo;
12723db3f65cSamw int num_users;
12737f667e74Sjose borrego int start_idx;
12747f667e74Sjose borrego int max_retcnt, retcnt;
12757f667e74Sjose borrego int skip;
1276da6c28aaSamw
12773db3f65cSamw if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
12783db3f65cSamw status = NT_STATUS_INVALID_HANDLE;
12793db3f65cSamw goto error;
1280dc20a302Sas }
1281da6c28aaSamw
12823db3f65cSamw if (!SAMR_VALID_DISPLEVEL(param->level)) {
12833db3f65cSamw status = NT_STATUS_INVALID_INFO_CLASS;
12843db3f65cSamw goto error;
12853db3f65cSamw }
1286da6c28aaSamw
12873db3f65cSamw if (!SAMR_SUPPORTED_DISPLEVEL(param->level)) {
12883db3f65cSamw status = NT_STATUS_NOT_IMPLEMENTED;
12893db3f65cSamw goto error;
12903db3f65cSamw }
1291da6c28aaSamw
12923db3f65cSamw data = (samr_keydata_t *)hd->nh_data;
1293da6c28aaSamw
12943db3f65cSamw switch (data->kd_type) {
1295a0aa776eSAlan Wright case SMB_DOMAIN_BUILTIN:
12963db3f65cSamw goto no_info;
1297da6c28aaSamw
1298a0aa776eSAlan Wright case SMB_DOMAIN_LOCAL:
12997f667e74Sjose borrego num_users = smb_sam_usr_cnt();
13003db3f65cSamw start_idx = param->start_idx;
13013db3f65cSamw if ((num_users == 0) || (start_idx >= num_users))
13023db3f65cSamw goto no_info;
13033db3f65cSamw
13047f667e74Sjose borrego max_retcnt = num_users - start_idx;
13057f667e74Sjose borrego if (max_retcnt > param->max_entries)
13067f667e74Sjose borrego max_retcnt = param->max_entries;
13078d7e4166Sjose borrego param->users.acct = NDR_MALLOC(mxa,
13087f667e74Sjose borrego max_retcnt * sizeof (struct user_acct_info));
13093db3f65cSamw user = param->users.acct;
13103db3f65cSamw if (user == NULL) {
13113db3f65cSamw status = NT_STATUS_NO_MEMORY;
13123db3f65cSamw goto error;
13133db3f65cSamw }
13147f667e74Sjose borrego bzero(user, max_retcnt * sizeof (struct user_acct_info));
13153db3f65cSamw
13163db3f65cSamw if (smb_pwd_iteropen(&pwi) != SMB_PWE_SUCCESS)
13173db3f65cSamw goto no_info;
13183db3f65cSamw
13197f667e74Sjose borrego skip = retcnt = 0;
13203db3f65cSamw while ((uinfo = smb_pwd_iterate(&pwi)) != NULL) {
13217f667e74Sjose borrego if (skip++ < start_idx)
13223db3f65cSamw continue;
13233db3f65cSamw
13247f667e74Sjose borrego if (retcnt++ >= max_retcnt)
13257f667e74Sjose borrego break;
13267f667e74Sjose borrego
13273db3f65cSamw assert(uinfo->su_name != NULL);
13283db3f65cSamw
13297f667e74Sjose borrego user->index = start_idx + retcnt;
13303db3f65cSamw user->rid = uinfo->su_rid;
13313db3f65cSamw user->ctrl = ACF_NORMUSER | ACF_PWDNOEXP;
13323db3f65cSamw if (uinfo->su_ctrl & SMB_PWF_DISABLE)
13333db3f65cSamw user->ctrl |= ACF_DISABLED;
13348d7e4166Sjose borrego if (NDR_MSTRING(mxa, uinfo->su_name,
13358d7e4166Sjose borrego (ndr_mstring_t *)&user->name) == -1) {
13363db3f65cSamw smb_pwd_iterclose(&pwi);
13373db3f65cSamw status = NT_STATUS_NO_MEMORY;
13383db3f65cSamw goto error;
13393db3f65cSamw }
13408d7e4166Sjose borrego (void) NDR_MSTRING(mxa, uinfo->su_fullname,
13418d7e4166Sjose borrego (ndr_mstring_t *)&user->fullname);
13428d7e4166Sjose borrego (void) NDR_MSTRING(mxa, uinfo->su_desc,
13438d7e4166Sjose borrego (ndr_mstring_t *)&user->desc);
13443db3f65cSamw user++;
13453db3f65cSamw }
13463db3f65cSamw smb_pwd_iterclose(&pwi);
1347da6c28aaSamw
13487f667e74Sjose borrego if (retcnt >= max_retcnt) {
13497f667e74Sjose borrego retcnt = max_retcnt;
13507f667e74Sjose borrego param->status = status;
13517f667e74Sjose borrego } else {
1352148c5f43SAlan Wright param->status = NT_STATUS_MORE_ENTRIES;
13537f667e74Sjose borrego }
13547f667e74Sjose borrego
13553db3f65cSamw param->users.total_size = num_users;
13567f667e74Sjose borrego param->users.returned_size = retcnt;
13573db3f65cSamw param->users.switch_value = param->level;
13587f667e74Sjose borrego param->users.count = retcnt;
1359da6c28aaSamw
13603db3f65cSamw break;
1361da6c28aaSamw
13623db3f65cSamw default:
13633db3f65cSamw status = NT_STATUS_INVALID_HANDLE;
13643db3f65cSamw goto error;
1365da6c28aaSamw }
13663db3f65cSamw
13678d7e4166Sjose borrego return (NDR_DRC_OK);
13683db3f65cSamw
13693db3f65cSamw no_info:
13703db3f65cSamw param->users.total_size = 0;
13713db3f65cSamw param->users.returned_size = 0;
13723db3f65cSamw param->users.switch_value = param->level;
13733db3f65cSamw param->users.count = 0;
13743db3f65cSamw param->users.acct = NULL;
13753db3f65cSamw param->status = status;
13768d7e4166Sjose borrego return (NDR_DRC_OK);
13773db3f65cSamw
13783db3f65cSamw error:
13793db3f65cSamw bzero(param, sizeof (struct samr_QueryDispInfo));
13803db3f65cSamw param->status = NT_SC_ERROR(status);
13818d7e4166Sjose borrego return (NDR_DRC_OK);
1382da6c28aaSamw }
1383da6c28aaSamw
1384da6c28aaSamw /*
1385da6c28aaSamw * samr_s_EnumDomainGroups
1386da6c28aaSamw *
1387da6c28aaSamw *
1388dc20a302Sas * This function is supposed to return local group information.
1389da6c28aaSamw * As we don't support local users, this function dosen't send
1390da6c28aaSamw * back any information.
1391da6c28aaSamw *
1392dc20a302Sas * Added template that returns information for a domain group as None.
1393dc20a302Sas * All information is hard-coded from packet captures.
1394da6c28aaSamw */
1395da6c28aaSamw static int
samr_s_EnumDomainGroups(void * arg,ndr_xa_t * mxa)13968d7e4166Sjose borrego samr_s_EnumDomainGroups(void *arg, ndr_xa_t *mxa)
1397da6c28aaSamw {
1398da6c28aaSamw struct samr_EnumDomainGroups *param = arg;
1399dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
1400da6c28aaSamw DWORD status = NT_STATUS_SUCCESS;
1401da6c28aaSamw
1402dc20a302Sas if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL)
1403da6c28aaSamw status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1404da6c28aaSamw
1405da6c28aaSamw param->total_size = 0;
1406da6c28aaSamw param->returned_size = 0;
1407da6c28aaSamw param->switch_value = 3;
1408da6c28aaSamw param->count = 0;
1409da6c28aaSamw param->groups = 0;
1410da6c28aaSamw param->status = status;
14118d7e4166Sjose borrego return (NDR_DRC_OK);
1412da6c28aaSamw
1413da6c28aaSamw #ifdef SAMR_SUPPORT_GROUPS
1414da6c28aaSamw if ((desc->discrim != SAMR_LOCAL_DOMAIN) || (param->start_idx != 0)) {
1415da6c28aaSamw param->total_size = 0;
1416da6c28aaSamw param->returned_size = 0;
1417da6c28aaSamw param->switch_value = 3;
1418da6c28aaSamw param->count = 0;
1419da6c28aaSamw param->groups = 0;
1420da6c28aaSamw } else {
1421da6c28aaSamw param->total_size = 64;
1422da6c28aaSamw param->returned_size = 64;
1423da6c28aaSamw param->switch_value = 3;
1424da6c28aaSamw param->count = 1;
14258d7e4166Sjose borrego param->groups = (struct group_disp_info *)NDR_MALLOC(
1426da6c28aaSamw mxa, sizeof (struct group_disp_info));
1427da6c28aaSamw
1428da6c28aaSamw param->groups->count = 1;
1429da6c28aaSamw param->groups->acct[0].index = 1;
1430da6c28aaSamw param->groups->acct[0].rid = 513;
1431da6c28aaSamw param->groups->acct[0].ctrl = 0x7;
14328d7e4166Sjose borrego (void) NDR_MSTRING(mxa, "None",
14338d7e4166Sjose borrego (ndr_mstring_t *)¶m->groups->acct[0].name);
1434da6c28aaSamw
14358d7e4166Sjose borrego (void) NDR_MSTRING(mxa, "Ordinary users",
14368d7e4166Sjose borrego (ndr_mstring_t *)¶m->groups->acct[0].desc);
1437da6c28aaSamw }
1438da6c28aaSamw
1439da6c28aaSamw param->status = NT_STATUS_SUCCESS;
14408d7e4166Sjose borrego return (NDR_DRC_OK);
1441da6c28aaSamw #endif
1442da6c28aaSamw }
1443da6c28aaSamw
1444da6c28aaSamw /*
1445da6c28aaSamw * samr_s_OpenAlias
1446da6c28aaSamw *
1447da6c28aaSamw * Lookup for requested alias, if it exists return a handle
1448da6c28aaSamw * for that alias. The alias domain sid should match with
1449da6c28aaSamw * the passed domain handle.
1450da6c28aaSamw */
1451da6c28aaSamw static int
samr_s_OpenAlias(void * arg,ndr_xa_t * mxa)14528d7e4166Sjose borrego samr_s_OpenAlias(void *arg, ndr_xa_t *mxa)
1453da6c28aaSamw {
1454da6c28aaSamw struct samr_OpenAlias *param = arg;
1455f96bd5c8SAlan Wright ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
1456f96bd5c8SAlan Wright ndr_handle_t *hd;
1457f96bd5c8SAlan Wright samr_keydata_t *data;
14589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_domain_type_t gd_type;
1459f96bd5c8SAlan Wright smb_sid_t *sid;
1460f96bd5c8SAlan Wright smb_wka_t *wka;
1461f96bd5c8SAlan Wright char sidstr[SMB_SID_STRSZ];
1462f96bd5c8SAlan Wright uint32_t rid;
1463f96bd5c8SAlan Wright uint32_t status;
1464f96bd5c8SAlan Wright int rc;
1465da6c28aaSamw
1466dc20a302Sas if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
1467da6c28aaSamw status = NT_STATUS_INVALID_HANDLE;
1468da6c28aaSamw goto open_alias_err;
1469da6c28aaSamw }
1470da6c28aaSamw
1471c5866007SKeyur Desai if ((param->access_mask & SAMR_ALIAS_ACCESS_ALL_ACCESS) == 0) {
1472da6c28aaSamw status = NT_STATUS_ACCESS_DENIED;
1473da6c28aaSamw goto open_alias_err;
1474da6c28aaSamw }
1475da6c28aaSamw
1476dc20a302Sas data = (samr_keydata_t *)hd->nh_data;
14779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States gd_type = (smb_domain_type_t)data->kd_type;
1478f96bd5c8SAlan Wright rid = param->rid;
1479f96bd5c8SAlan Wright
1480f96bd5c8SAlan Wright switch (gd_type) {
14819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_DOMAIN_BUILTIN:
1482f96bd5c8SAlan Wright (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d",
1483f96bd5c8SAlan Wright NT_BUILTIN_DOMAIN_SIDSTR, rid);
1484f96bd5c8SAlan Wright if ((sid = smb_sid_fromstr(sidstr)) == NULL) {
1485f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1486f96bd5c8SAlan Wright goto open_alias_err;
1487f96bd5c8SAlan Wright }
1488f96bd5c8SAlan Wright
1489f96bd5c8SAlan Wright wka = smb_wka_lookup_sid(sid);
1490f96bd5c8SAlan Wright smb_sid_free(sid);
1491f96bd5c8SAlan Wright
1492f96bd5c8SAlan Wright if (wka == NULL) {
1493f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1494f96bd5c8SAlan Wright goto open_alias_err;
1495f96bd5c8SAlan Wright }
1496f96bd5c8SAlan Wright break;
1497f96bd5c8SAlan Wright
14989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_DOMAIN_LOCAL:
1499f96bd5c8SAlan Wright rc = smb_lgrp_getbyrid(rid, gd_type, NULL);
1500f96bd5c8SAlan Wright if (rc != SMB_LGRP_SUCCESS) {
1501f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1502f96bd5c8SAlan Wright goto open_alias_err;
1503f96bd5c8SAlan Wright }
1504f96bd5c8SAlan Wright break;
1505f96bd5c8SAlan Wright
1506f96bd5c8SAlan Wright default:
1507da6c28aaSamw status = NT_STATUS_NO_SUCH_ALIAS;
1508da6c28aaSamw goto open_alias_err;
1509da6c28aaSamw }
1510da6c28aaSamw
1511dc20a302Sas id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, data->kd_type, param->rid);
1512dc20a302Sas if (id) {
1513dc20a302Sas bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t));
1514dc20a302Sas param->status = NT_STATUS_SUCCESS;
15158d7e4166Sjose borrego return (NDR_DRC_OK);
1516da6c28aaSamw }
1517da6c28aaSamw
1518dc20a302Sas status = NT_STATUS_NO_MEMORY;
1519da6c28aaSamw
1520da6c28aaSamw open_alias_err:
1521da6c28aaSamw bzero(¶m->alias_handle, sizeof (samr_handle_t));
1522da6c28aaSamw param->status = NT_SC_ERROR(status);
15238d7e4166Sjose borrego return (NDR_DRC_OK);
1524da6c28aaSamw }
1525da6c28aaSamw
1526da6c28aaSamw /*
1527da6c28aaSamw * samr_s_CreateDomainAlias
1528da6c28aaSamw *
1529c5866007SKeyur Desai * Create a local group in the security accounts manager (SAM) database.
1530c5866007SKeyur Desai * A local SAM group can only be added if a Solaris group already exists
1531c5866007SKeyur Desai * with the same name. On success, a valid group handle is returned.
1532c5866007SKeyur Desai *
1533c5866007SKeyur Desai * The caller must have administrator rights to execute this function.
1534da6c28aaSamw */
1535da6c28aaSamw static int
samr_s_CreateDomainAlias(void * arg,ndr_xa_t * mxa)15368d7e4166Sjose borrego samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa)
1537da6c28aaSamw {
1538da6c28aaSamw struct samr_CreateDomainAlias *param = arg;
1539dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1540c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS;
1541c5866007SKeyur Desai smb_group_t grp;
1542c5866007SKeyur Desai uint32_t rc;
1543c5866007SKeyur Desai char *gname;
1544dc20a302Sas
1545c5866007SKeyur Desai if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) != NULL) {
1546dc20a302Sas bzero(param, sizeof (struct samr_CreateDomainAlias));
1547dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
15488d7e4166Sjose borrego return (NDR_DRC_OK);
1549dc20a302Sas }
1550dc20a302Sas
1551c5866007SKeyur Desai gname = (char *)param->alias_name.str;
1552c5866007SKeyur Desai if (gname == NULL) {
1553c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t));
1554c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
1555c5866007SKeyur Desai return (NDR_DRC_OK);
1556da6c28aaSamw }
1557da6c28aaSamw
1558c5866007SKeyur Desai if ((!ndr_is_admin(mxa)) ||
1559c5866007SKeyur Desai ((param->access_mask & SAMR_ALIAS_ACCESS_WRITE_ACCOUNT) == 0)) {
1560c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t));
1561c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
1562c5866007SKeyur Desai return (NDR_DRC_OK);
1563c5866007SKeyur Desai }
1564da6c28aaSamw
1565c5866007SKeyur Desai rc = smb_lgrp_add(gname, "");
1566c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1567c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t));
1568c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1569c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
1570c5866007SKeyur Desai return (NDR_DRC_OK);
1571da6c28aaSamw }
1572da6c28aaSamw
1573c5866007SKeyur Desai rc = smb_lgrp_getbyname((char *)gname, &grp);
1574c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1575c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t));
1576c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1577c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
1578c5866007SKeyur Desai return (NDR_DRC_OK);
1579c5866007SKeyur Desai }
1580da6c28aaSamw
1581c5866007SKeyur Desai id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, SMB_DOMAIN_LOCAL, grp.sg_rid);
1582c5866007SKeyur Desai smb_lgrp_free(&grp);
1583c5866007SKeyur Desai if (id) {
1584c5866007SKeyur Desai bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t));
1585c5866007SKeyur Desai param->status = status;
1586c5866007SKeyur Desai } else {
1587c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t));
1588c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1589c5866007SKeyur Desai }
1590da6c28aaSamw
15918d7e4166Sjose borrego return (NDR_DRC_OK);
1592da6c28aaSamw }
1593da6c28aaSamw
1594da6c28aaSamw /*
1595da6c28aaSamw * samr_s_SetAliasInfo
1596da6c28aaSamw *
1597dc20a302Sas * Similar to NetLocalGroupSetInfo.
1598da6c28aaSamw */
1599da6c28aaSamw static int
samr_s_SetAliasInfo(void * arg,ndr_xa_t * mxa)16008d7e4166Sjose borrego samr_s_SetAliasInfo(void *arg, ndr_xa_t *mxa)
1601da6c28aaSamw {
1602da6c28aaSamw struct samr_SetAliasInfo *param = arg;
1603dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1604da6c28aaSamw DWORD status = NT_STATUS_SUCCESS;
1605da6c28aaSamw
1606dc20a302Sas if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL)
1607da6c28aaSamw status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1608da6c28aaSamw
1609da6c28aaSamw param->status = status;
16108d7e4166Sjose borrego return (NDR_DRC_OK);
1611da6c28aaSamw }
1612da6c28aaSamw
1613da6c28aaSamw /*
1614da6c28aaSamw * samr_s_QueryAliasInfo
1615da6c28aaSamw *
1616da6c28aaSamw * Retrieves information about the specified local group account
1617da6c28aaSamw * by given handle.
1618da6c28aaSamw */
1619da6c28aaSamw static int
samr_s_QueryAliasInfo(void * arg,ndr_xa_t * mxa)16208d7e4166Sjose borrego samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa)
1621da6c28aaSamw {
1622da6c28aaSamw struct samr_QueryAliasInfo *param = arg;
1623f96bd5c8SAlan Wright ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1624f96bd5c8SAlan Wright ndr_handle_t *hd;
1625f96bd5c8SAlan Wright samr_keydata_t *data;
1626f96bd5c8SAlan Wright smb_group_t grp;
16279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_domain_type_t gd_type;
1628f96bd5c8SAlan Wright smb_sid_t *sid;
1629f96bd5c8SAlan Wright smb_wka_t *wka;
1630f96bd5c8SAlan Wright char sidstr[SMB_SID_STRSZ];
1631f96bd5c8SAlan Wright char *name;
1632f96bd5c8SAlan Wright char *desc;
1633f96bd5c8SAlan Wright uint32_t rid;
1634f96bd5c8SAlan Wright uint32_t status;
1635f96bd5c8SAlan Wright int rc;
1636da6c28aaSamw
1637dc20a302Sas if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
1638da6c28aaSamw status = NT_STATUS_INVALID_HANDLE;
1639da6c28aaSamw goto query_alias_err;
1640da6c28aaSamw }
1641da6c28aaSamw
1642dc20a302Sas data = (samr_keydata_t *)hd->nh_data;
16439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States gd_type = (smb_domain_type_t)data->kd_type;
1644f96bd5c8SAlan Wright rid = data->kd_rid;
1645f96bd5c8SAlan Wright
1646f96bd5c8SAlan Wright switch (gd_type) {
16479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_DOMAIN_BUILTIN:
1648f96bd5c8SAlan Wright (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d",
1649f96bd5c8SAlan Wright NT_BUILTIN_DOMAIN_SIDSTR, rid);
1650f96bd5c8SAlan Wright if ((sid = smb_sid_fromstr(sidstr)) == NULL) {
1651f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1652f96bd5c8SAlan Wright goto query_alias_err;
1653f96bd5c8SAlan Wright }
1654f96bd5c8SAlan Wright
1655f96bd5c8SAlan Wright wka = smb_wka_lookup_sid(sid);
1656f96bd5c8SAlan Wright smb_sid_free(sid);
1657f96bd5c8SAlan Wright
1658f96bd5c8SAlan Wright if (wka == NULL) {
1659f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1660f96bd5c8SAlan Wright goto query_alias_err;
1661f96bd5c8SAlan Wright }
1662f96bd5c8SAlan Wright
1663f96bd5c8SAlan Wright name = wka->wka_name;
1664f96bd5c8SAlan Wright desc = (wka->wka_desc != NULL) ? wka->wka_desc : "";
1665f96bd5c8SAlan Wright break;
1666f96bd5c8SAlan Wright
16679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_DOMAIN_LOCAL:
1668f96bd5c8SAlan Wright rc = smb_lgrp_getbyrid(rid, gd_type, &grp);
1669f96bd5c8SAlan Wright if (rc != SMB_LGRP_SUCCESS) {
1670f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1671f96bd5c8SAlan Wright goto query_alias_err;
1672f96bd5c8SAlan Wright }
1673f96bd5c8SAlan Wright name = grp.sg_name;
1674f96bd5c8SAlan Wright desc = grp.sg_cmnt;
1675f96bd5c8SAlan Wright break;
1676f96bd5c8SAlan Wright
1677f96bd5c8SAlan Wright default:
1678da6c28aaSamw status = NT_STATUS_NO_SUCH_ALIAS;
1679da6c28aaSamw goto query_alias_err;
1680da6c28aaSamw }
1681da6c28aaSamw
1682da6c28aaSamw switch (param->level) {
1683eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_GENERAL:
1684da6c28aaSamw param->ru.info1.level = param->level;
1685f96bd5c8SAlan Wright (void) NDR_MSTRING(mxa, name,
16868d7e4166Sjose borrego (ndr_mstring_t *)¶m->ru.info1.name);
1687f96bd5c8SAlan Wright (void) NDR_MSTRING(mxa, desc,
16888d7e4166Sjose borrego (ndr_mstring_t *)¶m->ru.info1.desc);
1689eef90b86SGordon Ross param->ru.info1.member_count = 1;
1690eef90b86SGordon Ross break;
1691da6c28aaSamw
1692eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_NAME:
1693eef90b86SGordon Ross param->ru.info2.level = param->level;
1694eef90b86SGordon Ross (void) NDR_MSTRING(mxa, name,
1695eef90b86SGordon Ross (ndr_mstring_t *)¶m->ru.info2.name);
1696da6c28aaSamw break;
1697da6c28aaSamw
1698eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_COMMENT:
1699da6c28aaSamw param->ru.info3.level = param->level;
1700f96bd5c8SAlan Wright (void) NDR_MSTRING(mxa, desc,
17018d7e4166Sjose borrego (ndr_mstring_t *)¶m->ru.info3.desc);
1702da6c28aaSamw break;
1703da6c28aaSamw
1704da6c28aaSamw default:
17059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (gd_type == SMB_DOMAIN_LOCAL)
1706f96bd5c8SAlan Wright smb_lgrp_free(&grp);
1707da6c28aaSamw status = NT_STATUS_INVALID_INFO_CLASS;
1708da6c28aaSamw goto query_alias_err;
1709da6c28aaSamw };
1710da6c28aaSamw
17119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (gd_type == SMB_DOMAIN_LOCAL)
1712f96bd5c8SAlan Wright smb_lgrp_free(&grp);
171355bf511dSas param->address = (DWORD)(uintptr_t)¶m->ru;
1714da6c28aaSamw param->status = 0;
17158d7e4166Sjose borrego return (NDR_DRC_OK);
1716da6c28aaSamw
1717da6c28aaSamw query_alias_err:
1718da6c28aaSamw param->status = NT_SC_ERROR(status);
17198d7e4166Sjose borrego return (NDR_DRC_OK);
1720da6c28aaSamw }
1721da6c28aaSamw
1722da6c28aaSamw /*
1723da6c28aaSamw * samr_s_DeleteDomainAlias
1724da6c28aaSamw *
1725c5866007SKeyur Desai * Deletes a local group in the security database, which is the
1726c5866007SKeyur Desai * security accounts manager (SAM). A valid group handle is returned
1727c5866007SKeyur Desai * to the caller upon success.
1728da6c28aaSamw *
1729c5866007SKeyur Desai * The caller must have administrator rights to execute this function.
1730da6c28aaSamw */
1731da6c28aaSamw static int
samr_s_DeleteDomainAlias(void * arg,ndr_xa_t * mxa)17328d7e4166Sjose borrego samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa)
1733da6c28aaSamw {
1734da6c28aaSamw struct samr_DeleteDomainAlias *param = arg;
1735dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1736c5866007SKeyur Desai ndr_handle_t *hd;
1737c5866007SKeyur Desai smb_group_t grp;
1738c5866007SKeyur Desai samr_keydata_t *data;
1739c5866007SKeyur Desai smb_domain_type_t gd_type;
1740c5866007SKeyur Desai uint32_t rid;
1741c5866007SKeyur Desai uint32_t rc;
1742c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS;
1743da6c28aaSamw
1744c5866007SKeyur Desai if (!ndr_is_admin(mxa)) {
1745dc20a302Sas bzero(param, sizeof (struct samr_DeleteDomainAlias));
1746c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
17478d7e4166Sjose borrego return (NDR_DRC_OK);
1748dc20a302Sas }
1749da6c28aaSamw
1750c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
1751c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias));
1752c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1753c5866007SKeyur Desai return (NDR_DRC_OK);
1754c5866007SKeyur Desai }
1755da6c28aaSamw
1756c5866007SKeyur Desai data = (samr_keydata_t *)hd->nh_data;
1757c5866007SKeyur Desai gd_type = (smb_domain_type_t)data->kd_type;
1758c5866007SKeyur Desai rid = data->kd_rid;
1759da6c28aaSamw
1760c5866007SKeyur Desai switch (gd_type) {
1761c5866007SKeyur Desai case SMB_DOMAIN_BUILTIN:
1762c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias));
1763c5866007SKeyur Desai status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED);
1764c5866007SKeyur Desai break;
1765da6c28aaSamw
1766c5866007SKeyur Desai case SMB_DOMAIN_LOCAL:
1767c5866007SKeyur Desai rc = smb_lgrp_getbyrid(rid, gd_type, &grp);
1768c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1769c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias));
1770c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1771c5866007SKeyur Desai status = NT_SC_ERROR(status);
1772c5866007SKeyur Desai break;
1773c5866007SKeyur Desai }
1774da6c28aaSamw
1775c5866007SKeyur Desai rc = smb_lgrp_delete(grp.sg_name);
1776c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1777c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias));
1778c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1779c5866007SKeyur Desai status = NT_SC_ERROR(status);
1780c5866007SKeyur Desai }
1781c5866007SKeyur Desai smb_lgrp_free(&grp);
1782c5866007SKeyur Desai break;
1783da6c28aaSamw
1784c5866007SKeyur Desai default:
1785c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias));
1786c5866007SKeyur Desai status = NT_SC_ERROR(NT_STATUS_NO_SUCH_ALIAS);
1787c5866007SKeyur Desai }
1788da6c28aaSamw
1789c5866007SKeyur Desai param->status = status;
17908d7e4166Sjose borrego return (NDR_DRC_OK);
1791da6c28aaSamw }
1792da6c28aaSamw
1793da6c28aaSamw /*
1794da6c28aaSamw * samr_s_EnumDomainAliases
1795da6c28aaSamw *
1796da6c28aaSamw * This function sends back a list which contains all local groups' name.
1797da6c28aaSamw */
1798da6c28aaSamw static int
samr_s_EnumDomainAliases(void * arg,ndr_xa_t * mxa)17998d7e4166Sjose borrego samr_s_EnumDomainAliases(void *arg, ndr_xa_t *mxa)
1800da6c28aaSamw {
1801da6c28aaSamw struct samr_EnumDomainAliases *param = arg;
1802dc20a302Sas ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
1803dc20a302Sas ndr_handle_t *hd;
1804dc20a302Sas samr_keydata_t *data;
1805dc20a302Sas smb_group_t grp;
1806dc20a302Sas smb_giter_t gi;
1807dc20a302Sas int cnt, skip, i;
1808da6c28aaSamw struct name_rid *info;
1809da6c28aaSamw
1810dc20a302Sas if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
1811dc20a302Sas bzero(param, sizeof (struct samr_EnumDomainAliases));
1812dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
18138d7e4166Sjose borrego return (NDR_DRC_OK);
1814da6c28aaSamw }
1815da6c28aaSamw
1816dc20a302Sas data = (samr_keydata_t *)hd->nh_data;
1817da6c28aaSamw
18187f667e74Sjose borrego cnt = smb_sam_grp_cnt(data->kd_type);
1819dc20a302Sas if (cnt <= param->resume_handle) {
18208d7e4166Sjose borrego param->aliases = (struct aliases_info *)NDR_MALLOC(mxa,
1821dc20a302Sas sizeof (struct aliases_info));
1822da6c28aaSamw
18233db3f65cSamw if (param->aliases == NULL) {
18243db3f65cSamw bzero(param, sizeof (struct samr_EnumDomainAliases));
18253db3f65cSamw param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
18268d7e4166Sjose borrego return (NDR_DRC_OK);
18273db3f65cSamw }
18283db3f65cSamw
1829dc20a302Sas bzero(param->aliases, sizeof (struct aliases_info));
1830dc20a302Sas param->out_resume = 0;
1831dc20a302Sas param->entries = 0;
1832dc20a302Sas param->status = NT_STATUS_SUCCESS;
18338d7e4166Sjose borrego return (NDR_DRC_OK);
1834da6c28aaSamw }
1835da6c28aaSamw
1836dc20a302Sas cnt -= param->resume_handle;
18378d7e4166Sjose borrego param->aliases = (struct aliases_info *)NDR_MALLOC(mxa,
1838da6c28aaSamw sizeof (struct aliases_info) + (cnt-1) * sizeof (struct name_rid));
1839da6c28aaSamw
18403db3f65cSamw if (param->aliases == NULL) {
18413db3f65cSamw bzero(param, sizeof (struct samr_EnumDomainAliases));
18423db3f65cSamw param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
18438d7e4166Sjose borrego return (NDR_DRC_OK);
18443db3f65cSamw }
18453db3f65cSamw
1846dc20a302Sas if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
1847dc20a302Sas bzero(param, sizeof (struct samr_EnumDomainAliases));
1848dc20a302Sas param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR);
18498d7e4166Sjose borrego return (NDR_DRC_OK);
1850dc20a302Sas }
1851da6c28aaSamw
1852dc20a302Sas skip = i = 0;
1853dc20a302Sas info = param->aliases->info;
1854dc20a302Sas while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) {
1855dc20a302Sas if ((skip++ >= param->resume_handle) &&
1856dc20a302Sas (grp.sg_domain == data->kd_type) && (i++ < cnt)) {
1857dc20a302Sas info->rid = grp.sg_rid;
18588d7e4166Sjose borrego (void) NDR_MSTRING(mxa, grp.sg_name,
18598d7e4166Sjose borrego (ndr_mstring_t *)&info->name);
1860da6c28aaSamw
1861da6c28aaSamw info++;
1862da6c28aaSamw }
1863dc20a302Sas smb_lgrp_free(&grp);
1864da6c28aaSamw }
1865dc20a302Sas smb_lgrp_iterclose(&gi);
1866da6c28aaSamw
1867dc20a302Sas param->aliases->count = i;
1868dc20a302Sas param->aliases->address = i;
1869da6c28aaSamw
1870dc20a302Sas param->out_resume = i;
1871dc20a302Sas param->entries = i;
1872dc20a302Sas param->status = 0;
18738d7e4166Sjose borrego return (NDR_DRC_OK);
1874da6c28aaSamw }
1875da6c28aaSamw
1876da6c28aaSamw /*
1877cb174861Sjoyce mcintosh * samr_s_Connect4
1878da6c28aaSamw */
1879da6c28aaSamw static int
samr_s_Connect4(void * arg,ndr_xa_t * mxa)1880cb174861Sjoyce mcintosh samr_s_Connect4(void *arg, ndr_xa_t *mxa)
1881da6c28aaSamw {
1882cb174861Sjoyce mcintosh struct samr_Connect4 *param = arg;
1883f96bd5c8SAlan Wright ndr_hdid_t *id;
1884da6c28aaSamw
1885f96bd5c8SAlan Wright id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
1886f96bd5c8SAlan Wright if (id) {
1887f96bd5c8SAlan Wright bcopy(id, ¶m->handle, sizeof (samr_handle_t));
1888f96bd5c8SAlan Wright param->status = 0;
1889f96bd5c8SAlan Wright } else {
1890f96bd5c8SAlan Wright bzero(¶m->handle, sizeof (samr_handle_t));
1891f96bd5c8SAlan Wright param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1892f96bd5c8SAlan Wright }
1893da6c28aaSamw
1894f96bd5c8SAlan Wright return (NDR_DRC_OK);
1895f96bd5c8SAlan Wright }
1896da6c28aaSamw
1897da6c28aaSamw /*
1898cb174861Sjoyce mcintosh * samr_s_Connect5
1899da6c28aaSamw *
1900cb174861Sjoyce mcintosh * This is the connect5 form of the connect request used by Windows XP.
1901da6c28aaSamw * Returns an RPC fault for now.
1902da6c28aaSamw */
1903da6c28aaSamw /*ARGSUSED*/
1904da6c28aaSamw static int
samr_s_Connect5(void * arg,ndr_xa_t * mxa)1905cb174861Sjoyce mcintosh samr_s_Connect5(void *arg, ndr_xa_t *mxa)
1906da6c28aaSamw {
1907cb174861Sjoyce mcintosh struct samr_Connect5 *param = arg;
1908da6c28aaSamw
1909cb174861Sjoyce mcintosh bzero(param, sizeof (struct samr_Connect5));
19108d7e4166Sjose borrego return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
1911da6c28aaSamw }
1912da6c28aaSamw
19138d7e4166Sjose borrego static ndr_stub_table_t samr_stub_table[] = {
1914cb174861Sjoyce mcintosh { samr_s_Connect, SAMR_OPNUM_Connect },
1915da6c28aaSamw { samr_s_CloseHandle, SAMR_OPNUM_CloseHandle },
1916*9242c919SMatt Barden { samr_s_QuerySecObject, SAMR_OPNUM_QuerySecObject },
1917da6c28aaSamw { samr_s_LookupDomain, SAMR_OPNUM_LookupDomain },
1918da6c28aaSamw { samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains },
1919da6c28aaSamw { samr_s_OpenDomain, SAMR_OPNUM_OpenDomain },
1920da6c28aaSamw { samr_s_QueryDomainInfo, SAMR_OPNUM_QueryDomainInfo },
1921f96bd5c8SAlan Wright { samr_s_QueryInfoDomain2, SAMR_OPNUM_QueryInfoDomain2 },
1922da6c28aaSamw { samr_s_LookupNames, SAMR_OPNUM_LookupNames },
1923da6c28aaSamw { samr_s_OpenUser, SAMR_OPNUM_OpenUser },
1924da6c28aaSamw { samr_s_DeleteUser, SAMR_OPNUM_DeleteUser },
1925da6c28aaSamw { samr_s_QueryUserInfo, SAMR_OPNUM_QueryUserInfo },
1926da6c28aaSamw { samr_s_QueryUserGroups, SAMR_OPNUM_QueryUserGroups },
1927da6c28aaSamw { samr_s_OpenGroup, SAMR_OPNUM_OpenGroup },
1928cb174861Sjoyce mcintosh { samr_s_Connect2, SAMR_OPNUM_Connect2 },
1929da6c28aaSamw { samr_s_GetUserPwInfo, SAMR_OPNUM_GetUserPwInfo },
1930da6c28aaSamw { samr_s_CreateUser, SAMR_OPNUM_CreateUser },
19311ed6b69aSGordon Ross { samr_s_ChangePasswordUser2, SAMR_OPNUM_ChangePasswordUser2 },
1932da6c28aaSamw { samr_s_GetDomainPwInfo, SAMR_OPNUM_GetDomainPwInfo },
1933da6c28aaSamw { samr_s_SetUserInfo, SAMR_OPNUM_SetUserInfo },
1934da6c28aaSamw { samr_s_Connect4, SAMR_OPNUM_Connect4 },
1935cb174861Sjoyce mcintosh { samr_s_Connect5, SAMR_OPNUM_Connect5 },
1936da6c28aaSamw { samr_s_QueryDispInfo, SAMR_OPNUM_QueryDispInfo },
1937da6c28aaSamw { samr_s_OpenAlias, SAMR_OPNUM_OpenAlias },
1938da6c28aaSamw { samr_s_CreateDomainAlias, SAMR_OPNUM_CreateDomainAlias },
1939da6c28aaSamw { samr_s_SetAliasInfo, SAMR_OPNUM_SetAliasInfo },
1940da6c28aaSamw { samr_s_QueryAliasInfo, SAMR_OPNUM_QueryAliasInfo },
1941da6c28aaSamw { samr_s_DeleteDomainAlias, SAMR_OPNUM_DeleteDomainAlias },
1942da6c28aaSamw { samr_s_EnumDomainAliases, SAMR_OPNUM_EnumDomainAliases },
1943da6c28aaSamw { samr_s_EnumDomainGroups, SAMR_OPNUM_EnumDomainGroups },
1944c5866007SKeyur Desai { samr_s_AddAliasMember, SAMR_OPNUM_AddAliasMember },
1945c5866007SKeyur Desai { samr_s_DeleteAliasMember, SAMR_OPNUM_DeleteAliasMember },
1946c5866007SKeyur Desai { samr_s_ListAliasMembers, SAMR_OPNUM_ListAliasMembers },
1947da6c28aaSamw {0}
1948da6c28aaSamw };
1949da6c28aaSamw
1950da6c28aaSamw /*
1951da6c28aaSamw * There is a bug in the way that midl and the marshalling code handles
1952da6c28aaSamw * unions so we need to fix some of the data offsets at runtime. The
1953da6c28aaSamw * following macros and the fixup functions handle the corrections.
1954da6c28aaSamw */
1955da6c28aaSamw
1956da6c28aaSamw DECL_FIXUP_STRUCT(samr_QueryAliasInfo_ru);
1957da6c28aaSamw DECL_FIXUP_STRUCT(samr_QueryAliasInfoRes);
1958da6c28aaSamw DECL_FIXUP_STRUCT(samr_QueryAliasInfo);
1959da6c28aaSamw
1960da6c28aaSamw DECL_FIXUP_STRUCT(QueryUserInfo_result_u);
1961da6c28aaSamw DECL_FIXUP_STRUCT(QueryUserInfo_result);
1962da6c28aaSamw DECL_FIXUP_STRUCT(samr_QueryUserInfo);
1963da6c28aaSamw
1964da6c28aaSamw void
fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo * val)1965da6c28aaSamw fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo *val)
1966da6c28aaSamw {
1967da6c28aaSamw unsigned short size1 = 0;
1968da6c28aaSamw unsigned short size2 = 0;
1969da6c28aaSamw unsigned short size3 = 0;
1970da6c28aaSamw
1971da6c28aaSamw switch (val->level) {
1972eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_GENERAL:
1973eef90b86SGordon Ross size1 = sizeof (struct samr_QueryAliasInfoGeneral);
1974eef90b86SGordon Ross break;
1975eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_NAME:
1976eef90b86SGordon Ross size1 = sizeof (struct samr_QueryAliasInfoName);
1977eef90b86SGordon Ross break;
1978eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_COMMENT:
1979eef90b86SGordon Ross size1 = sizeof (struct samr_QueryAliasInfoComment);
1980eef90b86SGordon Ross break;
1981da6c28aaSamw
1982eef90b86SGordon Ross default:
1983eef90b86SGordon Ross return;
1984da6c28aaSamw };
1985da6c28aaSamw
1986da6c28aaSamw size2 = size1 + (2 * sizeof (DWORD));
19872c1b14e5Sjose borrego size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
1988da6c28aaSamw
1989da6c28aaSamw FIXUP_PDU_SIZE(samr_QueryAliasInfo_ru, size1);
1990da6c28aaSamw FIXUP_PDU_SIZE(samr_QueryAliasInfoRes, size2);
1991da6c28aaSamw FIXUP_PDU_SIZE(samr_QueryAliasInfo, size3);
1992da6c28aaSamw }
1993da6c28aaSamw
1994da6c28aaSamw void
fixup_samr_QueryUserInfo(struct samr_QueryUserInfo * val)1995da6c28aaSamw fixup_samr_QueryUserInfo(struct samr_QueryUserInfo *val)
1996da6c28aaSamw {
1997da6c28aaSamw unsigned short size1 = 0;
1998da6c28aaSamw unsigned short size2 = 0;
1999da6c28aaSamw unsigned short size3 = 0;
2000da6c28aaSamw
2001da6c28aaSamw switch (val->switch_index) {
2002da6c28aaSamw CASE_INFO_ENT(samr_QueryUserInfo, 1);
2003da6c28aaSamw CASE_INFO_ENT(samr_QueryUserInfo, 6);
2004da6c28aaSamw CASE_INFO_ENT(samr_QueryUserInfo, 7);
2005da6c28aaSamw CASE_INFO_ENT(samr_QueryUserInfo, 8);
2006da6c28aaSamw CASE_INFO_ENT(samr_QueryUserInfo, 9);
2007da6c28aaSamw CASE_INFO_ENT(samr_QueryUserInfo, 16);
2008fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 21);
2009da6c28aaSamw
2010da6c28aaSamw default:
2011da6c28aaSamw return;
2012da6c28aaSamw };
2013da6c28aaSamw
2014da6c28aaSamw size2 = size1 + (2 * sizeof (DWORD));
20152c1b14e5Sjose borrego size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
2016da6c28aaSamw
2017da6c28aaSamw FIXUP_PDU_SIZE(QueryUserInfo_result_u, size1);
2018da6c28aaSamw FIXUP_PDU_SIZE(QueryUserInfo_result, size2);
2019da6c28aaSamw FIXUP_PDU_SIZE(samr_QueryUserInfo, size3);
2020da6c28aaSamw }
2021da6c28aaSamw
2022da6c28aaSamw /*
2023da6c28aaSamw * As long as there is only one entry in the union, there is no need
2024da6c28aaSamw * to patch anything.
2025da6c28aaSamw */
2026da6c28aaSamw /*ARGSUSED*/
2027da6c28aaSamw void
fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo * val)2028da6c28aaSamw fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo *val)
2029da6c28aaSamw {
2030da6c28aaSamw }
2031