1fe1c642dSBill Krier /*
2fe1c642dSBill Krier * CDDL HEADER START
3fe1c642dSBill Krier *
4fe1c642dSBill Krier * The contents of this file are subject to the terms of the
5fe1c642dSBill Krier * Common Development and Distribution License (the "License").
6fe1c642dSBill Krier * You may not use this file except in compliance with the License.
7fe1c642dSBill Krier *
8fe1c642dSBill Krier * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fe1c642dSBill Krier * or http://www.opensolaris.org/os/licensing.
10fe1c642dSBill Krier * See the License for the specific language governing permissions
11fe1c642dSBill Krier * and limitations under the License.
12fe1c642dSBill Krier *
13fe1c642dSBill Krier * When distributing Covered Code, include this CDDL HEADER in each
14fe1c642dSBill Krier * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fe1c642dSBill Krier * If applicable, add the following below this CDDL HEADER, with the
16fe1c642dSBill Krier * fields enclosed by brackets "[]" replaced with your own identifying
17fe1c642dSBill Krier * information: Portions Copyright [yyyy] [name of copyright owner]
18fe1c642dSBill Krier *
19fe1c642dSBill Krier * CDDL HEADER END
20fe1c642dSBill Krier */
21148c5f43SAlan Wright
22fe1c642dSBill Krier /*
23c5866007SKeyur Desai * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24*9242c919SMatt Barden * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
25fe1c642dSBill Krier */
26fe1c642dSBill Krier
27fe1c642dSBill Krier /*
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.
35fe1c642dSBill Krier */
36fe1c642dSBill Krier
37fe1c642dSBill Krier #include <strings.h>
38fe1c642dSBill Krier #include <unistd.h>
39fe1c642dSBill Krier #include <netdb.h>
40fe1c642dSBill Krier #include <assert.h>
41c5866007SKeyur Desai #include <grp.h>
423299f39fSGordon Ross #include <libmlrpc/libmlrpc.h>
43fe1c642dSBill Krier #include <smbsrv/libsmb.h>
44fe1c642dSBill Krier #include <smbsrv/libmlsvc.h>
45fe1c642dSBill Krier #include <smbsrv/smbinfo.h>
46fe1c642dSBill Krier #include <smbsrv/nmpipes.h>
47fe1c642dSBill Krier #include <smbsrv/ndl/samrpc.ndl>
48fe1c642dSBill Krier #include <samlib.h>
49fe1c642dSBill Krier
50fe1c642dSBill Krier /*
51fe1c642dSBill Krier * The keys associated with the various handles dispensed by the SAMR
52fe1c642dSBill Krier * server. These keys can be used to validate client activity.
53fe1c642dSBill Krier * These values are never passed over the wire so security shouldn't
54fe1c642dSBill Krier * be an issue.
55fe1c642dSBill Krier */
56fe1c642dSBill Krier typedef enum {
57fe1c642dSBill Krier SAMR_KEY_NULL = 0,
58fe1c642dSBill Krier SAMR_KEY_CONNECT,
59fe1c642dSBill Krier SAMR_KEY_DOMAIN,
60fe1c642dSBill Krier SAMR_KEY_USER,
61fe1c642dSBill Krier SAMR_KEY_GROUP,
62fe1c642dSBill Krier SAMR_KEY_ALIAS
63fe1c642dSBill Krier } samr_key_t;
64fe1c642dSBill Krier
65fe1c642dSBill Krier typedef struct samr_keydata {
66fe1c642dSBill Krier samr_key_t kd_key;
67fe1c642dSBill Krier smb_domain_type_t kd_type;
68fe1c642dSBill Krier DWORD kd_rid;
69fe1c642dSBill Krier } samr_keydata_t;
70fe1c642dSBill Krier
71fe1c642dSBill Krier /*
72fe1c642dSBill Krier * DomainDisplayUser All user objects (or those derived from user) with
73fe1c642dSBill Krier * userAccountControl containing the UF_NORMAL_ACCOUNT bit.
74fe1c642dSBill Krier *
75fe1c642dSBill Krier * DomainDisplayMachine All user objects (or those derived from user) with
76fe1c642dSBill Krier * userAccountControl containing the
77fe1c642dSBill Krier * UF_WORKSTATION_TRUST_ACCOUNT or UF_SERVER_TRUST_ACCOUNT
78fe1c642dSBill Krier * bit.
79fe1c642dSBill Krier *
80fe1c642dSBill Krier * DomainDisplayGroup All group objects (or those derived from group) with
81fe1c642dSBill Krier * groupType equal to GROUP_TYPE_SECURITY_UNIVERSAL or
82fe1c642dSBill Krier * GROUP_TYPE_SECURITY_ACCOUNT.
83fe1c642dSBill Krier *
84fe1c642dSBill Krier * DomainDisplayOemUser Same as DomainDisplayUser with OEM strings
85fe1c642dSBill Krier *
86fe1c642dSBill Krier * DomainDisplayOemGroup Same as DomainDisplayGroup with OEM strings
87fe1c642dSBill Krier */
88fe1c642dSBill Krier typedef enum {
89fe1c642dSBill Krier DomainDisplayUser = 1,
90fe1c642dSBill Krier DomainDisplayMachine,
91fe1c642dSBill Krier DomainDispalyGroup,
92fe1c642dSBill Krier DomainDisplayOemUser,
93fe1c642dSBill Krier DomainDisplayOemGroup
94fe1c642dSBill Krier } samr_displvl_t;
95fe1c642dSBill Krier
96fe1c642dSBill Krier #define SAMR_VALID_DISPLEVEL(lvl) \
97fe1c642dSBill Krier (((lvl) >= DomainDisplayUser) && ((lvl) <= DomainDisplayOemGroup))
98fe1c642dSBill Krier
99fe1c642dSBill Krier #define SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser)
100fe1c642dSBill Krier
101fe1c642dSBill Krier static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t,
102fe1c642dSBill Krier DWORD);
103fe1c642dSBill Krier static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *);
104fe1c642dSBill Krier 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 *);
106fe1c642dSBill Krier static int samr_call_stub(ndr_xa_t *mxa);
107fe1c642dSBill Krier static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *,
108fe1c642dSBill Krier ndr_xa_t *);
109fe1c642dSBill Krier
110fe1c642dSBill Krier static ndr_stub_table_t samr_stub_table[];
111fe1c642dSBill Krier
112fe1c642dSBill Krier static ndr_service_t samr_service = {
113fe1c642dSBill Krier "SAMR", /* name */
114fe1c642dSBill Krier "Security Accounts Manager", /* desc */
115fe1c642dSBill Krier "\\samr", /* endpoint */
116fe1c642dSBill Krier PIPE_LSASS, /* sec_addr_port */
117fe1c642dSBill Krier "12345778-1234-abcd-ef00-0123456789ac", 1, /* abstract */
118fe1c642dSBill Krier NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */
119fe1c642dSBill Krier 0, /* no bind_instance_size */
120fe1c642dSBill Krier NULL, /* no bind_req() */
121fe1c642dSBill Krier NULL, /* no unbind_and_close() */
122fe1c642dSBill Krier samr_call_stub, /* call_stub() */
123fe1c642dSBill Krier &TYPEINFO(samr_interface), /* interface ti */
124fe1c642dSBill Krier samr_stub_table /* stub_table */
125fe1c642dSBill Krier };
126fe1c642dSBill Krier
127fe1c642dSBill Krier /*
128fe1c642dSBill Krier * samr_initialize
129fe1c642dSBill Krier *
130fe1c642dSBill Krier * This function registers the SAM RPC interface with the RPC runtime
131fe1c642dSBill Krier * library. It must be called in order to use either the client side
132fe1c642dSBill Krier * or the server side functions.
133fe1c642dSBill Krier */
134fe1c642dSBill Krier void
samr_initialize(void)135fe1c642dSBill Krier samr_initialize(void)
136fe1c642dSBill Krier {
137fe1c642dSBill Krier (void) ndr_svc_register(&samr_service);
138fe1c642dSBill Krier }
139fe1c642dSBill Krier
140fe1c642dSBill Krier /*
141fe1c642dSBill Krier * Custom call_stub to set the stream string policy.
142fe1c642dSBill Krier */
143fe1c642dSBill Krier static int
samr_call_stub(ndr_xa_t * mxa)144fe1c642dSBill Krier samr_call_stub(ndr_xa_t *mxa)
145fe1c642dSBill Krier {
146fe1c642dSBill Krier NDS_SETF(&mxa->send_nds, NDS_F_NOTERM);
147fe1c642dSBill Krier NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM);
148fe1c642dSBill Krier
149fe1c642dSBill Krier return (ndr_generic_call_stub(mxa));
150fe1c642dSBill Krier }
151fe1c642dSBill Krier
152fe1c642dSBill Krier /*
153fe1c642dSBill Krier * Handle allocation wrapper to setup the local context.
154fe1c642dSBill Krier */
155fe1c642dSBill Krier static ndr_hdid_t *
samr_hdalloc(ndr_xa_t * mxa,samr_key_t key,smb_domain_type_t domain_type,DWORD rid)156fe1c642dSBill Krier samr_hdalloc(ndr_xa_t *mxa, samr_key_t key, smb_domain_type_t domain_type,
157fe1c642dSBill Krier DWORD rid)
158fe1c642dSBill Krier {
1599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_handle_t *hd;
1609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_hdid_t *id;
161fe1c642dSBill Krier samr_keydata_t *data;
162fe1c642dSBill Krier
163fe1c642dSBill Krier if ((data = malloc(sizeof (samr_keydata_t))) == NULL)
164fe1c642dSBill Krier return (NULL);
165fe1c642dSBill Krier
166fe1c642dSBill Krier data->kd_key = key;
167fe1c642dSBill Krier data->kd_type = domain_type;
168fe1c642dSBill Krier data->kd_rid = rid;
169fe1c642dSBill Krier
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);
179fe1c642dSBill Krier }
180fe1c642dSBill Krier
181fe1c642dSBill Krier /*
182fe1c642dSBill Krier * Handle deallocation wrapper to free the local context.
183fe1c642dSBill Krier */
184fe1c642dSBill Krier static void
samr_hdfree(ndr_xa_t * mxa,ndr_hdid_t * id)185fe1c642dSBill Krier samr_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id)
186fe1c642dSBill Krier {
187fe1c642dSBill Krier ndr_handle_t *hd;
188fe1c642dSBill Krier
189fe1c642dSBill Krier if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
190fe1c642dSBill Krier free(hd->nh_data);
1919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States hd->nh_data = NULL;
192fe1c642dSBill Krier ndr_hdfree(mxa, id);
193fe1c642dSBill Krier }
194fe1c642dSBill Krier }
195fe1c642dSBill Krier
196fe1c642dSBill Krier /*
197fe1c642dSBill Krier * Handle lookup wrapper to validate the local context.
198fe1c642dSBill Krier */
199fe1c642dSBill Krier static ndr_handle_t *
samr_hdlookup(ndr_xa_t * mxa,ndr_hdid_t * id,samr_key_t key)200fe1c642dSBill Krier samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key)
201fe1c642dSBill Krier {
202fe1c642dSBill Krier ndr_handle_t *hd;
203fe1c642dSBill Krier samr_keydata_t *data;
204fe1c642dSBill Krier
205fe1c642dSBill Krier if ((hd = ndr_hdlookup(mxa, id)) == NULL)
206fe1c642dSBill Krier return (NULL);
207fe1c642dSBill Krier
208fe1c642dSBill Krier if ((data = (samr_keydata_t *)hd->nh_data) == NULL)
209fe1c642dSBill Krier return (NULL);
210fe1c642dSBill Krier
211fe1c642dSBill Krier if (data->kd_key != key)
212fe1c642dSBill Krier return (NULL);
213fe1c642dSBill Krier
214fe1c642dSBill Krier return (hd);
215fe1c642dSBill Krier }
216fe1c642dSBill Krier
217fe1c642dSBill Krier /*
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
235*9242c919SMatt Barden /*
236cb174861Sjoyce mcintosh * samr_s_Connect
237fe1c642dSBill Krier *
238fe1c642dSBill Krier * This is a request to connect to the local SAM database. We don't
239fe1c642dSBill Krier * support any form of update request and our database doesn't
240fe1c642dSBill Krier * contain any private information, so there is little point in
241fe1c642dSBill Krier * doing any access access checking here.
242fe1c642dSBill Krier *
243fe1c642dSBill Krier * Return a handle for use with subsequent SAM requests.
244fe1c642dSBill Krier */
245fe1c642dSBill Krier static int
samr_s_Connect(void * arg,ndr_xa_t * mxa)246cb174861Sjoyce mcintosh samr_s_Connect(void *arg, ndr_xa_t *mxa)
247fe1c642dSBill Krier {
248cb174861Sjoyce mcintosh struct samr_Connect *param = arg;
249fe1c642dSBill Krier ndr_hdid_t *id;
250fe1c642dSBill Krier
251fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
252fe1c642dSBill Krier if (id) {
253fe1c642dSBill Krier bcopy(id, ¶m->handle, sizeof (samr_handle_t));
254fe1c642dSBill Krier param->status = 0;
255fe1c642dSBill Krier } else {
256fe1c642dSBill Krier bzero(¶m->handle, sizeof (samr_handle_t));
257fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
258fe1c642dSBill Krier }
259fe1c642dSBill Krier
260fe1c642dSBill Krier return (NDR_DRC_OK);
261fe1c642dSBill Krier }
262fe1c642dSBill Krier
263fe1c642dSBill Krier /*
264fe1c642dSBill Krier * samr_s_CloseHandle
265fe1c642dSBill Krier *
266fe1c642dSBill Krier * Close the SAM interface specified by the handle.
267fe1c642dSBill Krier * Free the handle and zero out the result handle for the client.
268fe1c642dSBill Krier */
269fe1c642dSBill Krier static int
samr_s_CloseHandle(void * arg,ndr_xa_t * mxa)270fe1c642dSBill Krier samr_s_CloseHandle(void *arg, ndr_xa_t *mxa)
271fe1c642dSBill Krier {
272fe1c642dSBill Krier struct samr_CloseHandle *param = arg;
273fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
274fe1c642dSBill Krier
275fe1c642dSBill Krier samr_hdfree(mxa, id);
276fe1c642dSBill Krier
277fe1c642dSBill Krier bzero(¶m->result_handle, sizeof (samr_handle_t));
278fe1c642dSBill Krier param->status = 0;
279fe1c642dSBill Krier return (NDR_DRC_OK);
280fe1c642dSBill Krier }
281fe1c642dSBill Krier
282fe1c642dSBill Krier /*
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
325*9242c919SMatt Barden /*
326fe1c642dSBill Krier * samr_s_LookupDomain
327fe1c642dSBill Krier *
328fe1c642dSBill Krier * This is a request to map a domain name to a domain SID. We can map
329fe1c642dSBill Krier * the primary domain name, our local domain name (hostname) and the
330fe1c642dSBill Krier * builtin domain names to the appropriate SID. Anything else will be
331fe1c642dSBill Krier * rejected.
332fe1c642dSBill Krier */
333fe1c642dSBill Krier static int
samr_s_LookupDomain(void * arg,ndr_xa_t * mxa)334fe1c642dSBill Krier samr_s_LookupDomain(void *arg, ndr_xa_t *mxa)
335fe1c642dSBill Krier {
336fe1c642dSBill Krier struct samr_LookupDomain *param = arg;
337fe1c642dSBill Krier char *domain_name;
338fe1c642dSBill Krier smb_domain_t di;
339fe1c642dSBill Krier
340fe1c642dSBill Krier if ((domain_name = (char *)param->domain_name.str) == NULL) {
341fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupDomain));
342fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
343fe1c642dSBill Krier return (NDR_DRC_OK);
344fe1c642dSBill Krier }
345fe1c642dSBill Krier
346fe1c642dSBill Krier if (!smb_domain_lookup_name(domain_name, &di)) {
347fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupDomain));
348fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_DOMAIN);
349fe1c642dSBill Krier return (NDR_DRC_OK);
350fe1c642dSBill Krier }
351fe1c642dSBill Krier
352fe1c642dSBill Krier param->sid = (struct samr_sid *)NDR_SIDDUP(mxa, di.di_binsid);
353fe1c642dSBill Krier if (param->sid == NULL) {
354fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupDomain));
355fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
356fe1c642dSBill Krier return (NDR_DRC_OK);
357fe1c642dSBill Krier }
358fe1c642dSBill Krier
359fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
360fe1c642dSBill Krier return (NDR_DRC_OK);
361fe1c642dSBill Krier }
362fe1c642dSBill Krier
363fe1c642dSBill Krier /*
364fe1c642dSBill Krier * samr_s_EnumLocalDomains
365fe1c642dSBill Krier *
366fe1c642dSBill Krier * This is a request for the local domains supported by this server.
367fe1c642dSBill Krier * All we do here is validate the handle and set the status. The real
368fe1c642dSBill Krier * work is done in samr_s_enum_local_domains.
369fe1c642dSBill Krier */
370fe1c642dSBill Krier static int
samr_s_EnumLocalDomains(void * arg,ndr_xa_t * mxa)371fe1c642dSBill Krier samr_s_EnumLocalDomains(void *arg, ndr_xa_t *mxa)
372fe1c642dSBill Krier {
373fe1c642dSBill Krier struct samr_EnumLocalDomain *param = arg;
374fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
375fe1c642dSBill Krier DWORD status;
376fe1c642dSBill Krier
377fe1c642dSBill Krier if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL)
378fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
379fe1c642dSBill Krier else
380fe1c642dSBill Krier status = samr_s_enum_local_domains(param, mxa);
381fe1c642dSBill Krier
382fe1c642dSBill Krier if (status == NT_STATUS_SUCCESS) {
383fe1c642dSBill Krier param->enum_context = param->info->entries_read;
384fe1c642dSBill Krier param->total_entries = param->info->entries_read;
385fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
386fe1c642dSBill Krier } else {
387fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumLocalDomain));
388fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
389fe1c642dSBill Krier }
390fe1c642dSBill Krier
391fe1c642dSBill Krier return (NDR_DRC_OK);
392fe1c642dSBill Krier }
393fe1c642dSBill Krier
394fe1c642dSBill Krier
395fe1c642dSBill Krier /*
396fe1c642dSBill Krier * samr_s_enum_local_domains
397fe1c642dSBill Krier *
398fe1c642dSBill Krier * This function should only be called via samr_s_EnumLocalDomains to
399fe1c642dSBill Krier * ensure that the appropriate validation is performed. We will answer
400fe1c642dSBill Krier * queries about two domains: the local domain, synonymous with the
401fe1c642dSBill Krier * local hostname, and the BUILTIN domain. So we return these two
402fe1c642dSBill Krier * strings.
403fe1c642dSBill Krier *
404fe1c642dSBill Krier * Returns NT status values.
405fe1c642dSBill Krier */
406fe1c642dSBill Krier static DWORD
samr_s_enum_local_domains(struct samr_EnumLocalDomain * param,ndr_xa_t * mxa)407fe1c642dSBill Krier samr_s_enum_local_domains(struct samr_EnumLocalDomain *param,
408fe1c642dSBill Krier ndr_xa_t *mxa)
409fe1c642dSBill Krier {
410fe1c642dSBill Krier struct samr_LocalDomainInfo *info;
411fe1c642dSBill Krier struct samr_LocalDomainEntry *entry;
412fe1c642dSBill Krier char *hostname;
413fe1c642dSBill Krier
414fe1c642dSBill Krier hostname = NDR_MALLOC(mxa, NETBIOS_NAME_SZ);
415fe1c642dSBill Krier if (hostname == NULL)
416fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY);
417fe1c642dSBill Krier
418fe1c642dSBill Krier if (smb_getnetbiosname(hostname, NETBIOS_NAME_SZ) != 0)
419fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY);
420fe1c642dSBill Krier
421fe1c642dSBill Krier entry = NDR_NEWN(mxa, struct samr_LocalDomainEntry, 2);
422fe1c642dSBill Krier if (entry == NULL)
423fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY);
424fe1c642dSBill Krier
425fe1c642dSBill Krier bzero(entry, (sizeof (struct samr_LocalDomainEntry) * 2));
426fe1c642dSBill Krier (void) NDR_MSTRING(mxa, hostname, (ndr_mstring_t *)&entry[0].name);
427fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "Builtin", (ndr_mstring_t *)&entry[1].name);
428fe1c642dSBill Krier
429fe1c642dSBill Krier info = NDR_NEW(mxa, struct samr_LocalDomainInfo);
430fe1c642dSBill Krier if (info == NULL)
431fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY);
432fe1c642dSBill Krier
433fe1c642dSBill Krier info->entries_read = 2;
434fe1c642dSBill Krier info->entry = entry;
435fe1c642dSBill Krier param->info = info;
436fe1c642dSBill Krier return (NT_STATUS_SUCCESS);
437fe1c642dSBill Krier }
438fe1c642dSBill Krier
439fe1c642dSBill Krier /*
440fe1c642dSBill Krier * samr_s_OpenDomain
441fe1c642dSBill Krier *
442fe1c642dSBill Krier * This is a request to open a domain within the local SAM database.
443fe1c642dSBill Krier * The caller must supply a valid connect handle.
444fe1c642dSBill Krier * We return a handle to be used to access objects within this domain.
445fe1c642dSBill Krier */
446fe1c642dSBill Krier static int
samr_s_OpenDomain(void * arg,ndr_xa_t * mxa)447fe1c642dSBill Krier samr_s_OpenDomain(void *arg, ndr_xa_t *mxa)
448fe1c642dSBill Krier {
449fe1c642dSBill Krier struct samr_OpenDomain *param = arg;
450fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
451fe1c642dSBill Krier smb_domain_t domain;
452fe1c642dSBill Krier
453fe1c642dSBill Krier if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) {
454fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (samr_handle_t));
455fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
456fe1c642dSBill Krier return (NDR_DRC_OK);
457fe1c642dSBill Krier }
458fe1c642dSBill Krier
459fe1c642dSBill Krier if (!smb_domain_lookup_sid((smb_sid_t *)param->sid, &domain)) {
460fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (samr_handle_t));
461fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
462fe1c642dSBill Krier return (NDR_DRC_OK);
463fe1c642dSBill Krier }
464fe1c642dSBill Krier
465fe1c642dSBill Krier if ((domain.di_type != SMB_DOMAIN_BUILTIN) &&
466fe1c642dSBill Krier (domain.di_type != SMB_DOMAIN_LOCAL)) {
467fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (samr_handle_t));
468fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
469fe1c642dSBill Krier return (NDR_DRC_OK);
470fe1c642dSBill Krier }
471fe1c642dSBill Krier
472fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_DOMAIN, domain.di_type, 0);
473fe1c642dSBill Krier if (id) {
474fe1c642dSBill Krier bcopy(id, ¶m->domain_handle, sizeof (samr_handle_t));
475fe1c642dSBill Krier param->status = 0;
476fe1c642dSBill Krier } else {
477fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (samr_handle_t));
478fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
479fe1c642dSBill Krier }
480fe1c642dSBill Krier
481fe1c642dSBill Krier return (NDR_DRC_OK);
482fe1c642dSBill Krier }
483fe1c642dSBill Krier
484fe1c642dSBill Krier /*
485fe1c642dSBill Krier * samr_s_QueryDomainInfo
486fe1c642dSBill Krier *
487fe1c642dSBill Krier * The caller should pass a domain handle.
488fe1c642dSBill Krier *
489fe1c642dSBill Krier * Windows 95 Server Manager sends requests for levels 6 and 7 when
490fe1c642dSBill Krier * the services menu item is selected. Level 2 is basically for getting
491fe1c642dSBill Krier * number of users, groups, and aliases in a domain.
492fe1c642dSBill Krier * We have no information on what the various information levels mean.
493fe1c642dSBill Krier */
494fe1c642dSBill Krier static int
samr_s_QueryDomainInfo(void * arg,ndr_xa_t * mxa)495fe1c642dSBill Krier samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa)
496fe1c642dSBill Krier {
497fe1c642dSBill Krier struct samr_QueryDomainInfo *param = arg;
498fe1c642dSBill Krier struct samr_QueryDomainInfoRes *info;
499fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
500fe1c642dSBill Krier ndr_handle_t *hd;
501fe1c642dSBill Krier samr_keydata_t *data;
502fe1c642dSBill Krier char *domain;
503fe1c642dSBill Krier char hostname[NETBIOS_NAME_SZ];
504fe1c642dSBill Krier int alias_cnt, user_cnt;
505fe1c642dSBill Krier int rc = 0;
506fe1c642dSBill Krier
507fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
508fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo));
509fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
510fe1c642dSBill Krier return (NDR_DRC_OK);
511fe1c642dSBill Krier }
512fe1c642dSBill Krier
513fe1c642dSBill Krier info = NDR_NEW(mxa, struct samr_QueryDomainInfoRes);
514fe1c642dSBill Krier if (info == NULL) {
515fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo));
516fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
517fe1c642dSBill Krier return (NDR_DRC_OK);
518fe1c642dSBill Krier }
519fe1c642dSBill Krier info->switch_value = param->info_level;
520fe1c642dSBill Krier param->info = info;
521fe1c642dSBill Krier
522fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
523fe1c642dSBill Krier
524fe1c642dSBill Krier switch (data->kd_type) {
525fe1c642dSBill Krier case SMB_DOMAIN_BUILTIN:
526fe1c642dSBill Krier domain = "BUILTIN";
527fe1c642dSBill Krier user_cnt = 0;
528fe1c642dSBill Krier alias_cnt = smb_sam_grp_cnt(data->kd_type);
529fe1c642dSBill Krier break;
530fe1c642dSBill Krier
531fe1c642dSBill Krier case SMB_DOMAIN_LOCAL:
532fe1c642dSBill Krier rc = smb_getnetbiosname(hostname, sizeof (hostname));
533fe1c642dSBill Krier if (rc == 0) {
534fe1c642dSBill Krier domain = hostname;
535fe1c642dSBill Krier user_cnt = smb_sam_usr_cnt();
536fe1c642dSBill Krier alias_cnt = smb_sam_grp_cnt(data->kd_type);
537fe1c642dSBill Krier }
538fe1c642dSBill Krier break;
539fe1c642dSBill Krier
540fe1c642dSBill Krier default:
541fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo));
542fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
543fe1c642dSBill Krier return (NDR_DRC_OK);
544fe1c642dSBill Krier }
545fe1c642dSBill Krier
546fe1c642dSBill Krier if (rc != 0) {
547fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo));
548fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR);
549fe1c642dSBill Krier return (NDR_DRC_OK);
550fe1c642dSBill Krier }
551fe1c642dSBill Krier
552fe1c642dSBill Krier switch (param->info_level) {
553fe1c642dSBill Krier case SAMR_QUERY_DOMAIN_INFO_6:
554fe1c642dSBill Krier info->ru.info6.unknown1 = 0x00000000;
555fe1c642dSBill Krier info->ru.info6.unknown2 = 0x00147FB0;
556fe1c642dSBill Krier info->ru.info6.unknown3 = 0x00000000;
557fe1c642dSBill Krier info->ru.info6.unknown4 = 0x00000000;
558fe1c642dSBill Krier info->ru.info6.unknown5 = 0x00000000;
559fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
560fe1c642dSBill Krier break;
561fe1c642dSBill Krier
562fe1c642dSBill Krier case SAMR_QUERY_DOMAIN_INFO_7:
563fe1c642dSBill Krier info->ru.info7.unknown1 = 0x00000003;
564fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
565fe1c642dSBill Krier break;
566fe1c642dSBill Krier
567fe1c642dSBill Krier case SAMR_QUERY_DOMAIN_INFO_2:
568fe1c642dSBill Krier info->ru.info2.unknown1 = 0x00000000;
569fe1c642dSBill Krier info->ru.info2.unknown2 = 0x80000000;
570fe1c642dSBill Krier
571fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "",
572fe1c642dSBill Krier (ndr_mstring_t *)&(info->ru.info2.s1));
573fe1c642dSBill Krier (void) NDR_MSTRING(mxa, domain,
574fe1c642dSBill Krier (ndr_mstring_t *)&(info->ru.info2.domain));
575fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "",
576fe1c642dSBill Krier (ndr_mstring_t *)&(info->ru.info2.s2));
577fe1c642dSBill Krier
578fe1c642dSBill Krier info->ru.info2.sequence_num = 0x0000002B;
579fe1c642dSBill Krier info->ru.info2.unknown3 = 0x00000000;
580fe1c642dSBill Krier info->ru.info2.unknown4 = 0x00000001;
581fe1c642dSBill Krier info->ru.info2.unknown5 = 0x00000003;
582fe1c642dSBill Krier info->ru.info2.unknown6 = 0x00000001;
583fe1c642dSBill Krier info->ru.info2.num_users = user_cnt;
584fe1c642dSBill Krier info->ru.info2.num_groups = 0;
585fe1c642dSBill Krier info->ru.info2.num_aliases = alias_cnt;
586fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
587fe1c642dSBill Krier break;
588fe1c642dSBill Krier
589fe1c642dSBill Krier default:
590fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo));
591fe1c642dSBill Krier return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
592fe1c642dSBill Krier };
593fe1c642dSBill Krier
594fe1c642dSBill Krier return (NDR_DRC_OK);
595fe1c642dSBill Krier }
596fe1c642dSBill Krier
597fe1c642dSBill Krier /*
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
606f96bd5c8SAlan Wright /*
607fe1c642dSBill Krier * Looks up the given name in the specified domain which could
608fe1c642dSBill Krier * be either the built-in or local domain.
609fe1c642dSBill Krier *
610fe1c642dSBill Krier * CAVEAT: this function should be able to handle a list of
611fe1c642dSBill Krier * names but currently it can only handle one name at a time.
612fe1c642dSBill Krier */
613fe1c642dSBill Krier static int
samr_s_LookupNames(void * arg,ndr_xa_t * mxa)614fe1c642dSBill Krier samr_s_LookupNames(void *arg, ndr_xa_t *mxa)
615fe1c642dSBill Krier {
616fe1c642dSBill Krier struct samr_LookupNames *param = arg;
617fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
618fe1c642dSBill Krier ndr_handle_t *hd;
619fe1c642dSBill Krier samr_keydata_t *data;
620fe1c642dSBill Krier smb_account_t account;
621fe1c642dSBill Krier smb_wka_t *wka;
622fe1c642dSBill Krier uint32_t status = NT_STATUS_SUCCESS;
623fe1c642dSBill Krier
624fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL)
625fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
626fe1c642dSBill Krier
627fe1c642dSBill Krier if (param->n_entry != 1)
628fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
629fe1c642dSBill Krier
630fe1c642dSBill Krier if (param->name.str == NULL) {
631fe1c642dSBill Krier /*
632fe1c642dSBill Krier * Windows NT returns NT_STATUS_NONE_MAPPED.
633fe1c642dSBill Krier * Windows 2000 returns STATUS_INVALID_ACCOUNT_NAME.
634fe1c642dSBill Krier */
635fe1c642dSBill Krier status = NT_STATUS_NONE_MAPPED;
636fe1c642dSBill Krier }
637fe1c642dSBill Krier
638fe1c642dSBill Krier if (status != NT_STATUS_SUCCESS) {
639fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupNames));
640fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
641fe1c642dSBill Krier return (NDR_DRC_OK);
642fe1c642dSBill Krier }
643fe1c642dSBill Krier
644fe1c642dSBill Krier param->rids.rid = NDR_NEW(mxa, DWORD);
645fe1c642dSBill Krier param->rid_types.rid_type = NDR_NEW(mxa, DWORD);
646fe1c642dSBill Krier
647fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
648fe1c642dSBill Krier
649fe1c642dSBill Krier switch (data->kd_type) {
650fe1c642dSBill Krier case SMB_DOMAIN_BUILTIN:
651f96bd5c8SAlan Wright wka = smb_wka_lookup_builtin((char *)param->name.str);
652fe1c642dSBill Krier if (wka != NULL) {
653fe1c642dSBill Krier param->rids.n_entry = 1;
654fe1c642dSBill Krier (void) smb_sid_getrid(wka->wka_binsid,
655fe1c642dSBill Krier ¶m->rids.rid[0]);
656fe1c642dSBill Krier param->rid_types.n_entry = 1;
657fe1c642dSBill Krier param->rid_types.rid_type[0] = wka->wka_type;
658fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
659fe1c642dSBill Krier return (NDR_DRC_OK);
660fe1c642dSBill Krier }
661fe1c642dSBill Krier break;
662fe1c642dSBill Krier
663fe1c642dSBill Krier case SMB_DOMAIN_LOCAL:
664fe1c642dSBill Krier status = smb_sam_lookup_name(NULL, (char *)param->name.str,
665fe1c642dSBill Krier SidTypeUnknown, &account);
666fe1c642dSBill Krier if (status == NT_STATUS_SUCCESS) {
667fe1c642dSBill Krier param->rids.n_entry = 1;
668fe1c642dSBill Krier param->rids.rid[0] = account.a_rid;
669fe1c642dSBill Krier param->rid_types.n_entry = 1;
670fe1c642dSBill Krier param->rid_types.rid_type[0] = account.a_type;
671fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
672fe1c642dSBill Krier smb_account_free(&account);
673fe1c642dSBill Krier return (NDR_DRC_OK);
674fe1c642dSBill Krier }
675fe1c642dSBill Krier break;
676fe1c642dSBill Krier
677fe1c642dSBill Krier default:
678fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupNames));
679fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
680fe1c642dSBill Krier return (NDR_DRC_OK);
681fe1c642dSBill Krier }
682fe1c642dSBill Krier
683fe1c642dSBill Krier param->rids.n_entry = 0;
684fe1c642dSBill Krier param->rid_types.n_entry = 0;
685fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NONE_MAPPED);
686fe1c642dSBill Krier return (NDR_DRC_OK);
687fe1c642dSBill Krier }
688fe1c642dSBill Krier
689fe1c642dSBill Krier /*
690fe1c642dSBill Krier * samr_s_OpenUser
691fe1c642dSBill Krier *
692fe1c642dSBill Krier * This is a request to open a user within a specified domain in the
693fe1c642dSBill Krier * local SAM database. The caller must supply a valid domain handle,
694fe1c642dSBill Krier * obtained via a successful domain open request. The user is
695fe1c642dSBill Krier * specified by the rid in the request.
696fe1c642dSBill Krier */
697fe1c642dSBill Krier static int
samr_s_OpenUser(void * arg,ndr_xa_t * mxa)698fe1c642dSBill Krier samr_s_OpenUser(void *arg, ndr_xa_t *mxa)
699fe1c642dSBill Krier {
700fe1c642dSBill Krier struct samr_OpenUser *param = arg;
701fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
702fe1c642dSBill Krier ndr_handle_t *hd;
703fe1c642dSBill Krier samr_keydata_t *data;
704fe1c642dSBill Krier
705fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
706fe1c642dSBill Krier bzero(¶m->user_handle, sizeof (samr_handle_t));
707fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
708fe1c642dSBill Krier return (NDR_DRC_OK);
709fe1c642dSBill Krier }
710fe1c642dSBill Krier
711fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
712fe1c642dSBill Krier
713fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_USER, data->kd_type, param->rid);
714fe1c642dSBill Krier if (id == NULL) {
715fe1c642dSBill Krier bzero(¶m->user_handle, sizeof (samr_handle_t));
716fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
717fe1c642dSBill Krier } else {
718fe1c642dSBill Krier bcopy(id, ¶m->user_handle, sizeof (samr_handle_t));
719fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
720fe1c642dSBill Krier }
721fe1c642dSBill Krier
722fe1c642dSBill Krier return (NDR_DRC_OK);
723fe1c642dSBill Krier }
724fe1c642dSBill Krier
725fe1c642dSBill Krier /*
726fe1c642dSBill Krier * samr_s_DeleteUser
727fe1c642dSBill Krier *
728fe1c642dSBill Krier * Request to delete a user within a specified domain in the local
729fe1c642dSBill Krier * SAM database. The caller should supply a valid user handle.
730fe1c642dSBill Krier */
731fe1c642dSBill Krier /*ARGSUSED*/
732fe1c642dSBill Krier static int
samr_s_DeleteUser(void * arg,ndr_xa_t * mxa)733fe1c642dSBill Krier samr_s_DeleteUser(void *arg, ndr_xa_t *mxa)
734fe1c642dSBill Krier {
735fe1c642dSBill Krier struct samr_DeleteUser *param = arg;
736fe1c642dSBill Krier
737fe1c642dSBill Krier bzero(param, sizeof (struct samr_DeleteUser));
738fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
739fe1c642dSBill Krier return (NDR_DRC_OK);
740fe1c642dSBill Krier }
741fe1c642dSBill Krier
742fe1c642dSBill Krier /*
743fe1c642dSBill Krier * samr_s_QueryUserInfo
744fe1c642dSBill Krier *
745fe1c642dSBill Krier * Returns:
746fe1c642dSBill Krier * NT_STATUS_SUCCESS
747fe1c642dSBill Krier * NT_STATUS_ACCESS_DENIED
748fe1c642dSBill Krier * NT_STATUS_INVALID_INFO_CLASS
749fe1c642dSBill Krier */
750fe1c642dSBill Krier /*ARGSUSED*/
751fe1c642dSBill Krier static int
samr_s_QueryUserInfo(void * arg,ndr_xa_t * mxa)752fe1c642dSBill Krier samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa)
753fe1c642dSBill Krier {
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 }
776fe1c642dSBill Krier
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);
821fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryUserInfo));
822fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
823fe1c642dSBill Krier return (NDR_DRC_OK);
824fe1c642dSBill Krier }
825fe1c642dSBill Krier
826fe1c642dSBill Krier /*
827fe1c642dSBill Krier * samr_s_QueryUserGroups
828fe1c642dSBill Krier *
829fe1c642dSBill Krier * Request the list of groups of which a user is a member.
830fe1c642dSBill Krier * The user is identified from the handle, which contains an
831fe1c642dSBill Krier * rid in the discriminator field. Note that this is a local user.
832fe1c642dSBill Krier */
833fe1c642dSBill Krier static int
samr_s_QueryUserGroups(void * arg,ndr_xa_t * mxa)834fe1c642dSBill Krier samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa)
835fe1c642dSBill Krier {
836fe1c642dSBill Krier struct samr_QueryUserGroups *param = arg;
837fe1c642dSBill Krier struct samr_UserGroupInfo *info;
838fe1c642dSBill Krier struct samr_UserGroups *group;
839fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->user_handle;
840fe1c642dSBill Krier ndr_handle_t *hd;
841fe1c642dSBill Krier samr_keydata_t *data;
842fe1c642dSBill Krier smb_sid_t *user_sid = NULL;
843fe1c642dSBill Krier smb_group_t grp;
844fe1c642dSBill Krier smb_giter_t gi;
845fe1c642dSBill Krier smb_domain_t di;
846fe1c642dSBill Krier uint32_t status;
847fe1c642dSBill Krier int size;
848fe1c642dSBill Krier int ngrp_max;
849fe1c642dSBill Krier
850fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) {
851fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
852fe1c642dSBill Krier goto query_error;
853fe1c642dSBill Krier }
854fe1c642dSBill Krier
855fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
856fe1c642dSBill Krier switch (data->kd_type) {
857fe1c642dSBill Krier case SMB_DOMAIN_BUILTIN:
858fe1c642dSBill Krier case SMB_DOMAIN_LOCAL:
859fe1c642dSBill Krier if (!smb_domain_lookup_type(data->kd_type, &di)) {
860fe1c642dSBill Krier status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
861fe1c642dSBill Krier goto query_error;
862fe1c642dSBill Krier }
863fe1c642dSBill Krier break;
864fe1c642dSBill Krier default:
865fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
866fe1c642dSBill Krier goto query_error;
867fe1c642dSBill Krier }
868fe1c642dSBill Krier
869fe1c642dSBill Krier user_sid = smb_sid_splice(di.di_binsid, data->kd_rid);
870fe1c642dSBill Krier if (user_sid == NULL) {
871fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY;
872fe1c642dSBill Krier goto query_error;
873fe1c642dSBill Krier }
874fe1c642dSBill Krier
875fe1c642dSBill Krier info = NDR_NEW(mxa, struct samr_UserGroupInfo);
876fe1c642dSBill Krier if (info == NULL) {
877fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY;
878fe1c642dSBill Krier goto query_error;
879fe1c642dSBill Krier }
880fe1c642dSBill Krier bzero(info, sizeof (struct samr_UserGroupInfo));
881fe1c642dSBill Krier
882fe1c642dSBill Krier size = 32 * 1024;
883fe1c642dSBill Krier info->groups = NDR_MALLOC(mxa, size);
884fe1c642dSBill Krier if (info->groups == NULL) {
885fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY;
886fe1c642dSBill Krier goto query_error;
887fe1c642dSBill Krier }
888fe1c642dSBill Krier ngrp_max = size / sizeof (struct samr_UserGroups);
889fe1c642dSBill Krier
890fe1c642dSBill Krier if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
891fe1c642dSBill Krier status = NT_STATUS_INTERNAL_ERROR;
892fe1c642dSBill Krier goto query_error;
893fe1c642dSBill Krier }
894fe1c642dSBill Krier
895fe1c642dSBill Krier info->n_entry = 0;
896fe1c642dSBill Krier group = info->groups;
897fe1c642dSBill Krier while ((info->n_entry < ngrp_max) &&
898fe1c642dSBill Krier (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS)) {
899fe1c642dSBill Krier if (smb_lgrp_is_member(&grp, user_sid)) {
900fe1c642dSBill Krier group->rid = grp.sg_rid;
901fe1c642dSBill Krier group->attr = grp.sg_attr;
902fe1c642dSBill Krier group++;
903fe1c642dSBill Krier info->n_entry++;
904fe1c642dSBill Krier }
905fe1c642dSBill Krier smb_lgrp_free(&grp);
906fe1c642dSBill Krier }
907fe1c642dSBill Krier smb_lgrp_iterclose(&gi);
908fe1c642dSBill Krier
909fe1c642dSBill Krier free(user_sid);
910fe1c642dSBill Krier param->info = info;
911fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
912fe1c642dSBill Krier return (NDR_DRC_OK);
913fe1c642dSBill Krier
914fe1c642dSBill Krier query_error:
915fe1c642dSBill Krier free(user_sid);
916fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryUserGroups));
917fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
918fe1c642dSBill Krier return (NDR_DRC_OK);
919fe1c642dSBill Krier }
920fe1c642dSBill Krier
921fe1c642dSBill Krier /*
922fe1c642dSBill Krier * samr_s_OpenGroup
923fe1c642dSBill Krier *
924fe1c642dSBill Krier * This is a request to open a group within the specified domain in the
925fe1c642dSBill Krier * local SAM database. The caller must supply a valid domain handle,
926fe1c642dSBill Krier * obtained via a successful domain open request. The group is
927fe1c642dSBill Krier * specified by the rid in the request. If this is a local RID it
928fe1c642dSBill Krier * should already be encoded with type information.
929fe1c642dSBill Krier *
930fe1c642dSBill Krier * We return a handle to be used to access information about this group.
931fe1c642dSBill Krier */
932fe1c642dSBill Krier static int
samr_s_OpenGroup(void * arg,ndr_xa_t * mxa)933fe1c642dSBill Krier samr_s_OpenGroup(void *arg, ndr_xa_t *mxa)
934fe1c642dSBill Krier {
935fe1c642dSBill Krier struct samr_OpenGroup *param = arg;
936fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
937fe1c642dSBill Krier ndr_handle_t *hd;
938fe1c642dSBill Krier samr_keydata_t *data;
939fe1c642dSBill Krier
940fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
941fe1c642dSBill Krier bzero(¶m->group_handle, sizeof (samr_handle_t));
942fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
943fe1c642dSBill Krier return (NDR_DRC_OK);
944fe1c642dSBill Krier }
945fe1c642dSBill Krier
946fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
947fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_GROUP, data->kd_type, param->rid);
948fe1c642dSBill Krier
949fe1c642dSBill Krier if (id) {
950fe1c642dSBill Krier bcopy(id, ¶m->group_handle, sizeof (samr_handle_t));
951fe1c642dSBill Krier param->status = 0;
952fe1c642dSBill Krier } else {
953fe1c642dSBill Krier bzero(¶m->group_handle, sizeof (samr_handle_t));
954fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
955fe1c642dSBill Krier }
956fe1c642dSBill Krier
957fe1c642dSBill Krier return (NDR_DRC_OK);
958fe1c642dSBill Krier }
959fe1c642dSBill Krier
960fe1c642dSBill Krier /*
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
1147c5866007SKeyur Desai /*
1148cb174861Sjoyce mcintosh * samr_s_Connect2
1149fe1c642dSBill Krier *
1150fe1c642dSBill Krier * This is a request to connect to the local SAM database.
1151fe1c642dSBill Krier * We don't support any form of update request and our database doesn't
1152fe1c642dSBill Krier * contain any private information, so there is little point in doing
1153fe1c642dSBill Krier * any access access checking here.
1154fe1c642dSBill Krier *
1155fe1c642dSBill Krier * Return a handle for use with subsequent SAM requests.
1156fe1c642dSBill Krier */
1157fe1c642dSBill Krier static int
samr_s_Connect2(void * arg,ndr_xa_t * mxa)1158cb174861Sjoyce mcintosh samr_s_Connect2(void *arg, ndr_xa_t *mxa)
1159fe1c642dSBill Krier {
1160cb174861Sjoyce mcintosh struct samr_Connect2 *param = arg;
1161fe1c642dSBill Krier ndr_hdid_t *id;
1162fe1c642dSBill Krier
1163fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
1164fe1c642dSBill Krier if (id) {
1165fe1c642dSBill Krier bcopy(id, ¶m->handle, sizeof (samr_handle_t));
1166fe1c642dSBill Krier param->status = 0;
1167fe1c642dSBill Krier } else {
1168fe1c642dSBill Krier bzero(¶m->handle, sizeof (samr_handle_t));
1169fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1170fe1c642dSBill Krier }
1171fe1c642dSBill Krier
1172fe1c642dSBill Krier return (NDR_DRC_OK);
1173fe1c642dSBill Krier }
1174fe1c642dSBill Krier
1175fe1c642dSBill Krier /*
1176fe1c642dSBill Krier * samr_s_GetUserPwInfo
1177fe1c642dSBill Krier *
1178f96bd5c8SAlan Wright * Request for a user's password policy information.
1179fe1c642dSBill Krier */
1180fe1c642dSBill Krier /*ARGSUSED*/
1181fe1c642dSBill Krier static int
samr_s_GetUserPwInfo(void * arg,ndr_xa_t * mxa)1182fe1c642dSBill Krier samr_s_GetUserPwInfo(void *arg, ndr_xa_t *mxa)
1183fe1c642dSBill Krier {
1184f96bd5c8SAlan Wright static samr_password_info_t pwinfo;
1185fe1c642dSBill Krier struct samr_GetUserPwInfo *param = arg;
1186fe1c642dSBill Krier
1187f96bd5c8SAlan Wright param->pwinfo = &pwinfo;
1188f96bd5c8SAlan Wright param->status = NT_STATUS_SUCCESS;
1189fe1c642dSBill Krier return (NDR_DRC_OK);
1190fe1c642dSBill Krier }
1191fe1c642dSBill Krier
1192fe1c642dSBill Krier /*
1193fe1c642dSBill Krier * samr_s_CreateUser
1194fe1c642dSBill Krier */
1195fe1c642dSBill Krier /*ARGSUSED*/
1196fe1c642dSBill Krier static int
samr_s_CreateUser(void * arg,ndr_xa_t * mxa)1197fe1c642dSBill Krier samr_s_CreateUser(void *arg, ndr_xa_t *mxa)
1198fe1c642dSBill Krier {
1199fe1c642dSBill Krier struct samr_CreateUser *param = arg;
1200fe1c642dSBill Krier
1201fe1c642dSBill Krier bzero(¶m->user_handle, sizeof (samr_handle_t));
1202fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
1203fe1c642dSBill Krier return (NDR_DRC_OK);
1204fe1c642dSBill Krier }
1205fe1c642dSBill Krier
1206fe1c642dSBill Krier /*
12071ed6b69aSGordon Ross * samr_s_ChangePasswordUser2
1208fe1c642dSBill Krier */
1209fe1c642dSBill Krier /*ARGSUSED*/
1210fe1c642dSBill Krier static int
samr_s_ChangePasswordUser2(void * arg,ndr_xa_t * mxa)12111ed6b69aSGordon Ross samr_s_ChangePasswordUser2(void *arg, ndr_xa_t *mxa)
1212fe1c642dSBill Krier {
12131ed6b69aSGordon Ross struct samr_ChangePasswordUser2 *param = arg;
1214fe1c642dSBill Krier
12151ed6b69aSGordon Ross bzero(param, sizeof (*param));
1216fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
1217fe1c642dSBill Krier return (NDR_DRC_OK);
1218fe1c642dSBill Krier }
1219fe1c642dSBill Krier
1220fe1c642dSBill Krier /*
1221fe1c642dSBill Krier * samr_s_GetDomainPwInfo
1222f96bd5c8SAlan Wright *
1223f96bd5c8SAlan Wright * Request for the domain password policy information.
1224fe1c642dSBill Krier */
1225fe1c642dSBill Krier /*ARGSUSED*/
1226fe1c642dSBill Krier static int
samr_s_GetDomainPwInfo(void * arg,ndr_xa_t * mxa)1227fe1c642dSBill Krier samr_s_GetDomainPwInfo(void *arg, ndr_xa_t *mxa)
1228fe1c642dSBill Krier {
1229f96bd5c8SAlan Wright static samr_password_info_t pwinfo;
1230fe1c642dSBill Krier struct samr_GetDomainPwInfo *param = arg;
1231fe1c642dSBill Krier
1232f96bd5c8SAlan Wright param->pwinfo = &pwinfo;
1233f96bd5c8SAlan Wright param->status = NT_STATUS_SUCCESS;
1234fe1c642dSBill Krier return (NDR_DRC_OK);
1235fe1c642dSBill Krier }
1236fe1c642dSBill Krier
1237fe1c642dSBill Krier /*
1238fe1c642dSBill Krier * samr_s_SetUserInfo
1239fe1c642dSBill Krier */
1240fe1c642dSBill Krier /*ARGSUSED*/
1241fe1c642dSBill Krier static int
samr_s_SetUserInfo(void * arg,ndr_xa_t * mxa)1242fe1c642dSBill Krier samr_s_SetUserInfo(void *arg, ndr_xa_t *mxa)
1243fe1c642dSBill Krier {
1244fe1c642dSBill Krier struct samr_SetUserInfo *param = arg;
1245fe1c642dSBill Krier
1246fe1c642dSBill Krier bzero(param, sizeof (struct samr_SetUserInfo));
1247fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
1248fe1c642dSBill Krier return (NDR_DRC_OK);
1249fe1c642dSBill Krier }
1250fe1c642dSBill Krier
1251fe1c642dSBill Krier /*
1252fe1c642dSBill Krier * samr_s_QueryDispInfo
1253fe1c642dSBill Krier *
1254fe1c642dSBill Krier * This function currently return local users' information only.
1255fe1c642dSBill Krier * This RPC is called repeatedly until all the users info are
1256fe1c642dSBill Krier * retrieved.
1257fe1c642dSBill Krier *
1258fe1c642dSBill Krier * The total count and the returned count are returned as total size
1259fe1c642dSBill Krier * and returned size. The client doesn't seem to care.
1260fe1c642dSBill Krier */
1261fe1c642dSBill Krier static int
samr_s_QueryDispInfo(void * arg,ndr_xa_t * mxa)1262fe1c642dSBill Krier samr_s_QueryDispInfo(void *arg, ndr_xa_t *mxa)
1263fe1c642dSBill Krier {
1264fe1c642dSBill Krier struct samr_QueryDispInfo *param = arg;
1265fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
1266fe1c642dSBill Krier ndr_handle_t *hd;
1267fe1c642dSBill Krier samr_keydata_t *data;
1268fe1c642dSBill Krier DWORD status = NT_STATUS_SUCCESS;
1269fe1c642dSBill Krier struct user_acct_info *user;
1270fe1c642dSBill Krier smb_pwditer_t pwi;
1271fe1c642dSBill Krier smb_luser_t *uinfo;
1272fe1c642dSBill Krier int num_users;
1273fe1c642dSBill Krier int start_idx;
1274fe1c642dSBill Krier int max_retcnt, retcnt;
1275fe1c642dSBill Krier int skip;
1276fe1c642dSBill Krier
1277fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
1278fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
1279fe1c642dSBill Krier goto error;
1280fe1c642dSBill Krier }
1281fe1c642dSBill Krier
1282fe1c642dSBill Krier if (!SAMR_VALID_DISPLEVEL(param->level)) {
1283fe1c642dSBill Krier status = NT_STATUS_INVALID_INFO_CLASS;
1284fe1c642dSBill Krier goto error;
1285fe1c642dSBill Krier }
1286fe1c642dSBill Krier
1287fe1c642dSBill Krier if (!SAMR_SUPPORTED_DISPLEVEL(param->level)) {
1288fe1c642dSBill Krier status = NT_STATUS_NOT_IMPLEMENTED;
1289fe1c642dSBill Krier goto error;
1290fe1c642dSBill Krier }
1291fe1c642dSBill Krier
1292fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
1293fe1c642dSBill Krier
1294fe1c642dSBill Krier switch (data->kd_type) {
1295fe1c642dSBill Krier case SMB_DOMAIN_BUILTIN:
1296fe1c642dSBill Krier goto no_info;
1297fe1c642dSBill Krier
1298fe1c642dSBill Krier case SMB_DOMAIN_LOCAL:
1299fe1c642dSBill Krier num_users = smb_sam_usr_cnt();
1300fe1c642dSBill Krier start_idx = param->start_idx;
1301fe1c642dSBill Krier if ((num_users == 0) || (start_idx >= num_users))
1302fe1c642dSBill Krier goto no_info;
1303fe1c642dSBill Krier
1304fe1c642dSBill Krier max_retcnt = num_users - start_idx;
1305fe1c642dSBill Krier if (max_retcnt > param->max_entries)
1306fe1c642dSBill Krier max_retcnt = param->max_entries;
1307fe1c642dSBill Krier param->users.acct = NDR_MALLOC(mxa,
1308fe1c642dSBill Krier max_retcnt * sizeof (struct user_acct_info));
1309fe1c642dSBill Krier user = param->users.acct;
1310fe1c642dSBill Krier if (user == NULL) {
1311fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY;
1312fe1c642dSBill Krier goto error;
1313fe1c642dSBill Krier }
1314fe1c642dSBill Krier bzero(user, max_retcnt * sizeof (struct user_acct_info));
1315fe1c642dSBill Krier
1316fe1c642dSBill Krier if (smb_pwd_iteropen(&pwi) != SMB_PWE_SUCCESS)
1317fe1c642dSBill Krier goto no_info;
1318fe1c642dSBill Krier
1319fe1c642dSBill Krier skip = retcnt = 0;
1320fe1c642dSBill Krier while ((uinfo = smb_pwd_iterate(&pwi)) != NULL) {
1321fe1c642dSBill Krier if (skip++ < start_idx)
1322fe1c642dSBill Krier continue;
1323fe1c642dSBill Krier
1324fe1c642dSBill Krier if (retcnt++ >= max_retcnt)
1325fe1c642dSBill Krier break;
1326fe1c642dSBill Krier
1327fe1c642dSBill Krier assert(uinfo->su_name != NULL);
1328fe1c642dSBill Krier
1329fe1c642dSBill Krier user->index = start_idx + retcnt;
1330fe1c642dSBill Krier user->rid = uinfo->su_rid;
1331fe1c642dSBill Krier user->ctrl = ACF_NORMUSER | ACF_PWDNOEXP;
1332fe1c642dSBill Krier if (uinfo->su_ctrl & SMB_PWF_DISABLE)
1333fe1c642dSBill Krier user->ctrl |= ACF_DISABLED;
1334fe1c642dSBill Krier if (NDR_MSTRING(mxa, uinfo->su_name,
1335fe1c642dSBill Krier (ndr_mstring_t *)&user->name) == -1) {
1336fe1c642dSBill Krier smb_pwd_iterclose(&pwi);
1337fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY;
1338fe1c642dSBill Krier goto error;
1339fe1c642dSBill Krier }
1340fe1c642dSBill Krier (void) NDR_MSTRING(mxa, uinfo->su_fullname,
1341fe1c642dSBill Krier (ndr_mstring_t *)&user->fullname);
1342fe1c642dSBill Krier (void) NDR_MSTRING(mxa, uinfo->su_desc,
1343fe1c642dSBill Krier (ndr_mstring_t *)&user->desc);
1344fe1c642dSBill Krier user++;
1345fe1c642dSBill Krier }
1346fe1c642dSBill Krier smb_pwd_iterclose(&pwi);
1347fe1c642dSBill Krier
1348fe1c642dSBill Krier if (retcnt >= max_retcnt) {
1349fe1c642dSBill Krier retcnt = max_retcnt;
1350fe1c642dSBill Krier param->status = status;
1351fe1c642dSBill Krier } else {
1352148c5f43SAlan Wright param->status = NT_STATUS_MORE_ENTRIES;
1353fe1c642dSBill Krier }
1354fe1c642dSBill Krier
1355fe1c642dSBill Krier param->users.total_size = num_users;
1356fe1c642dSBill Krier param->users.returned_size = retcnt;
1357fe1c642dSBill Krier param->users.switch_value = param->level;
1358fe1c642dSBill Krier param->users.count = retcnt;
1359fe1c642dSBill Krier
1360fe1c642dSBill Krier break;
1361fe1c642dSBill Krier
1362fe1c642dSBill Krier default:
1363fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
1364fe1c642dSBill Krier goto error;
1365fe1c642dSBill Krier }
1366fe1c642dSBill Krier
1367fe1c642dSBill Krier return (NDR_DRC_OK);
1368fe1c642dSBill Krier
1369fe1c642dSBill Krier no_info:
1370fe1c642dSBill Krier param->users.total_size = 0;
1371fe1c642dSBill Krier param->users.returned_size = 0;
1372fe1c642dSBill Krier param->users.switch_value = param->level;
1373fe1c642dSBill Krier param->users.count = 0;
1374fe1c642dSBill Krier param->users.acct = NULL;
1375fe1c642dSBill Krier param->status = status;
1376fe1c642dSBill Krier return (NDR_DRC_OK);
1377fe1c642dSBill Krier
1378fe1c642dSBill Krier error:
1379fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDispInfo));
1380fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
1381fe1c642dSBill Krier return (NDR_DRC_OK);
1382fe1c642dSBill Krier }
1383fe1c642dSBill Krier
1384fe1c642dSBill Krier /*
1385fe1c642dSBill Krier * samr_s_EnumDomainGroups
1386fe1c642dSBill Krier *
1387fe1c642dSBill Krier *
1388fe1c642dSBill Krier * This function is supposed to return local group information.
1389fe1c642dSBill Krier * As we don't support local users, this function dosen't send
1390fe1c642dSBill Krier * back any information.
1391fe1c642dSBill Krier *
1392fe1c642dSBill Krier * Added template that returns information for a domain group as None.
1393fe1c642dSBill Krier * All information is hard-coded from packet captures.
1394fe1c642dSBill Krier */
1395fe1c642dSBill Krier static int
samr_s_EnumDomainGroups(void * arg,ndr_xa_t * mxa)1396fe1c642dSBill Krier samr_s_EnumDomainGroups(void *arg, ndr_xa_t *mxa)
1397fe1c642dSBill Krier {
1398fe1c642dSBill Krier struct samr_EnumDomainGroups *param = arg;
1399fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
1400fe1c642dSBill Krier DWORD status = NT_STATUS_SUCCESS;
1401fe1c642dSBill Krier
1402fe1c642dSBill Krier if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL)
1403fe1c642dSBill Krier status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1404fe1c642dSBill Krier
1405fe1c642dSBill Krier param->total_size = 0;
1406fe1c642dSBill Krier param->returned_size = 0;
1407fe1c642dSBill Krier param->switch_value = 3;
1408fe1c642dSBill Krier param->count = 0;
1409fe1c642dSBill Krier param->groups = 0;
1410fe1c642dSBill Krier param->status = status;
1411fe1c642dSBill Krier return (NDR_DRC_OK);
1412fe1c642dSBill Krier
1413fe1c642dSBill Krier #ifdef SAMR_SUPPORT_GROUPS
1414fe1c642dSBill Krier if ((desc->discrim != SAMR_LOCAL_DOMAIN) || (param->start_idx != 0)) {
1415fe1c642dSBill Krier param->total_size = 0;
1416fe1c642dSBill Krier param->returned_size = 0;
1417fe1c642dSBill Krier param->switch_value = 3;
1418fe1c642dSBill Krier param->count = 0;
1419fe1c642dSBill Krier param->groups = 0;
1420fe1c642dSBill Krier } else {
1421fe1c642dSBill Krier param->total_size = 64;
1422fe1c642dSBill Krier param->returned_size = 64;
1423fe1c642dSBill Krier param->switch_value = 3;
1424fe1c642dSBill Krier param->count = 1;
1425fe1c642dSBill Krier param->groups = (struct group_disp_info *)NDR_MALLOC(
1426fe1c642dSBill Krier mxa, sizeof (struct group_disp_info));
1427fe1c642dSBill Krier
1428fe1c642dSBill Krier param->groups->count = 1;
1429fe1c642dSBill Krier param->groups->acct[0].index = 1;
1430fe1c642dSBill Krier param->groups->acct[0].rid = 513;
1431fe1c642dSBill Krier param->groups->acct[0].ctrl = 0x7;
1432fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "None",
1433fe1c642dSBill Krier (ndr_mstring_t *)¶m->groups->acct[0].name);
1434fe1c642dSBill Krier
1435fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "Ordinary users",
1436fe1c642dSBill Krier (ndr_mstring_t *)¶m->groups->acct[0].desc);
1437fe1c642dSBill Krier }
1438fe1c642dSBill Krier
1439fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
1440fe1c642dSBill Krier return (NDR_DRC_OK);
1441fe1c642dSBill Krier #endif
1442fe1c642dSBill Krier }
1443fe1c642dSBill Krier
1444fe1c642dSBill Krier /*
1445fe1c642dSBill Krier * samr_s_OpenAlias
1446fe1c642dSBill Krier *
1447fe1c642dSBill Krier * Lookup for requested alias, if it exists return a handle
1448fe1c642dSBill Krier * for that alias. The alias domain sid should match with
1449fe1c642dSBill Krier * the passed domain handle.
1450fe1c642dSBill Krier */
1451fe1c642dSBill Krier static int
samr_s_OpenAlias(void * arg,ndr_xa_t * mxa)1452fe1c642dSBill Krier samr_s_OpenAlias(void *arg, ndr_xa_t *mxa)
1453fe1c642dSBill Krier {
1454fe1c642dSBill Krier struct samr_OpenAlias *param = arg;
1455fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
1456fe1c642dSBill Krier ndr_handle_t *hd;
1457fe1c642dSBill Krier 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;
1464fe1c642dSBill Krier int rc;
1465fe1c642dSBill Krier
1466fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
1467fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
1468fe1c642dSBill Krier goto open_alias_err;
1469fe1c642dSBill Krier }
1470fe1c642dSBill Krier
1471c5866007SKeyur Desai if ((param->access_mask & SAMR_ALIAS_ACCESS_ALL_ACCESS) == 0) {
1472fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
1473fe1c642dSBill Krier goto open_alias_err;
1474fe1c642dSBill Krier }
1475fe1c642dSBill Krier
1476fe1c642dSBill Krier 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);
1500fe1c642dSBill Krier if (rc != SMB_LGRP_SUCCESS) {
1501fe1c642dSBill Krier status = NT_STATUS_NO_SUCH_ALIAS;
1502fe1c642dSBill Krier goto open_alias_err;
1503fe1c642dSBill Krier }
1504f96bd5c8SAlan Wright break;
1505f96bd5c8SAlan Wright
1506f96bd5c8SAlan Wright default:
1507f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1508f96bd5c8SAlan Wright goto open_alias_err;
1509f96bd5c8SAlan Wright }
1510fe1c642dSBill Krier
1511fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, data->kd_type, param->rid);
1512fe1c642dSBill Krier if (id) {
1513fe1c642dSBill Krier bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t));
1514fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
1515fe1c642dSBill Krier return (NDR_DRC_OK);
1516fe1c642dSBill Krier }
1517fe1c642dSBill Krier
1518fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY;
1519fe1c642dSBill Krier
1520fe1c642dSBill Krier open_alias_err:
1521fe1c642dSBill Krier bzero(¶m->alias_handle, sizeof (samr_handle_t));
1522fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
1523fe1c642dSBill Krier return (NDR_DRC_OK);
1524fe1c642dSBill Krier }
1525fe1c642dSBill Krier
1526fe1c642dSBill Krier /*
1527fe1c642dSBill Krier * samr_s_CreateDomainAlias
1528fe1c642dSBill Krier *
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.
1534fe1c642dSBill Krier */
1535fe1c642dSBill Krier static int
samr_s_CreateDomainAlias(void * arg,ndr_xa_t * mxa)1536fe1c642dSBill Krier samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa)
1537fe1c642dSBill Krier {
1538fe1c642dSBill Krier struct samr_CreateDomainAlias *param = arg;
1539fe1c642dSBill Krier 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;
1544fe1c642dSBill Krier
1545c5866007SKeyur Desai if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) != NULL) {
1546fe1c642dSBill Krier bzero(param, sizeof (struct samr_CreateDomainAlias));
1547fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1548fe1c642dSBill Krier return (NDR_DRC_OK);
1549fe1c642dSBill Krier }
1550fe1c642dSBill Krier
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);
1556c5866007SKeyur Desai }
1557c5866007SKeyur Desai
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));
1561fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
1562fe1c642dSBill Krier return (NDR_DRC_OK);
1563fe1c642dSBill Krier }
1564fe1c642dSBill Krier
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);
1569fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
1570fe1c642dSBill Krier return (NDR_DRC_OK);
1571c5866007SKeyur Desai }
1572c5866007SKeyur Desai
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 }
1580c5866007SKeyur Desai
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 }
1590c5866007SKeyur Desai
1591c5866007SKeyur Desai return (NDR_DRC_OK);
1592fe1c642dSBill Krier }
1593fe1c642dSBill Krier
1594fe1c642dSBill Krier /*
1595fe1c642dSBill Krier * samr_s_SetAliasInfo
1596fe1c642dSBill Krier *
1597fe1c642dSBill Krier * Similar to NetLocalGroupSetInfo.
1598fe1c642dSBill Krier */
1599fe1c642dSBill Krier static int
samr_s_SetAliasInfo(void * arg,ndr_xa_t * mxa)1600fe1c642dSBill Krier samr_s_SetAliasInfo(void *arg, ndr_xa_t *mxa)
1601fe1c642dSBill Krier {
1602fe1c642dSBill Krier struct samr_SetAliasInfo *param = arg;
1603fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1604fe1c642dSBill Krier DWORD status = NT_STATUS_SUCCESS;
1605fe1c642dSBill Krier
1606fe1c642dSBill Krier if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL)
1607fe1c642dSBill Krier status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1608fe1c642dSBill Krier
1609fe1c642dSBill Krier param->status = status;
1610fe1c642dSBill Krier return (NDR_DRC_OK);
1611fe1c642dSBill Krier }
1612fe1c642dSBill Krier
1613fe1c642dSBill Krier /*
1614fe1c642dSBill Krier * samr_s_QueryAliasInfo
1615fe1c642dSBill Krier *
1616fe1c642dSBill Krier * Retrieves information about the specified local group account
1617fe1c642dSBill Krier * by given handle.
1618fe1c642dSBill Krier */
1619fe1c642dSBill Krier static int
samr_s_QueryAliasInfo(void * arg,ndr_xa_t * mxa)1620fe1c642dSBill Krier samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa)
1621fe1c642dSBill Krier {
1622fe1c642dSBill Krier struct samr_QueryAliasInfo *param = arg;
1623fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1624fe1c642dSBill Krier ndr_handle_t *hd;
1625fe1c642dSBill Krier samr_keydata_t *data;
1626fe1c642dSBill Krier 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;
1634fe1c642dSBill Krier uint32_t status;
1635fe1c642dSBill Krier int rc;
1636fe1c642dSBill Krier
1637fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
1638fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
1639fe1c642dSBill Krier goto query_alias_err;
1640fe1c642dSBill Krier }
1641fe1c642dSBill Krier
1642fe1c642dSBill Krier 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);
1669fe1c642dSBill Krier if (rc != SMB_LGRP_SUCCESS) {
1670fe1c642dSBill Krier status = NT_STATUS_NO_SUCH_ALIAS;
1671fe1c642dSBill Krier goto query_alias_err;
1672fe1c642dSBill Krier }
1673f96bd5c8SAlan Wright name = grp.sg_name;
1674f96bd5c8SAlan Wright desc = grp.sg_cmnt;
1675f96bd5c8SAlan Wright break;
1676f96bd5c8SAlan Wright
1677f96bd5c8SAlan Wright default:
1678f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1679f96bd5c8SAlan Wright goto query_alias_err;
1680f96bd5c8SAlan Wright }
1681fe1c642dSBill Krier
1682fe1c642dSBill Krier switch (param->level) {
1683eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_GENERAL:
1684fe1c642dSBill Krier param->ru.info1.level = param->level;
1685f96bd5c8SAlan Wright (void) NDR_MSTRING(mxa, name,
1686fe1c642dSBill Krier (ndr_mstring_t *)¶m->ru.info1.name);
1687f96bd5c8SAlan Wright (void) NDR_MSTRING(mxa, desc,
1688fe1c642dSBill Krier (ndr_mstring_t *)¶m->ru.info1.desc);
1689eef90b86SGordon Ross param->ru.info1.member_count = 1;
1690fe1c642dSBill Krier break;
1691fe1c642dSBill Krier
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);
1696eef90b86SGordon Ross break;
1697eef90b86SGordon Ross
1698eef90b86SGordon Ross case SAMR_QUERY_ALIAS_INFO_COMMENT:
1699fe1c642dSBill Krier param->ru.info3.level = param->level;
1700f96bd5c8SAlan Wright (void) NDR_MSTRING(mxa, desc,
1701fe1c642dSBill Krier (ndr_mstring_t *)¶m->ru.info3.desc);
1702fe1c642dSBill Krier break;
1703fe1c642dSBill Krier
1704fe1c642dSBill Krier default:
17059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (gd_type == SMB_DOMAIN_LOCAL)
1706fe1c642dSBill Krier smb_lgrp_free(&grp);
1707fe1c642dSBill Krier status = NT_STATUS_INVALID_INFO_CLASS;
1708fe1c642dSBill Krier goto query_alias_err;
1709fe1c642dSBill Krier };
1710fe1c642dSBill Krier
17119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (gd_type == SMB_DOMAIN_LOCAL)
1712fe1c642dSBill Krier smb_lgrp_free(&grp);
1713fe1c642dSBill Krier param->address = (DWORD)(uintptr_t)¶m->ru;
1714fe1c642dSBill Krier param->status = 0;
1715fe1c642dSBill Krier return (NDR_DRC_OK);
1716fe1c642dSBill Krier
1717fe1c642dSBill Krier query_alias_err:
1718fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
1719fe1c642dSBill Krier return (NDR_DRC_OK);
1720fe1c642dSBill Krier }
1721fe1c642dSBill Krier
1722fe1c642dSBill Krier /*
1723fe1c642dSBill Krier * samr_s_DeleteDomainAlias
1724fe1c642dSBill Krier *
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.
1728fe1c642dSBill Krier *
1729c5866007SKeyur Desai * The caller must have administrator rights to execute this function.
1730fe1c642dSBill Krier */
1731fe1c642dSBill Krier static int
samr_s_DeleteDomainAlias(void * arg,ndr_xa_t * mxa)1732fe1c642dSBill Krier samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa)
1733fe1c642dSBill Krier {
1734fe1c642dSBill Krier struct samr_DeleteDomainAlias *param = arg;
1735fe1c642dSBill Krier 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;
1743fe1c642dSBill Krier
1744c5866007SKeyur Desai if (!ndr_is_admin(mxa)) {
1745c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias));
1746c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
1747c5866007SKeyur Desai return (NDR_DRC_OK);
1748c5866007SKeyur Desai }
1749c5866007SKeyur Desai
1750c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
1751fe1c642dSBill Krier bzero(param, sizeof (struct samr_DeleteDomainAlias));
1752fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1753fe1c642dSBill Krier return (NDR_DRC_OK);
1754fe1c642dSBill Krier }
1755fe1c642dSBill Krier
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;
1759c5866007SKeyur Desai
1760c5866007SKeyur Desai switch (gd_type) {
1761c5866007SKeyur Desai case SMB_DOMAIN_BUILTIN:
1762fe1c642dSBill Krier bzero(param, sizeof (struct samr_DeleteDomainAlias));
1763c5866007SKeyur Desai status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED);
1764c5866007SKeyur Desai break;
1765fe1c642dSBill Krier
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;
1773fe1c642dSBill Krier }
1774fe1c642dSBill Krier
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;
1783c5866007SKeyur Desai
1784c5866007SKeyur Desai default:
1785c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias));
1786c5866007SKeyur Desai status = NT_SC_ERROR(NT_STATUS_NO_SUCH_ALIAS);
1787fe1c642dSBill Krier }
1788fe1c642dSBill Krier
1789c5866007SKeyur Desai param->status = status;
1790fe1c642dSBill Krier return (NDR_DRC_OK);
1791fe1c642dSBill Krier }
1792fe1c642dSBill Krier
1793fe1c642dSBill Krier /*
1794fe1c642dSBill Krier * samr_s_EnumDomainAliases
1795fe1c642dSBill Krier *
1796fe1c642dSBill Krier * This function sends back a list which contains all local groups' name.
1797fe1c642dSBill Krier */
1798fe1c642dSBill Krier static int
samr_s_EnumDomainAliases(void * arg,ndr_xa_t * mxa)1799fe1c642dSBill Krier samr_s_EnumDomainAliases(void *arg, ndr_xa_t *mxa)
1800fe1c642dSBill Krier {
1801fe1c642dSBill Krier struct samr_EnumDomainAliases *param = arg;
1802fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
1803fe1c642dSBill Krier ndr_handle_t *hd;
1804fe1c642dSBill Krier samr_keydata_t *data;
1805fe1c642dSBill Krier smb_group_t grp;
1806fe1c642dSBill Krier smb_giter_t gi;
1807fe1c642dSBill Krier int cnt, skip, i;
1808fe1c642dSBill Krier struct name_rid *info;
1809fe1c642dSBill Krier
1810fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
1811fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumDomainAliases));
1812fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1813fe1c642dSBill Krier return (NDR_DRC_OK);
1814fe1c642dSBill Krier }
1815fe1c642dSBill Krier
1816fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
1817fe1c642dSBill Krier
1818fe1c642dSBill Krier cnt = smb_sam_grp_cnt(data->kd_type);
1819fe1c642dSBill Krier if (cnt <= param->resume_handle) {
1820fe1c642dSBill Krier param->aliases = (struct aliases_info *)NDR_MALLOC(mxa,
1821fe1c642dSBill Krier sizeof (struct aliases_info));
1822fe1c642dSBill Krier
1823fe1c642dSBill Krier if (param->aliases == NULL) {
1824fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumDomainAliases));
1825fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1826fe1c642dSBill Krier return (NDR_DRC_OK);
1827fe1c642dSBill Krier }
1828fe1c642dSBill Krier
1829fe1c642dSBill Krier bzero(param->aliases, sizeof (struct aliases_info));
1830fe1c642dSBill Krier param->out_resume = 0;
1831fe1c642dSBill Krier param->entries = 0;
1832fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
1833fe1c642dSBill Krier return (NDR_DRC_OK);
1834fe1c642dSBill Krier }
1835fe1c642dSBill Krier
1836fe1c642dSBill Krier cnt -= param->resume_handle;
1837fe1c642dSBill Krier param->aliases = (struct aliases_info *)NDR_MALLOC(mxa,
1838fe1c642dSBill Krier sizeof (struct aliases_info) + (cnt-1) * sizeof (struct name_rid));
1839fe1c642dSBill Krier
1840fe1c642dSBill Krier if (param->aliases == NULL) {
1841fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumDomainAliases));
1842fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1843fe1c642dSBill Krier return (NDR_DRC_OK);
1844fe1c642dSBill Krier }
1845fe1c642dSBill Krier
1846fe1c642dSBill Krier if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
1847fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumDomainAliases));
1848fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR);
1849fe1c642dSBill Krier return (NDR_DRC_OK);
1850fe1c642dSBill Krier }
1851fe1c642dSBill Krier
1852fe1c642dSBill Krier skip = i = 0;
1853fe1c642dSBill Krier info = param->aliases->info;
1854fe1c642dSBill Krier while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) {
1855fe1c642dSBill Krier if ((skip++ >= param->resume_handle) &&
1856fe1c642dSBill Krier (grp.sg_domain == data->kd_type) && (i++ < cnt)) {
1857fe1c642dSBill Krier info->rid = grp.sg_rid;
1858fe1c642dSBill Krier (void) NDR_MSTRING(mxa, grp.sg_name,
1859fe1c642dSBill Krier (ndr_mstring_t *)&info->name);
1860fe1c642dSBill Krier
1861fe1c642dSBill Krier info++;
1862fe1c642dSBill Krier }
1863fe1c642dSBill Krier smb_lgrp_free(&grp);
1864fe1c642dSBill Krier }
1865fe1c642dSBill Krier smb_lgrp_iterclose(&gi);
1866fe1c642dSBill Krier
1867fe1c642dSBill Krier param->aliases->count = i;
1868fe1c642dSBill Krier param->aliases->address = i;
1869fe1c642dSBill Krier
1870fe1c642dSBill Krier param->out_resume = i;
1871fe1c642dSBill Krier param->entries = i;
1872fe1c642dSBill Krier param->status = 0;
1873fe1c642dSBill Krier return (NDR_DRC_OK);
1874fe1c642dSBill Krier }
1875fe1c642dSBill Krier
1876fe1c642dSBill Krier /*
1877cb174861Sjoyce mcintosh * samr_s_Connect4
1878fe1c642dSBill Krier */
1879fe1c642dSBill Krier static int
samr_s_Connect4(void * arg,ndr_xa_t * mxa)1880cb174861Sjoyce mcintosh samr_s_Connect4(void *arg, ndr_xa_t *mxa)
1881fe1c642dSBill Krier {
1882cb174861Sjoyce mcintosh struct samr_Connect4 *param = arg;
1883f96bd5c8SAlan Wright ndr_hdid_t *id;
1884fe1c642dSBill Krier
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);
1892fe1c642dSBill Krier }
1893fe1c642dSBill Krier
1894f96bd5c8SAlan Wright return (NDR_DRC_OK);
1895f96bd5c8SAlan Wright }
1896fe1c642dSBill Krier
1897fe1c642dSBill Krier /*
1898cb174861Sjoyce mcintosh * samr_s_Connect5
1899fe1c642dSBill Krier *
1900cb174861Sjoyce mcintosh * This is the connect5 form of the connect request used by Windows XP.
1901fe1c642dSBill Krier * Returns an RPC fault for now.
1902fe1c642dSBill Krier */
1903fe1c642dSBill Krier /*ARGSUSED*/
1904fe1c642dSBill Krier static int
samr_s_Connect5(void * arg,ndr_xa_t * mxa)1905cb174861Sjoyce mcintosh samr_s_Connect5(void *arg, ndr_xa_t *mxa)
1906fe1c642dSBill Krier {
1907cb174861Sjoyce mcintosh struct samr_Connect5 *param = arg;
1908fe1c642dSBill Krier
1909cb174861Sjoyce mcintosh bzero(param, sizeof (struct samr_Connect5));
1910fe1c642dSBill Krier return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
1911fe1c642dSBill Krier }
1912fe1c642dSBill Krier
1913fe1c642dSBill Krier static ndr_stub_table_t samr_stub_table[] = {
1914cb174861Sjoyce mcintosh { samr_s_Connect, SAMR_OPNUM_Connect },
1915fe1c642dSBill Krier { samr_s_CloseHandle, SAMR_OPNUM_CloseHandle },
1916*9242c919SMatt Barden { samr_s_QuerySecObject, SAMR_OPNUM_QuerySecObject },
1917fe1c642dSBill Krier { samr_s_LookupDomain, SAMR_OPNUM_LookupDomain },
1918fe1c642dSBill Krier { samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains },
1919fe1c642dSBill Krier { samr_s_OpenDomain, SAMR_OPNUM_OpenDomain },
1920fe1c642dSBill Krier { samr_s_QueryDomainInfo, SAMR_OPNUM_QueryDomainInfo },
1921f96bd5c8SAlan Wright { samr_s_QueryInfoDomain2, SAMR_OPNUM_QueryInfoDomain2 },
1922fe1c642dSBill Krier { samr_s_LookupNames, SAMR_OPNUM_LookupNames },
1923fe1c642dSBill Krier { samr_s_OpenUser, SAMR_OPNUM_OpenUser },
1924fe1c642dSBill Krier { samr_s_DeleteUser, SAMR_OPNUM_DeleteUser },
1925fe1c642dSBill Krier { samr_s_QueryUserInfo, SAMR_OPNUM_QueryUserInfo },
1926fe1c642dSBill Krier { samr_s_QueryUserGroups, SAMR_OPNUM_QueryUserGroups },
1927fe1c642dSBill Krier { samr_s_OpenGroup, SAMR_OPNUM_OpenGroup },
1928cb174861Sjoyce mcintosh { samr_s_Connect2, SAMR_OPNUM_Connect2 },
1929fe1c642dSBill Krier { samr_s_GetUserPwInfo, SAMR_OPNUM_GetUserPwInfo },
1930fe1c642dSBill Krier { samr_s_CreateUser, SAMR_OPNUM_CreateUser },
19311ed6b69aSGordon Ross { samr_s_ChangePasswordUser2, SAMR_OPNUM_ChangePasswordUser2 },
1932fe1c642dSBill Krier { samr_s_GetDomainPwInfo, SAMR_OPNUM_GetDomainPwInfo },
1933fe1c642dSBill Krier { samr_s_SetUserInfo, SAMR_OPNUM_SetUserInfo },
1934fe1c642dSBill Krier { samr_s_Connect4, SAMR_OPNUM_Connect4 },
1935cb174861Sjoyce mcintosh { samr_s_Connect5, SAMR_OPNUM_Connect5 },
1936fe1c642dSBill Krier { samr_s_QueryDispInfo, SAMR_OPNUM_QueryDispInfo },
1937fe1c642dSBill Krier { samr_s_OpenAlias, SAMR_OPNUM_OpenAlias },
1938fe1c642dSBill Krier { samr_s_CreateDomainAlias, SAMR_OPNUM_CreateDomainAlias },
1939fe1c642dSBill Krier { samr_s_SetAliasInfo, SAMR_OPNUM_SetAliasInfo },
1940fe1c642dSBill Krier { samr_s_QueryAliasInfo, SAMR_OPNUM_QueryAliasInfo },
1941fe1c642dSBill Krier { samr_s_DeleteDomainAlias, SAMR_OPNUM_DeleteDomainAlias },
1942fe1c642dSBill Krier { samr_s_EnumDomainAliases, SAMR_OPNUM_EnumDomainAliases },
1943fe1c642dSBill Krier { 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 },
1947fe1c642dSBill Krier {0}
1948fe1c642dSBill Krier };
1949fe1c642dSBill Krier
1950fe1c642dSBill Krier /*
1951fe1c642dSBill Krier * There is a bug in the way that midl and the marshalling code handles
1952fe1c642dSBill Krier * unions so we need to fix some of the data offsets at runtime. The
1953fe1c642dSBill Krier * following macros and the fixup functions handle the corrections.
1954fe1c642dSBill Krier */
1955fe1c642dSBill Krier
1956fe1c642dSBill Krier DECL_FIXUP_STRUCT(samr_QueryAliasInfo_ru);
1957fe1c642dSBill Krier DECL_FIXUP_STRUCT(samr_QueryAliasInfoRes);
1958fe1c642dSBill Krier DECL_FIXUP_STRUCT(samr_QueryAliasInfo);
1959fe1c642dSBill Krier
1960fe1c642dSBill Krier DECL_FIXUP_STRUCT(QueryUserInfo_result_u);
1961fe1c642dSBill Krier DECL_FIXUP_STRUCT(QueryUserInfo_result);
1962fe1c642dSBill Krier DECL_FIXUP_STRUCT(samr_QueryUserInfo);
1963fe1c642dSBill Krier
1964fe1c642dSBill Krier void
fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo * val)1965fe1c642dSBill Krier fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo *val)
1966fe1c642dSBill Krier {
1967fe1c642dSBill Krier unsigned short size1 = 0;
1968fe1c642dSBill Krier unsigned short size2 = 0;
1969fe1c642dSBill Krier unsigned short size3 = 0;
1970fe1c642dSBill Krier
1971fe1c642dSBill Krier 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;
1981fe1c642dSBill Krier
1982fe1c642dSBill Krier default:
1983fe1c642dSBill Krier return;
1984fe1c642dSBill Krier };
1985fe1c642dSBill Krier
1986fe1c642dSBill Krier size2 = size1 + (2 * sizeof (DWORD));
1987fe1c642dSBill Krier size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
1988fe1c642dSBill Krier
1989fe1c642dSBill Krier FIXUP_PDU_SIZE(samr_QueryAliasInfo_ru, size1);
1990fe1c642dSBill Krier FIXUP_PDU_SIZE(samr_QueryAliasInfoRes, size2);
1991fe1c642dSBill Krier FIXUP_PDU_SIZE(samr_QueryAliasInfo, size3);
1992fe1c642dSBill Krier }
1993fe1c642dSBill Krier
1994fe1c642dSBill Krier void
fixup_samr_QueryUserInfo(struct samr_QueryUserInfo * val)1995fe1c642dSBill Krier fixup_samr_QueryUserInfo(struct samr_QueryUserInfo *val)
1996fe1c642dSBill Krier {
1997fe1c642dSBill Krier unsigned short size1 = 0;
1998fe1c642dSBill Krier unsigned short size2 = 0;
1999fe1c642dSBill Krier unsigned short size3 = 0;
2000fe1c642dSBill Krier
2001fe1c642dSBill Krier switch (val->switch_index) {
2002fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 1);
2003fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 6);
2004fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 7);
2005fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 8);
2006fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 9);
2007fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 16);
2008fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 21);
2009fe1c642dSBill Krier
2010fe1c642dSBill Krier default:
2011fe1c642dSBill Krier return;
2012fe1c642dSBill Krier };
2013fe1c642dSBill Krier
2014fe1c642dSBill Krier size2 = size1 + (2 * sizeof (DWORD));
2015fe1c642dSBill Krier size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
2016fe1c642dSBill Krier
2017fe1c642dSBill Krier FIXUP_PDU_SIZE(QueryUserInfo_result_u, size1);
2018fe1c642dSBill Krier FIXUP_PDU_SIZE(QueryUserInfo_result, size2);
2019fe1c642dSBill Krier FIXUP_PDU_SIZE(samr_QueryUserInfo, size3);
2020fe1c642dSBill Krier }
2021fe1c642dSBill Krier
2022fe1c642dSBill Krier /*
2023fe1c642dSBill Krier * As long as there is only one entry in the union, there is no need
2024fe1c642dSBill Krier * to patch anything.
2025fe1c642dSBill Krier */
2026fe1c642dSBill Krier /*ARGSUSED*/
2027fe1c642dSBill Krier void
fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo * val)2028fe1c642dSBill Krier fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo *val)
2029fe1c642dSBill Krier {
2030fe1c642dSBill Krier }
2031