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*1ed6b69aSGordon Ross * Copyright 2012 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>
42fe1c642dSBill Krier #include <smbsrv/libsmb.h>
43fe1c642dSBill Krier #include <smbsrv/libmlrpc.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);
105fe1c642dSBill Krier static int samr_call_stub(ndr_xa_t *mxa);
106fe1c642dSBill Krier static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *,
107fe1c642dSBill Krier ndr_xa_t *);
108fe1c642dSBill Krier
109fe1c642dSBill Krier static ndr_stub_table_t samr_stub_table[];
110fe1c642dSBill Krier
111fe1c642dSBill Krier static ndr_service_t samr_service = {
112fe1c642dSBill Krier "SAMR", /* name */
113fe1c642dSBill Krier "Security Accounts Manager", /* desc */
114fe1c642dSBill Krier "\\samr", /* endpoint */
115fe1c642dSBill Krier PIPE_LSASS, /* sec_addr_port */
116fe1c642dSBill Krier "12345778-1234-abcd-ef00-0123456789ac", 1, /* abstract */
117fe1c642dSBill Krier NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */
118fe1c642dSBill Krier 0, /* no bind_instance_size */
119fe1c642dSBill Krier NULL, /* no bind_req() */
120fe1c642dSBill Krier NULL, /* no unbind_and_close() */
121fe1c642dSBill Krier samr_call_stub, /* call_stub() */
122fe1c642dSBill Krier &TYPEINFO(samr_interface), /* interface ti */
123fe1c642dSBill Krier samr_stub_table /* stub_table */
124fe1c642dSBill Krier };
125fe1c642dSBill Krier
126fe1c642dSBill Krier /*
127fe1c642dSBill Krier * samr_initialize
128fe1c642dSBill Krier *
129fe1c642dSBill Krier * This function registers the SAM RPC interface with the RPC runtime
130fe1c642dSBill Krier * library. It must be called in order to use either the client side
131fe1c642dSBill Krier * or the server side functions.
132fe1c642dSBill Krier */
133fe1c642dSBill Krier void
samr_initialize(void)134fe1c642dSBill Krier samr_initialize(void)
135fe1c642dSBill Krier {
136fe1c642dSBill Krier (void) ndr_svc_register(&samr_service);
137fe1c642dSBill Krier }
138fe1c642dSBill Krier
139fe1c642dSBill Krier /*
140fe1c642dSBill Krier * Custom call_stub to set the stream string policy.
141fe1c642dSBill Krier */
142fe1c642dSBill Krier static int
samr_call_stub(ndr_xa_t * mxa)143fe1c642dSBill Krier samr_call_stub(ndr_xa_t *mxa)
144fe1c642dSBill Krier {
145fe1c642dSBill Krier NDS_SETF(&mxa->send_nds, NDS_F_NOTERM);
146fe1c642dSBill Krier NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM);
147fe1c642dSBill Krier
148fe1c642dSBill Krier return (ndr_generic_call_stub(mxa));
149fe1c642dSBill Krier }
150fe1c642dSBill Krier
151fe1c642dSBill Krier /*
152fe1c642dSBill Krier * Handle allocation wrapper to setup the local context.
153fe1c642dSBill Krier */
154fe1c642dSBill Krier static ndr_hdid_t *
samr_hdalloc(ndr_xa_t * mxa,samr_key_t key,smb_domain_type_t domain_type,DWORD rid)155fe1c642dSBill Krier samr_hdalloc(ndr_xa_t *mxa, samr_key_t key, smb_domain_type_t domain_type,
156fe1c642dSBill Krier DWORD rid)
157fe1c642dSBill Krier {
1589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_handle_t *hd;
1599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_hdid_t *id;
160fe1c642dSBill Krier samr_keydata_t *data;
161fe1c642dSBill Krier
162fe1c642dSBill Krier if ((data = malloc(sizeof (samr_keydata_t))) == NULL)
163fe1c642dSBill Krier return (NULL);
164fe1c642dSBill Krier
165fe1c642dSBill Krier data->kd_key = key;
166fe1c642dSBill Krier data->kd_type = domain_type;
167fe1c642dSBill Krier data->kd_rid = rid;
168fe1c642dSBill Krier
1699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((id = ndr_hdalloc(mxa, data)) == NULL) {
1709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States free(data);
1719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NULL);
1729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
1749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((hd = ndr_hdlookup(mxa, id)) != NULL)
1759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States hd->nh_data_free = free;
1769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
1779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (id);
178fe1c642dSBill Krier }
179fe1c642dSBill Krier
180fe1c642dSBill Krier /*
181fe1c642dSBill Krier * Handle deallocation wrapper to free the local context.
182fe1c642dSBill Krier */
183fe1c642dSBill Krier static void
samr_hdfree(ndr_xa_t * mxa,ndr_hdid_t * id)184fe1c642dSBill Krier samr_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id)
185fe1c642dSBill Krier {
186fe1c642dSBill Krier ndr_handle_t *hd;
187fe1c642dSBill Krier
188fe1c642dSBill Krier if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
189fe1c642dSBill Krier free(hd->nh_data);
1909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States hd->nh_data = NULL;
191fe1c642dSBill Krier ndr_hdfree(mxa, id);
192fe1c642dSBill Krier }
193fe1c642dSBill Krier }
194fe1c642dSBill Krier
195fe1c642dSBill Krier /*
196fe1c642dSBill Krier * Handle lookup wrapper to validate the local context.
197fe1c642dSBill Krier */
198fe1c642dSBill Krier static ndr_handle_t *
samr_hdlookup(ndr_xa_t * mxa,ndr_hdid_t * id,samr_key_t key)199fe1c642dSBill Krier samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key)
200fe1c642dSBill Krier {
201fe1c642dSBill Krier ndr_handle_t *hd;
202fe1c642dSBill Krier samr_keydata_t *data;
203fe1c642dSBill Krier
204fe1c642dSBill Krier if ((hd = ndr_hdlookup(mxa, id)) == NULL)
205fe1c642dSBill Krier return (NULL);
206fe1c642dSBill Krier
207fe1c642dSBill Krier if ((data = (samr_keydata_t *)hd->nh_data) == NULL)
208fe1c642dSBill Krier return (NULL);
209fe1c642dSBill Krier
210fe1c642dSBill Krier if (data->kd_key != key)
211fe1c642dSBill Krier return (NULL);
212fe1c642dSBill Krier
213fe1c642dSBill Krier return (hd);
214fe1c642dSBill Krier }
215fe1c642dSBill Krier
216fe1c642dSBill Krier /*
217cb174861Sjoyce mcintosh * samr_s_Connect
218fe1c642dSBill Krier *
219fe1c642dSBill Krier * This is a request to connect to the local SAM database. We don't
220fe1c642dSBill Krier * support any form of update request and our database doesn't
221fe1c642dSBill Krier * contain any private information, so there is little point in
222fe1c642dSBill Krier * doing any access access checking here.
223fe1c642dSBill Krier *
224fe1c642dSBill Krier * Return a handle for use with subsequent SAM requests.
225fe1c642dSBill Krier */
226fe1c642dSBill Krier static int
samr_s_Connect(void * arg,ndr_xa_t * mxa)227cb174861Sjoyce mcintosh samr_s_Connect(void *arg, ndr_xa_t *mxa)
228fe1c642dSBill Krier {
229cb174861Sjoyce mcintosh struct samr_Connect *param = arg;
230fe1c642dSBill Krier ndr_hdid_t *id;
231fe1c642dSBill Krier
232fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
233fe1c642dSBill Krier if (id) {
234fe1c642dSBill Krier bcopy(id, ¶m->handle, sizeof (samr_handle_t));
235fe1c642dSBill Krier param->status = 0;
236fe1c642dSBill Krier } else {
237fe1c642dSBill Krier bzero(¶m->handle, sizeof (samr_handle_t));
238fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
239fe1c642dSBill Krier }
240fe1c642dSBill Krier
241fe1c642dSBill Krier return (NDR_DRC_OK);
242fe1c642dSBill Krier }
243fe1c642dSBill Krier
244fe1c642dSBill Krier /*
245fe1c642dSBill Krier * samr_s_CloseHandle
246fe1c642dSBill Krier *
247fe1c642dSBill Krier * Close the SAM interface specified by the handle.
248fe1c642dSBill Krier * Free the handle and zero out the result handle for the client.
249fe1c642dSBill Krier */
250fe1c642dSBill Krier static int
samr_s_CloseHandle(void * arg,ndr_xa_t * mxa)251fe1c642dSBill Krier samr_s_CloseHandle(void *arg, ndr_xa_t *mxa)
252fe1c642dSBill Krier {
253fe1c642dSBill Krier struct samr_CloseHandle *param = arg;
254fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
255fe1c642dSBill Krier
256fe1c642dSBill Krier samr_hdfree(mxa, id);
257fe1c642dSBill Krier
258fe1c642dSBill Krier bzero(¶m->result_handle, sizeof (samr_handle_t));
259fe1c642dSBill Krier param->status = 0;
260fe1c642dSBill Krier return (NDR_DRC_OK);
261fe1c642dSBill Krier }
262fe1c642dSBill Krier
263fe1c642dSBill Krier /*
264fe1c642dSBill Krier * samr_s_LookupDomain
265fe1c642dSBill Krier *
266fe1c642dSBill Krier * This is a request to map a domain name to a domain SID. We can map
267fe1c642dSBill Krier * the primary domain name, our local domain name (hostname) and the
268fe1c642dSBill Krier * builtin domain names to the appropriate SID. Anything else will be
269fe1c642dSBill Krier * rejected.
270fe1c642dSBill Krier */
271fe1c642dSBill Krier static int
samr_s_LookupDomain(void * arg,ndr_xa_t * mxa)272fe1c642dSBill Krier samr_s_LookupDomain(void *arg, ndr_xa_t *mxa)
273fe1c642dSBill Krier {
274fe1c642dSBill Krier struct samr_LookupDomain *param = arg;
275fe1c642dSBill Krier char *domain_name;
276fe1c642dSBill Krier smb_domain_t di;
277fe1c642dSBill Krier
278fe1c642dSBill Krier if ((domain_name = (char *)param->domain_name.str) == NULL) {
279fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupDomain));
280fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
281fe1c642dSBill Krier return (NDR_DRC_OK);
282fe1c642dSBill Krier }
283fe1c642dSBill Krier
284fe1c642dSBill Krier if (!smb_domain_lookup_name(domain_name, &di)) {
285fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupDomain));
286fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_DOMAIN);
287fe1c642dSBill Krier return (NDR_DRC_OK);
288fe1c642dSBill Krier }
289fe1c642dSBill Krier
290fe1c642dSBill Krier param->sid = (struct samr_sid *)NDR_SIDDUP(mxa, di.di_binsid);
291fe1c642dSBill Krier if (param->sid == NULL) {
292fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupDomain));
293fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
294fe1c642dSBill Krier return (NDR_DRC_OK);
295fe1c642dSBill Krier }
296fe1c642dSBill Krier
297fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
298fe1c642dSBill Krier return (NDR_DRC_OK);
299fe1c642dSBill Krier }
300fe1c642dSBill Krier
301fe1c642dSBill Krier /*
302fe1c642dSBill Krier * samr_s_EnumLocalDomains
303fe1c642dSBill Krier *
304fe1c642dSBill Krier * This is a request for the local domains supported by this server.
305fe1c642dSBill Krier * All we do here is validate the handle and set the status. The real
306fe1c642dSBill Krier * work is done in samr_s_enum_local_domains.
307fe1c642dSBill Krier */
308fe1c642dSBill Krier static int
samr_s_EnumLocalDomains(void * arg,ndr_xa_t * mxa)309fe1c642dSBill Krier samr_s_EnumLocalDomains(void *arg, ndr_xa_t *mxa)
310fe1c642dSBill Krier {
311fe1c642dSBill Krier struct samr_EnumLocalDomain *param = arg;
312fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
313fe1c642dSBill Krier DWORD status;
314fe1c642dSBill Krier
315fe1c642dSBill Krier if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL)
316fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
317fe1c642dSBill Krier else
318fe1c642dSBill Krier status = samr_s_enum_local_domains(param, mxa);
319fe1c642dSBill Krier
320fe1c642dSBill Krier if (status == NT_STATUS_SUCCESS) {
321fe1c642dSBill Krier param->enum_context = param->info->entries_read;
322fe1c642dSBill Krier param->total_entries = param->info->entries_read;
323fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
324fe1c642dSBill Krier } else {
325fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumLocalDomain));
326fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
327fe1c642dSBill Krier }
328fe1c642dSBill Krier
329fe1c642dSBill Krier return (NDR_DRC_OK);
330fe1c642dSBill Krier }
331fe1c642dSBill Krier
332fe1c642dSBill Krier
333fe1c642dSBill Krier /*
334fe1c642dSBill Krier * samr_s_enum_local_domains
335fe1c642dSBill Krier *
336fe1c642dSBill Krier * This function should only be called via samr_s_EnumLocalDomains to
337fe1c642dSBill Krier * ensure that the appropriate validation is performed. We will answer
338fe1c642dSBill Krier * queries about two domains: the local domain, synonymous with the
339fe1c642dSBill Krier * local hostname, and the BUILTIN domain. So we return these two
340fe1c642dSBill Krier * strings.
341fe1c642dSBill Krier *
342fe1c642dSBill Krier * Returns NT status values.
343fe1c642dSBill Krier */
344fe1c642dSBill Krier static DWORD
samr_s_enum_local_domains(struct samr_EnumLocalDomain * param,ndr_xa_t * mxa)345fe1c642dSBill Krier samr_s_enum_local_domains(struct samr_EnumLocalDomain *param,
346fe1c642dSBill Krier ndr_xa_t *mxa)
347fe1c642dSBill Krier {
348fe1c642dSBill Krier struct samr_LocalDomainInfo *info;
349fe1c642dSBill Krier struct samr_LocalDomainEntry *entry;
350fe1c642dSBill Krier char *hostname;
351fe1c642dSBill Krier
352fe1c642dSBill Krier hostname = NDR_MALLOC(mxa, NETBIOS_NAME_SZ);
353fe1c642dSBill Krier if (hostname == NULL)
354fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY);
355fe1c642dSBill Krier
356fe1c642dSBill Krier if (smb_getnetbiosname(hostname, NETBIOS_NAME_SZ) != 0)
357fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY);
358fe1c642dSBill Krier
359fe1c642dSBill Krier entry = NDR_NEWN(mxa, struct samr_LocalDomainEntry, 2);
360fe1c642dSBill Krier if (entry == NULL)
361fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY);
362fe1c642dSBill Krier
363fe1c642dSBill Krier bzero(entry, (sizeof (struct samr_LocalDomainEntry) * 2));
364fe1c642dSBill Krier (void) NDR_MSTRING(mxa, hostname, (ndr_mstring_t *)&entry[0].name);
365fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "Builtin", (ndr_mstring_t *)&entry[1].name);
366fe1c642dSBill Krier
367fe1c642dSBill Krier info = NDR_NEW(mxa, struct samr_LocalDomainInfo);
368fe1c642dSBill Krier if (info == NULL)
369fe1c642dSBill Krier return (NT_STATUS_NO_MEMORY);
370fe1c642dSBill Krier
371fe1c642dSBill Krier info->entries_read = 2;
372fe1c642dSBill Krier info->entry = entry;
373fe1c642dSBill Krier param->info = info;
374fe1c642dSBill Krier return (NT_STATUS_SUCCESS);
375fe1c642dSBill Krier }
376fe1c642dSBill Krier
377fe1c642dSBill Krier /*
378fe1c642dSBill Krier * samr_s_OpenDomain
379fe1c642dSBill Krier *
380fe1c642dSBill Krier * This is a request to open a domain within the local SAM database.
381fe1c642dSBill Krier * The caller must supply a valid connect handle.
382fe1c642dSBill Krier * We return a handle to be used to access objects within this domain.
383fe1c642dSBill Krier */
384fe1c642dSBill Krier static int
samr_s_OpenDomain(void * arg,ndr_xa_t * mxa)385fe1c642dSBill Krier samr_s_OpenDomain(void *arg, ndr_xa_t *mxa)
386fe1c642dSBill Krier {
387fe1c642dSBill Krier struct samr_OpenDomain *param = arg;
388fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
389fe1c642dSBill Krier smb_domain_t domain;
390fe1c642dSBill Krier
391fe1c642dSBill Krier if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) {
392fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (samr_handle_t));
393fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
394fe1c642dSBill Krier return (NDR_DRC_OK);
395fe1c642dSBill Krier }
396fe1c642dSBill Krier
397fe1c642dSBill Krier if (!smb_domain_lookup_sid((smb_sid_t *)param->sid, &domain)) {
398fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (samr_handle_t));
399fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
400fe1c642dSBill Krier return (NDR_DRC_OK);
401fe1c642dSBill Krier }
402fe1c642dSBill Krier
403fe1c642dSBill Krier if ((domain.di_type != SMB_DOMAIN_BUILTIN) &&
404fe1c642dSBill Krier (domain.di_type != SMB_DOMAIN_LOCAL)) {
405fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (samr_handle_t));
406fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
407fe1c642dSBill Krier return (NDR_DRC_OK);
408fe1c642dSBill Krier }
409fe1c642dSBill Krier
410fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_DOMAIN, domain.di_type, 0);
411fe1c642dSBill Krier if (id) {
412fe1c642dSBill Krier bcopy(id, ¶m->domain_handle, sizeof (samr_handle_t));
413fe1c642dSBill Krier param->status = 0;
414fe1c642dSBill Krier } else {
415fe1c642dSBill Krier bzero(¶m->domain_handle, sizeof (samr_handle_t));
416fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
417fe1c642dSBill Krier }
418fe1c642dSBill Krier
419fe1c642dSBill Krier return (NDR_DRC_OK);
420fe1c642dSBill Krier }
421fe1c642dSBill Krier
422fe1c642dSBill Krier /*
423fe1c642dSBill Krier * samr_s_QueryDomainInfo
424fe1c642dSBill Krier *
425fe1c642dSBill Krier * The caller should pass a domain handle.
426fe1c642dSBill Krier *
427fe1c642dSBill Krier * Windows 95 Server Manager sends requests for levels 6 and 7 when
428fe1c642dSBill Krier * the services menu item is selected. Level 2 is basically for getting
429fe1c642dSBill Krier * number of users, groups, and aliases in a domain.
430fe1c642dSBill Krier * We have no information on what the various information levels mean.
431fe1c642dSBill Krier */
432fe1c642dSBill Krier static int
samr_s_QueryDomainInfo(void * arg,ndr_xa_t * mxa)433fe1c642dSBill Krier samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa)
434fe1c642dSBill Krier {
435fe1c642dSBill Krier struct samr_QueryDomainInfo *param = arg;
436fe1c642dSBill Krier struct samr_QueryDomainInfoRes *info;
437fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
438fe1c642dSBill Krier ndr_handle_t *hd;
439fe1c642dSBill Krier samr_keydata_t *data;
440fe1c642dSBill Krier char *domain;
441fe1c642dSBill Krier char hostname[NETBIOS_NAME_SZ];
442fe1c642dSBill Krier int alias_cnt, user_cnt;
443fe1c642dSBill Krier int rc = 0;
444fe1c642dSBill Krier
445fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
446fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo));
447fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
448fe1c642dSBill Krier return (NDR_DRC_OK);
449fe1c642dSBill Krier }
450fe1c642dSBill Krier
451fe1c642dSBill Krier info = NDR_NEW(mxa, struct samr_QueryDomainInfoRes);
452fe1c642dSBill Krier if (info == NULL) {
453fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo));
454fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
455fe1c642dSBill Krier return (NDR_DRC_OK);
456fe1c642dSBill Krier }
457fe1c642dSBill Krier info->switch_value = param->info_level;
458fe1c642dSBill Krier param->info = info;
459fe1c642dSBill Krier
460fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
461fe1c642dSBill Krier
462fe1c642dSBill Krier switch (data->kd_type) {
463fe1c642dSBill Krier case SMB_DOMAIN_BUILTIN:
464fe1c642dSBill Krier domain = "BUILTIN";
465fe1c642dSBill Krier user_cnt = 0;
466fe1c642dSBill Krier alias_cnt = smb_sam_grp_cnt(data->kd_type);
467fe1c642dSBill Krier break;
468fe1c642dSBill Krier
469fe1c642dSBill Krier case SMB_DOMAIN_LOCAL:
470fe1c642dSBill Krier rc = smb_getnetbiosname(hostname, sizeof (hostname));
471fe1c642dSBill Krier if (rc == 0) {
472fe1c642dSBill Krier domain = hostname;
473fe1c642dSBill Krier user_cnt = smb_sam_usr_cnt();
474fe1c642dSBill Krier alias_cnt = smb_sam_grp_cnt(data->kd_type);
475fe1c642dSBill Krier }
476fe1c642dSBill Krier break;
477fe1c642dSBill Krier
478fe1c642dSBill Krier default:
479fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo));
480fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
481fe1c642dSBill Krier return (NDR_DRC_OK);
482fe1c642dSBill Krier }
483fe1c642dSBill Krier
484fe1c642dSBill Krier if (rc != 0) {
485fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo));
486fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR);
487fe1c642dSBill Krier return (NDR_DRC_OK);
488fe1c642dSBill Krier }
489fe1c642dSBill Krier
490fe1c642dSBill Krier switch (param->info_level) {
491fe1c642dSBill Krier case SAMR_QUERY_DOMAIN_INFO_6:
492fe1c642dSBill Krier info->ru.info6.unknown1 = 0x00000000;
493fe1c642dSBill Krier info->ru.info6.unknown2 = 0x00147FB0;
494fe1c642dSBill Krier info->ru.info6.unknown3 = 0x00000000;
495fe1c642dSBill Krier info->ru.info6.unknown4 = 0x00000000;
496fe1c642dSBill Krier info->ru.info6.unknown5 = 0x00000000;
497fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
498fe1c642dSBill Krier break;
499fe1c642dSBill Krier
500fe1c642dSBill Krier case SAMR_QUERY_DOMAIN_INFO_7:
501fe1c642dSBill Krier info->ru.info7.unknown1 = 0x00000003;
502fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
503fe1c642dSBill Krier break;
504fe1c642dSBill Krier
505fe1c642dSBill Krier case SAMR_QUERY_DOMAIN_INFO_2:
506fe1c642dSBill Krier info->ru.info2.unknown1 = 0x00000000;
507fe1c642dSBill Krier info->ru.info2.unknown2 = 0x80000000;
508fe1c642dSBill Krier
509fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "",
510fe1c642dSBill Krier (ndr_mstring_t *)&(info->ru.info2.s1));
511fe1c642dSBill Krier (void) NDR_MSTRING(mxa, domain,
512fe1c642dSBill Krier (ndr_mstring_t *)&(info->ru.info2.domain));
513fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "",
514fe1c642dSBill Krier (ndr_mstring_t *)&(info->ru.info2.s2));
515fe1c642dSBill Krier
516fe1c642dSBill Krier info->ru.info2.sequence_num = 0x0000002B;
517fe1c642dSBill Krier info->ru.info2.unknown3 = 0x00000000;
518fe1c642dSBill Krier info->ru.info2.unknown4 = 0x00000001;
519fe1c642dSBill Krier info->ru.info2.unknown5 = 0x00000003;
520fe1c642dSBill Krier info->ru.info2.unknown6 = 0x00000001;
521fe1c642dSBill Krier info->ru.info2.num_users = user_cnt;
522fe1c642dSBill Krier info->ru.info2.num_groups = 0;
523fe1c642dSBill Krier info->ru.info2.num_aliases = alias_cnt;
524fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
525fe1c642dSBill Krier break;
526fe1c642dSBill Krier
527fe1c642dSBill Krier default:
528fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDomainInfo));
529fe1c642dSBill Krier return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
530fe1c642dSBill Krier };
531fe1c642dSBill Krier
532fe1c642dSBill Krier return (NDR_DRC_OK);
533fe1c642dSBill Krier }
534fe1c642dSBill Krier
535fe1c642dSBill Krier /*
536f96bd5c8SAlan Wright * QueryInfoDomain2: Identical to QueryDomainInfo.
537f96bd5c8SAlan Wright */
538f96bd5c8SAlan Wright static int
samr_s_QueryInfoDomain2(void * arg,ndr_xa_t * mxa)539f96bd5c8SAlan Wright samr_s_QueryInfoDomain2(void *arg, ndr_xa_t *mxa)
540f96bd5c8SAlan Wright {
541f96bd5c8SAlan Wright return (samr_s_QueryDomainInfo(arg, mxa));
542f96bd5c8SAlan Wright }
543f96bd5c8SAlan Wright
544f96bd5c8SAlan Wright /*
545fe1c642dSBill Krier * Looks up the given name in the specified domain which could
546fe1c642dSBill Krier * be either the built-in or local domain.
547fe1c642dSBill Krier *
548fe1c642dSBill Krier * CAVEAT: this function should be able to handle a list of
549fe1c642dSBill Krier * names but currently it can only handle one name at a time.
550fe1c642dSBill Krier */
551fe1c642dSBill Krier static int
samr_s_LookupNames(void * arg,ndr_xa_t * mxa)552fe1c642dSBill Krier samr_s_LookupNames(void *arg, ndr_xa_t *mxa)
553fe1c642dSBill Krier {
554fe1c642dSBill Krier struct samr_LookupNames *param = arg;
555fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
556fe1c642dSBill Krier ndr_handle_t *hd;
557fe1c642dSBill Krier samr_keydata_t *data;
558fe1c642dSBill Krier smb_account_t account;
559fe1c642dSBill Krier smb_wka_t *wka;
560fe1c642dSBill Krier uint32_t status = NT_STATUS_SUCCESS;
561fe1c642dSBill Krier
562fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL)
563fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
564fe1c642dSBill Krier
565fe1c642dSBill Krier if (param->n_entry != 1)
566fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
567fe1c642dSBill Krier
568fe1c642dSBill Krier if (param->name.str == NULL) {
569fe1c642dSBill Krier /*
570fe1c642dSBill Krier * Windows NT returns NT_STATUS_NONE_MAPPED.
571fe1c642dSBill Krier * Windows 2000 returns STATUS_INVALID_ACCOUNT_NAME.
572fe1c642dSBill Krier */
573fe1c642dSBill Krier status = NT_STATUS_NONE_MAPPED;
574fe1c642dSBill Krier }
575fe1c642dSBill Krier
576fe1c642dSBill Krier if (status != NT_STATUS_SUCCESS) {
577fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupNames));
578fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
579fe1c642dSBill Krier return (NDR_DRC_OK);
580fe1c642dSBill Krier }
581fe1c642dSBill Krier
582fe1c642dSBill Krier param->rids.rid = NDR_NEW(mxa, DWORD);
583fe1c642dSBill Krier param->rid_types.rid_type = NDR_NEW(mxa, DWORD);
584fe1c642dSBill Krier
585fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
586fe1c642dSBill Krier
587fe1c642dSBill Krier switch (data->kd_type) {
588fe1c642dSBill Krier case SMB_DOMAIN_BUILTIN:
589f96bd5c8SAlan Wright wka = smb_wka_lookup_builtin((char *)param->name.str);
590fe1c642dSBill Krier if (wka != NULL) {
591fe1c642dSBill Krier param->rids.n_entry = 1;
592fe1c642dSBill Krier (void) smb_sid_getrid(wka->wka_binsid,
593fe1c642dSBill Krier ¶m->rids.rid[0]);
594fe1c642dSBill Krier param->rid_types.n_entry = 1;
595fe1c642dSBill Krier param->rid_types.rid_type[0] = wka->wka_type;
596fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
597fe1c642dSBill Krier return (NDR_DRC_OK);
598fe1c642dSBill Krier }
599fe1c642dSBill Krier break;
600fe1c642dSBill Krier
601fe1c642dSBill Krier case SMB_DOMAIN_LOCAL:
602fe1c642dSBill Krier status = smb_sam_lookup_name(NULL, (char *)param->name.str,
603fe1c642dSBill Krier SidTypeUnknown, &account);
604fe1c642dSBill Krier if (status == NT_STATUS_SUCCESS) {
605fe1c642dSBill Krier param->rids.n_entry = 1;
606fe1c642dSBill Krier param->rids.rid[0] = account.a_rid;
607fe1c642dSBill Krier param->rid_types.n_entry = 1;
608fe1c642dSBill Krier param->rid_types.rid_type[0] = account.a_type;
609fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
610fe1c642dSBill Krier smb_account_free(&account);
611fe1c642dSBill Krier return (NDR_DRC_OK);
612fe1c642dSBill Krier }
613fe1c642dSBill Krier break;
614fe1c642dSBill Krier
615fe1c642dSBill Krier default:
616fe1c642dSBill Krier bzero(param, sizeof (struct samr_LookupNames));
617fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
618fe1c642dSBill Krier return (NDR_DRC_OK);
619fe1c642dSBill Krier }
620fe1c642dSBill Krier
621fe1c642dSBill Krier param->rids.n_entry = 0;
622fe1c642dSBill Krier param->rid_types.n_entry = 0;
623fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NONE_MAPPED);
624fe1c642dSBill Krier return (NDR_DRC_OK);
625fe1c642dSBill Krier }
626fe1c642dSBill Krier
627fe1c642dSBill Krier /*
628fe1c642dSBill Krier * samr_s_OpenUser
629fe1c642dSBill Krier *
630fe1c642dSBill Krier * This is a request to open a user within a specified domain in the
631fe1c642dSBill Krier * local SAM database. The caller must supply a valid domain handle,
632fe1c642dSBill Krier * obtained via a successful domain open request. The user is
633fe1c642dSBill Krier * specified by the rid in the request.
634fe1c642dSBill Krier */
635fe1c642dSBill Krier static int
samr_s_OpenUser(void * arg,ndr_xa_t * mxa)636fe1c642dSBill Krier samr_s_OpenUser(void *arg, ndr_xa_t *mxa)
637fe1c642dSBill Krier {
638fe1c642dSBill Krier struct samr_OpenUser *param = arg;
639fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
640fe1c642dSBill Krier ndr_handle_t *hd;
641fe1c642dSBill Krier samr_keydata_t *data;
642fe1c642dSBill Krier
643fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
644fe1c642dSBill Krier bzero(¶m->user_handle, sizeof (samr_handle_t));
645fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
646fe1c642dSBill Krier return (NDR_DRC_OK);
647fe1c642dSBill Krier }
648fe1c642dSBill Krier
649fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
650fe1c642dSBill Krier
651fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_USER, data->kd_type, param->rid);
652fe1c642dSBill Krier if (id == NULL) {
653fe1c642dSBill Krier bzero(¶m->user_handle, sizeof (samr_handle_t));
654fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
655fe1c642dSBill Krier } else {
656fe1c642dSBill Krier bcopy(id, ¶m->user_handle, sizeof (samr_handle_t));
657fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
658fe1c642dSBill Krier }
659fe1c642dSBill Krier
660fe1c642dSBill Krier return (NDR_DRC_OK);
661fe1c642dSBill Krier }
662fe1c642dSBill Krier
663fe1c642dSBill Krier /*
664fe1c642dSBill Krier * samr_s_DeleteUser
665fe1c642dSBill Krier *
666fe1c642dSBill Krier * Request to delete a user within a specified domain in the local
667fe1c642dSBill Krier * SAM database. The caller should supply a valid user handle.
668fe1c642dSBill Krier */
669fe1c642dSBill Krier /*ARGSUSED*/
670fe1c642dSBill Krier static int
samr_s_DeleteUser(void * arg,ndr_xa_t * mxa)671fe1c642dSBill Krier samr_s_DeleteUser(void *arg, ndr_xa_t *mxa)
672fe1c642dSBill Krier {
673fe1c642dSBill Krier struct samr_DeleteUser *param = arg;
674fe1c642dSBill Krier
675fe1c642dSBill Krier bzero(param, sizeof (struct samr_DeleteUser));
676fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
677fe1c642dSBill Krier return (NDR_DRC_OK);
678fe1c642dSBill Krier }
679fe1c642dSBill Krier
680fe1c642dSBill Krier /*
681fe1c642dSBill Krier * samr_s_QueryUserInfo
682fe1c642dSBill Krier *
683fe1c642dSBill Krier * Returns:
684fe1c642dSBill Krier * NT_STATUS_SUCCESS
685fe1c642dSBill Krier * NT_STATUS_ACCESS_DENIED
686fe1c642dSBill Krier * NT_STATUS_INVALID_INFO_CLASS
687fe1c642dSBill Krier */
688fe1c642dSBill Krier /*ARGSUSED*/
689fe1c642dSBill Krier static int
samr_s_QueryUserInfo(void * arg,ndr_xa_t * mxa)690fe1c642dSBill Krier samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa)
691fe1c642dSBill Krier {
692fe1c642dSBill Krier static uint16_t owf_buf[8];
693fe1c642dSBill Krier static uint8_t hour_buf[SAMR_SET_USER_HOURS_SZ];
694fe1c642dSBill Krier struct samr_QueryUserInfo *param = arg;
695fe1c642dSBill Krier struct samr_QueryUserInfo21 *all_info;
696fe1c642dSBill Krier ndr_hdid_t *id;
697fe1c642dSBill Krier ndr_handle_t *hd;
698fe1c642dSBill Krier samr_keydata_t *data;
699fe1c642dSBill Krier smb_domain_t di;
700fe1c642dSBill Krier smb_account_t account;
701fe1c642dSBill Krier smb_sid_t *sid;
702fe1c642dSBill Krier uint32_t status;
703fe1c642dSBill Krier
704fe1c642dSBill Krier id = (ndr_hdid_t *)¶m->user_handle;
705fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) {
706fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
707fe1c642dSBill Krier goto QueryUserInfoError;
708fe1c642dSBill Krier }
709fe1c642dSBill Krier
710fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
711fe1c642dSBill Krier
712fe1c642dSBill Krier if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) {
713fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
714fe1c642dSBill Krier goto QueryUserInfoError;
715fe1c642dSBill Krier }
716fe1c642dSBill Krier
717fe1c642dSBill Krier if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) {
718fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
719fe1c642dSBill Krier goto QueryUserInfoError;
720fe1c642dSBill Krier }
721fe1c642dSBill Krier
722fe1c642dSBill Krier if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) {
723fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
724fe1c642dSBill Krier goto QueryUserInfoError;
725fe1c642dSBill Krier }
726fe1c642dSBill Krier
727fe1c642dSBill Krier if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) {
728fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
729fe1c642dSBill Krier goto QueryUserInfoError;
730fe1c642dSBill Krier }
731fe1c642dSBill Krier
732fe1c642dSBill Krier all_info = ¶m->ru.info21;
733fe1c642dSBill Krier bzero(all_info, sizeof (struct samr_QueryUserInfo21));
734fe1c642dSBill Krier
735fe1c642dSBill Krier all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID;
736fe1c642dSBill Krier
737fe1c642dSBill Krier (void) NDR_MSTRING(mxa, account.a_name,
738fe1c642dSBill Krier (ndr_mstring_t *)&all_info->UserName);
739fe1c642dSBill Krier all_info->UserId = data->kd_rid;
740fe1c642dSBill Krier
741fe1c642dSBill Krier all_info->LmOwfPassword.length = 16;
742fe1c642dSBill Krier all_info->LmOwfPassword.maxlen = 16;
743fe1c642dSBill Krier all_info->LmOwfPassword.buf = owf_buf;
744fe1c642dSBill Krier all_info->NtOwfPassword.length = 16;
745fe1c642dSBill Krier all_info->NtOwfPassword.maxlen = 16;
746fe1c642dSBill Krier all_info->NtOwfPassword.buf = owf_buf;
747fe1c642dSBill Krier all_info->LogonHours.units_per_week = SAMR_HOURS_PER_WEEK;
748fe1c642dSBill Krier all_info->LogonHours.hours = hour_buf;
749fe1c642dSBill Krier
750fe1c642dSBill Krier param->address = 1;
751fe1c642dSBill Krier param->switch_index = SAMR_QUERY_USER_ALL_INFO;
752fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
7539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_account_free(&account);
7549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_sid_free(sid);
755fe1c642dSBill Krier return (NDR_DRC_OK);
756fe1c642dSBill Krier
757fe1c642dSBill Krier QueryUserInfoError:
7589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_sid_free(sid);
759fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryUserInfo));
760fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
761fe1c642dSBill Krier return (NDR_DRC_OK);
762fe1c642dSBill Krier }
763fe1c642dSBill Krier
764fe1c642dSBill Krier /*
765fe1c642dSBill Krier * samr_s_QueryUserGroups
766fe1c642dSBill Krier *
767fe1c642dSBill Krier * Request the list of groups of which a user is a member.
768fe1c642dSBill Krier * The user is identified from the handle, which contains an
769fe1c642dSBill Krier * rid in the discriminator field. Note that this is a local user.
770fe1c642dSBill Krier */
771fe1c642dSBill Krier static int
samr_s_QueryUserGroups(void * arg,ndr_xa_t * mxa)772fe1c642dSBill Krier samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa)
773fe1c642dSBill Krier {
774fe1c642dSBill Krier struct samr_QueryUserGroups *param = arg;
775fe1c642dSBill Krier struct samr_UserGroupInfo *info;
776fe1c642dSBill Krier struct samr_UserGroups *group;
777fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->user_handle;
778fe1c642dSBill Krier ndr_handle_t *hd;
779fe1c642dSBill Krier samr_keydata_t *data;
780fe1c642dSBill Krier smb_sid_t *user_sid = NULL;
781fe1c642dSBill Krier smb_group_t grp;
782fe1c642dSBill Krier smb_giter_t gi;
783fe1c642dSBill Krier smb_domain_t di;
784fe1c642dSBill Krier uint32_t status;
785fe1c642dSBill Krier int size;
786fe1c642dSBill Krier int ngrp_max;
787fe1c642dSBill Krier
788fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) {
789fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
790fe1c642dSBill Krier goto query_error;
791fe1c642dSBill Krier }
792fe1c642dSBill Krier
793fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
794fe1c642dSBill Krier switch (data->kd_type) {
795fe1c642dSBill Krier case SMB_DOMAIN_BUILTIN:
796fe1c642dSBill Krier case SMB_DOMAIN_LOCAL:
797fe1c642dSBill Krier if (!smb_domain_lookup_type(data->kd_type, &di)) {
798fe1c642dSBill Krier status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
799fe1c642dSBill Krier goto query_error;
800fe1c642dSBill Krier }
801fe1c642dSBill Krier break;
802fe1c642dSBill Krier default:
803fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
804fe1c642dSBill Krier goto query_error;
805fe1c642dSBill Krier }
806fe1c642dSBill Krier
807fe1c642dSBill Krier user_sid = smb_sid_splice(di.di_binsid, data->kd_rid);
808fe1c642dSBill Krier if (user_sid == NULL) {
809fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY;
810fe1c642dSBill Krier goto query_error;
811fe1c642dSBill Krier }
812fe1c642dSBill Krier
813fe1c642dSBill Krier info = NDR_NEW(mxa, struct samr_UserGroupInfo);
814fe1c642dSBill Krier if (info == NULL) {
815fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY;
816fe1c642dSBill Krier goto query_error;
817fe1c642dSBill Krier }
818fe1c642dSBill Krier bzero(info, sizeof (struct samr_UserGroupInfo));
819fe1c642dSBill Krier
820fe1c642dSBill Krier size = 32 * 1024;
821fe1c642dSBill Krier info->groups = NDR_MALLOC(mxa, size);
822fe1c642dSBill Krier if (info->groups == NULL) {
823fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY;
824fe1c642dSBill Krier goto query_error;
825fe1c642dSBill Krier }
826fe1c642dSBill Krier ngrp_max = size / sizeof (struct samr_UserGroups);
827fe1c642dSBill Krier
828fe1c642dSBill Krier if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
829fe1c642dSBill Krier status = NT_STATUS_INTERNAL_ERROR;
830fe1c642dSBill Krier goto query_error;
831fe1c642dSBill Krier }
832fe1c642dSBill Krier
833fe1c642dSBill Krier info->n_entry = 0;
834fe1c642dSBill Krier group = info->groups;
835fe1c642dSBill Krier while ((info->n_entry < ngrp_max) &&
836fe1c642dSBill Krier (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS)) {
837fe1c642dSBill Krier if (smb_lgrp_is_member(&grp, user_sid)) {
838fe1c642dSBill Krier group->rid = grp.sg_rid;
839fe1c642dSBill Krier group->attr = grp.sg_attr;
840fe1c642dSBill Krier group++;
841fe1c642dSBill Krier info->n_entry++;
842fe1c642dSBill Krier }
843fe1c642dSBill Krier smb_lgrp_free(&grp);
844fe1c642dSBill Krier }
845fe1c642dSBill Krier smb_lgrp_iterclose(&gi);
846fe1c642dSBill Krier
847fe1c642dSBill Krier free(user_sid);
848fe1c642dSBill Krier param->info = info;
849fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
850fe1c642dSBill Krier return (NDR_DRC_OK);
851fe1c642dSBill Krier
852fe1c642dSBill Krier query_error:
853fe1c642dSBill Krier free(user_sid);
854fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryUserGroups));
855fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
856fe1c642dSBill Krier return (NDR_DRC_OK);
857fe1c642dSBill Krier }
858fe1c642dSBill Krier
859fe1c642dSBill Krier /*
860fe1c642dSBill Krier * samr_s_OpenGroup
861fe1c642dSBill Krier *
862fe1c642dSBill Krier * This is a request to open a group within the specified domain in the
863fe1c642dSBill Krier * local SAM database. The caller must supply a valid domain handle,
864fe1c642dSBill Krier * obtained via a successful domain open request. The group is
865fe1c642dSBill Krier * specified by the rid in the request. If this is a local RID it
866fe1c642dSBill Krier * should already be encoded with type information.
867fe1c642dSBill Krier *
868fe1c642dSBill Krier * We return a handle to be used to access information about this group.
869fe1c642dSBill Krier */
870fe1c642dSBill Krier static int
samr_s_OpenGroup(void * arg,ndr_xa_t * mxa)871fe1c642dSBill Krier samr_s_OpenGroup(void *arg, ndr_xa_t *mxa)
872fe1c642dSBill Krier {
873fe1c642dSBill Krier struct samr_OpenGroup *param = arg;
874fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
875fe1c642dSBill Krier ndr_handle_t *hd;
876fe1c642dSBill Krier samr_keydata_t *data;
877fe1c642dSBill Krier
878fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
879fe1c642dSBill Krier bzero(¶m->group_handle, sizeof (samr_handle_t));
880fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
881fe1c642dSBill Krier return (NDR_DRC_OK);
882fe1c642dSBill Krier }
883fe1c642dSBill Krier
884fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
885fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_GROUP, data->kd_type, param->rid);
886fe1c642dSBill Krier
887fe1c642dSBill Krier if (id) {
888fe1c642dSBill Krier bcopy(id, ¶m->group_handle, sizeof (samr_handle_t));
889fe1c642dSBill Krier param->status = 0;
890fe1c642dSBill Krier } else {
891fe1c642dSBill Krier bzero(¶m->group_handle, sizeof (samr_handle_t));
892fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
893fe1c642dSBill Krier }
894fe1c642dSBill Krier
895fe1c642dSBill Krier return (NDR_DRC_OK);
896fe1c642dSBill Krier }
897fe1c642dSBill Krier
898fe1c642dSBill Krier /*
899c5866007SKeyur Desai * samr_s_AddAliasMember
900c5866007SKeyur Desai *
901c5866007SKeyur Desai * Add a member to a local SAM group.
902c5866007SKeyur Desai * The caller must supply a valid group handle.
903c5866007SKeyur Desai * The member is specified by the sid in the request.
904c5866007SKeyur Desai */
905c5866007SKeyur Desai static int
samr_s_AddAliasMember(void * arg,ndr_xa_t * mxa)906c5866007SKeyur Desai samr_s_AddAliasMember(void *arg, ndr_xa_t *mxa)
907c5866007SKeyur Desai {
908c5866007SKeyur Desai struct samr_AddAliasMember *param = arg;
909c5866007SKeyur Desai ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
910c5866007SKeyur Desai ndr_handle_t *hd;
911c5866007SKeyur Desai samr_keydata_t *data;
912c5866007SKeyur Desai smb_group_t grp;
913c5866007SKeyur Desai uint32_t rc;
914c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS;
915c5866007SKeyur Desai
916c5866007SKeyur Desai if (param->sid == NULL) {
917c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember));
918c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
919c5866007SKeyur Desai return (NDR_DRC_OK);
920c5866007SKeyur Desai }
921c5866007SKeyur Desai
922c5866007SKeyur Desai if (!ndr_is_admin(mxa)) {
923c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember));
924c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
925c5866007SKeyur Desai return (NDR_DRC_OK);
926c5866007SKeyur Desai }
927c5866007SKeyur Desai
928c5866007SKeyur Desai
929c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
930c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember));
931c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
932c5866007SKeyur Desai return (NDR_DRC_OK);
933c5866007SKeyur Desai }
934c5866007SKeyur Desai
935c5866007SKeyur Desai data = (samr_keydata_t *)hd->nh_data;
936c5866007SKeyur Desai rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp);
937c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
938c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember));
939c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
940c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
941c5866007SKeyur Desai return (NDR_DRC_OK);
942c5866007SKeyur Desai }
943c5866007SKeyur Desai
944c5866007SKeyur Desai rc = smb_lgrp_add_member(grp.sg_name,
945c5866007SKeyur Desai (smb_sid_t *)param->sid, SidTypeUser);
946c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
947c5866007SKeyur Desai bzero(param, sizeof (struct samr_AddAliasMember));
948c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
949c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
950c5866007SKeyur Desai }
951c5866007SKeyur Desai smb_lgrp_free(&grp);
952c5866007SKeyur Desai
953c5866007SKeyur Desai param->status = status;
954c5866007SKeyur Desai return (NDR_DRC_OK);
955c5866007SKeyur Desai }
956c5866007SKeyur Desai
957c5866007SKeyur Desai /*
958c5866007SKeyur Desai * samr_s_DeleteAliasMember
959c5866007SKeyur Desai *
960c5866007SKeyur Desai * Delete a member from a local SAM group.
961c5866007SKeyur Desai * The caller must supply a valid group handle.
962c5866007SKeyur Desai * The member is specified by the sid in the request.
963c5866007SKeyur Desai */
964c5866007SKeyur Desai static int
samr_s_DeleteAliasMember(void * arg,ndr_xa_t * mxa)965c5866007SKeyur Desai samr_s_DeleteAliasMember(void *arg, ndr_xa_t *mxa)
966c5866007SKeyur Desai {
967c5866007SKeyur Desai struct samr_DeleteAliasMember *param = arg;
968c5866007SKeyur Desai ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
969c5866007SKeyur Desai ndr_handle_t *hd;
970c5866007SKeyur Desai samr_keydata_t *data;
971c5866007SKeyur Desai smb_group_t grp;
972c5866007SKeyur Desai uint32_t rc;
973c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS;
974c5866007SKeyur Desai
975c5866007SKeyur Desai if (param->sid == NULL) {
976c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember));
977c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
978c5866007SKeyur Desai return (NDR_DRC_OK);
979c5866007SKeyur Desai }
980c5866007SKeyur Desai
981c5866007SKeyur Desai if (!ndr_is_admin(mxa)) {
982c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember));
983c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
984c5866007SKeyur Desai return (NDR_DRC_OK);
985c5866007SKeyur Desai }
986c5866007SKeyur Desai
987c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
988c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember));
989c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
990c5866007SKeyur Desai return (NDR_DRC_OK);
991c5866007SKeyur Desai }
992c5866007SKeyur Desai
993c5866007SKeyur Desai data = (samr_keydata_t *)hd->nh_data;
994c5866007SKeyur Desai rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp);
995c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
996c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember));
997c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
998c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
999c5866007SKeyur Desai return (NDR_DRC_OK);
1000c5866007SKeyur Desai }
1001c5866007SKeyur Desai
1002c5866007SKeyur Desai rc = smb_lgrp_del_member(grp.sg_name,
1003c5866007SKeyur Desai (smb_sid_t *)param->sid, SidTypeUser);
1004c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1005c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteAliasMember));
1006c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1007c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
1008c5866007SKeyur Desai }
1009c5866007SKeyur Desai smb_lgrp_free(&grp);
1010c5866007SKeyur Desai
1011c5866007SKeyur Desai param->status = status;
1012c5866007SKeyur Desai return (NDR_DRC_OK);
1013c5866007SKeyur Desai }
1014c5866007SKeyur Desai
1015c5866007SKeyur Desai /*
1016c5866007SKeyur Desai * samr_s_ListAliasMembers
1017c5866007SKeyur Desai *
1018c5866007SKeyur Desai * List members from a local SAM group.
1019c5866007SKeyur Desai * The caller must supply a valid group handle.
1020c5866007SKeyur Desai * A list of user SIDs in the specified group is returned to the caller.
1021c5866007SKeyur Desai */
1022c5866007SKeyur Desai static int
samr_s_ListAliasMembers(void * arg,ndr_xa_t * mxa)1023c5866007SKeyur Desai samr_s_ListAliasMembers(void *arg, ndr_xa_t *mxa)
1024c5866007SKeyur Desai {
1025c5866007SKeyur Desai struct samr_ListAliasMembers *param = arg;
1026c5866007SKeyur Desai ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1027c5866007SKeyur Desai ndr_handle_t *hd;
1028c5866007SKeyur Desai samr_keydata_t *data;
1029c5866007SKeyur Desai smb_group_t grp;
1030c5866007SKeyur Desai smb_gsid_t *members;
1031c5866007SKeyur Desai struct samr_SidInfo info;
1032c5866007SKeyur Desai struct samr_SidList *user;
1033c5866007SKeyur Desai uint32_t num = 0, size;
1034c5866007SKeyur Desai int i;
1035c5866007SKeyur Desai uint32_t rc;
1036c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS;
1037c5866007SKeyur Desai
1038c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
1039c5866007SKeyur Desai bzero(param, sizeof (struct samr_ListAliasMembers));
1040c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1041c5866007SKeyur Desai return (NDR_DRC_OK);
1042c5866007SKeyur Desai }
1043c5866007SKeyur Desai
1044c5866007SKeyur Desai bzero(&info, sizeof (struct samr_SidInfo));
1045c5866007SKeyur Desai data = (samr_keydata_t *)hd->nh_data;
1046c5866007SKeyur Desai rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp);
1047c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1048c5866007SKeyur Desai bzero(param, sizeof (struct samr_ListAliasMembers));
1049c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1050c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
1051c5866007SKeyur Desai return (NDR_DRC_OK);
1052c5866007SKeyur Desai }
1053c5866007SKeyur Desai
1054c5866007SKeyur Desai num = grp.sg_nmembers;
1055c5866007SKeyur Desai members = grp.sg_members;
1056c5866007SKeyur Desai size = num * sizeof (struct samr_SidList);
1057c5866007SKeyur Desai info.sidlist = NDR_MALLOC(mxa, size);
1058c5866007SKeyur Desai if (info.sidlist == NULL) {
1059c5866007SKeyur Desai bzero(param, sizeof (struct samr_ListAliasMembers));
1060c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1061c5866007SKeyur Desai smb_lgrp_free(&grp);
1062c5866007SKeyur Desai return (NDR_DRC_OK);
1063c5866007SKeyur Desai }
1064c5866007SKeyur Desai
1065c5866007SKeyur Desai info.n_entry = num;
1066c5866007SKeyur Desai user = info.sidlist;
1067c5866007SKeyur Desai for (i = 0; i < num; i++) {
1068c5866007SKeyur Desai user->sid = (struct samr_sid *)NDR_SIDDUP(mxa,
1069c5866007SKeyur Desai members[i].gs_sid);
1070c5866007SKeyur Desai if (user->sid == NULL) {
1071c5866007SKeyur Desai bzero(param, sizeof (struct samr_ListAliasMembers));
1072c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1073c5866007SKeyur Desai smb_lgrp_free(&grp);
1074c5866007SKeyur Desai return (NDR_DRC_OK);
1075c5866007SKeyur Desai }
1076c5866007SKeyur Desai user++;
1077c5866007SKeyur Desai }
1078c5866007SKeyur Desai smb_lgrp_free(&grp);
1079c5866007SKeyur Desai
1080c5866007SKeyur Desai param->info = info;
1081c5866007SKeyur Desai param->status = status;
1082c5866007SKeyur Desai return (NDR_DRC_OK);
1083c5866007SKeyur Desai }
1084c5866007SKeyur Desai
1085c5866007SKeyur Desai /*
1086cb174861Sjoyce mcintosh * samr_s_Connect2
1087fe1c642dSBill Krier *
1088fe1c642dSBill Krier * This is a request to connect to the local SAM database.
1089fe1c642dSBill Krier * We don't support any form of update request and our database doesn't
1090fe1c642dSBill Krier * contain any private information, so there is little point in doing
1091fe1c642dSBill Krier * any access access checking here.
1092fe1c642dSBill Krier *
1093fe1c642dSBill Krier * Return a handle for use with subsequent SAM requests.
1094fe1c642dSBill Krier */
1095fe1c642dSBill Krier static int
samr_s_Connect2(void * arg,ndr_xa_t * mxa)1096cb174861Sjoyce mcintosh samr_s_Connect2(void *arg, ndr_xa_t *mxa)
1097fe1c642dSBill Krier {
1098cb174861Sjoyce mcintosh struct samr_Connect2 *param = arg;
1099fe1c642dSBill Krier ndr_hdid_t *id;
1100fe1c642dSBill Krier
1101fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
1102fe1c642dSBill Krier if (id) {
1103fe1c642dSBill Krier bcopy(id, ¶m->handle, sizeof (samr_handle_t));
1104fe1c642dSBill Krier param->status = 0;
1105fe1c642dSBill Krier } else {
1106fe1c642dSBill Krier bzero(¶m->handle, sizeof (samr_handle_t));
1107fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1108fe1c642dSBill Krier }
1109fe1c642dSBill Krier
1110fe1c642dSBill Krier return (NDR_DRC_OK);
1111fe1c642dSBill Krier }
1112fe1c642dSBill Krier
1113fe1c642dSBill Krier /*
1114fe1c642dSBill Krier * samr_s_GetUserPwInfo
1115fe1c642dSBill Krier *
1116f96bd5c8SAlan Wright * Request for a user's password policy information.
1117fe1c642dSBill Krier */
1118fe1c642dSBill Krier /*ARGSUSED*/
1119fe1c642dSBill Krier static int
samr_s_GetUserPwInfo(void * arg,ndr_xa_t * mxa)1120fe1c642dSBill Krier samr_s_GetUserPwInfo(void *arg, ndr_xa_t *mxa)
1121fe1c642dSBill Krier {
1122f96bd5c8SAlan Wright static samr_password_info_t pwinfo;
1123fe1c642dSBill Krier struct samr_GetUserPwInfo *param = arg;
1124fe1c642dSBill Krier
1125f96bd5c8SAlan Wright param->pwinfo = &pwinfo;
1126f96bd5c8SAlan Wright param->status = NT_STATUS_SUCCESS;
1127fe1c642dSBill Krier return (NDR_DRC_OK);
1128fe1c642dSBill Krier }
1129fe1c642dSBill Krier
1130fe1c642dSBill Krier /*
1131fe1c642dSBill Krier * samr_s_CreateUser
1132fe1c642dSBill Krier */
1133fe1c642dSBill Krier /*ARGSUSED*/
1134fe1c642dSBill Krier static int
samr_s_CreateUser(void * arg,ndr_xa_t * mxa)1135fe1c642dSBill Krier samr_s_CreateUser(void *arg, ndr_xa_t *mxa)
1136fe1c642dSBill Krier {
1137fe1c642dSBill Krier struct samr_CreateUser *param = arg;
1138fe1c642dSBill Krier
1139fe1c642dSBill Krier bzero(¶m->user_handle, sizeof (samr_handle_t));
1140fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
1141fe1c642dSBill Krier return (NDR_DRC_OK);
1142fe1c642dSBill Krier }
1143fe1c642dSBill Krier
1144fe1c642dSBill Krier /*
1145*1ed6b69aSGordon Ross * samr_s_ChangePasswordUser2
1146fe1c642dSBill Krier */
1147fe1c642dSBill Krier /*ARGSUSED*/
1148fe1c642dSBill Krier static int
samr_s_ChangePasswordUser2(void * arg,ndr_xa_t * mxa)1149*1ed6b69aSGordon Ross samr_s_ChangePasswordUser2(void *arg, ndr_xa_t *mxa)
1150fe1c642dSBill Krier {
1151*1ed6b69aSGordon Ross struct samr_ChangePasswordUser2 *param = arg;
1152fe1c642dSBill Krier
1153*1ed6b69aSGordon Ross bzero(param, sizeof (*param));
1154fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
1155fe1c642dSBill Krier return (NDR_DRC_OK);
1156fe1c642dSBill Krier }
1157fe1c642dSBill Krier
1158fe1c642dSBill Krier /*
1159fe1c642dSBill Krier * samr_s_GetDomainPwInfo
1160f96bd5c8SAlan Wright *
1161f96bd5c8SAlan Wright * Request for the domain password policy information.
1162fe1c642dSBill Krier */
1163fe1c642dSBill Krier /*ARGSUSED*/
1164fe1c642dSBill Krier static int
samr_s_GetDomainPwInfo(void * arg,ndr_xa_t * mxa)1165fe1c642dSBill Krier samr_s_GetDomainPwInfo(void *arg, ndr_xa_t *mxa)
1166fe1c642dSBill Krier {
1167f96bd5c8SAlan Wright static samr_password_info_t pwinfo;
1168fe1c642dSBill Krier struct samr_GetDomainPwInfo *param = arg;
1169fe1c642dSBill Krier
1170f96bd5c8SAlan Wright param->pwinfo = &pwinfo;
1171f96bd5c8SAlan Wright param->status = NT_STATUS_SUCCESS;
1172fe1c642dSBill Krier return (NDR_DRC_OK);
1173fe1c642dSBill Krier }
1174fe1c642dSBill Krier
1175fe1c642dSBill Krier /*
1176fe1c642dSBill Krier * samr_s_SetUserInfo
1177fe1c642dSBill Krier */
1178fe1c642dSBill Krier /*ARGSUSED*/
1179fe1c642dSBill Krier static int
samr_s_SetUserInfo(void * arg,ndr_xa_t * mxa)1180fe1c642dSBill Krier samr_s_SetUserInfo(void *arg, ndr_xa_t *mxa)
1181fe1c642dSBill Krier {
1182fe1c642dSBill Krier struct samr_SetUserInfo *param = arg;
1183fe1c642dSBill Krier
1184fe1c642dSBill Krier bzero(param, sizeof (struct samr_SetUserInfo));
1185fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
1186fe1c642dSBill Krier return (NDR_DRC_OK);
1187fe1c642dSBill Krier }
1188fe1c642dSBill Krier
1189fe1c642dSBill Krier /*
1190fe1c642dSBill Krier * samr_s_QueryDispInfo
1191fe1c642dSBill Krier *
1192fe1c642dSBill Krier * This function currently return local users' information only.
1193fe1c642dSBill Krier * This RPC is called repeatedly until all the users info are
1194fe1c642dSBill Krier * retrieved.
1195fe1c642dSBill Krier *
1196fe1c642dSBill Krier * The total count and the returned count are returned as total size
1197fe1c642dSBill Krier * and returned size. The client doesn't seem to care.
1198fe1c642dSBill Krier */
1199fe1c642dSBill Krier static int
samr_s_QueryDispInfo(void * arg,ndr_xa_t * mxa)1200fe1c642dSBill Krier samr_s_QueryDispInfo(void *arg, ndr_xa_t *mxa)
1201fe1c642dSBill Krier {
1202fe1c642dSBill Krier struct samr_QueryDispInfo *param = arg;
1203fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
1204fe1c642dSBill Krier ndr_handle_t *hd;
1205fe1c642dSBill Krier samr_keydata_t *data;
1206fe1c642dSBill Krier DWORD status = NT_STATUS_SUCCESS;
1207fe1c642dSBill Krier struct user_acct_info *user;
1208fe1c642dSBill Krier smb_pwditer_t pwi;
1209fe1c642dSBill Krier smb_luser_t *uinfo;
1210fe1c642dSBill Krier int num_users;
1211fe1c642dSBill Krier int start_idx;
1212fe1c642dSBill Krier int max_retcnt, retcnt;
1213fe1c642dSBill Krier int skip;
1214fe1c642dSBill Krier
1215fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
1216fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
1217fe1c642dSBill Krier goto error;
1218fe1c642dSBill Krier }
1219fe1c642dSBill Krier
1220fe1c642dSBill Krier if (!SAMR_VALID_DISPLEVEL(param->level)) {
1221fe1c642dSBill Krier status = NT_STATUS_INVALID_INFO_CLASS;
1222fe1c642dSBill Krier goto error;
1223fe1c642dSBill Krier }
1224fe1c642dSBill Krier
1225fe1c642dSBill Krier if (!SAMR_SUPPORTED_DISPLEVEL(param->level)) {
1226fe1c642dSBill Krier status = NT_STATUS_NOT_IMPLEMENTED;
1227fe1c642dSBill Krier goto error;
1228fe1c642dSBill Krier }
1229fe1c642dSBill Krier
1230fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
1231fe1c642dSBill Krier
1232fe1c642dSBill Krier switch (data->kd_type) {
1233fe1c642dSBill Krier case SMB_DOMAIN_BUILTIN:
1234fe1c642dSBill Krier goto no_info;
1235fe1c642dSBill Krier
1236fe1c642dSBill Krier case SMB_DOMAIN_LOCAL:
1237fe1c642dSBill Krier num_users = smb_sam_usr_cnt();
1238fe1c642dSBill Krier start_idx = param->start_idx;
1239fe1c642dSBill Krier if ((num_users == 0) || (start_idx >= num_users))
1240fe1c642dSBill Krier goto no_info;
1241fe1c642dSBill Krier
1242fe1c642dSBill Krier max_retcnt = num_users - start_idx;
1243fe1c642dSBill Krier if (max_retcnt > param->max_entries)
1244fe1c642dSBill Krier max_retcnt = param->max_entries;
1245fe1c642dSBill Krier param->users.acct = NDR_MALLOC(mxa,
1246fe1c642dSBill Krier max_retcnt * sizeof (struct user_acct_info));
1247fe1c642dSBill Krier user = param->users.acct;
1248fe1c642dSBill Krier if (user == NULL) {
1249fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY;
1250fe1c642dSBill Krier goto error;
1251fe1c642dSBill Krier }
1252fe1c642dSBill Krier bzero(user, max_retcnt * sizeof (struct user_acct_info));
1253fe1c642dSBill Krier
1254fe1c642dSBill Krier if (smb_pwd_iteropen(&pwi) != SMB_PWE_SUCCESS)
1255fe1c642dSBill Krier goto no_info;
1256fe1c642dSBill Krier
1257fe1c642dSBill Krier skip = retcnt = 0;
1258fe1c642dSBill Krier while ((uinfo = smb_pwd_iterate(&pwi)) != NULL) {
1259fe1c642dSBill Krier if (skip++ < start_idx)
1260fe1c642dSBill Krier continue;
1261fe1c642dSBill Krier
1262fe1c642dSBill Krier if (retcnt++ >= max_retcnt)
1263fe1c642dSBill Krier break;
1264fe1c642dSBill Krier
1265fe1c642dSBill Krier assert(uinfo->su_name != NULL);
1266fe1c642dSBill Krier
1267fe1c642dSBill Krier user->index = start_idx + retcnt;
1268fe1c642dSBill Krier user->rid = uinfo->su_rid;
1269fe1c642dSBill Krier user->ctrl = ACF_NORMUSER | ACF_PWDNOEXP;
1270fe1c642dSBill Krier if (uinfo->su_ctrl & SMB_PWF_DISABLE)
1271fe1c642dSBill Krier user->ctrl |= ACF_DISABLED;
1272fe1c642dSBill Krier if (NDR_MSTRING(mxa, uinfo->su_name,
1273fe1c642dSBill Krier (ndr_mstring_t *)&user->name) == -1) {
1274fe1c642dSBill Krier smb_pwd_iterclose(&pwi);
1275fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY;
1276fe1c642dSBill Krier goto error;
1277fe1c642dSBill Krier }
1278fe1c642dSBill Krier (void) NDR_MSTRING(mxa, uinfo->su_fullname,
1279fe1c642dSBill Krier (ndr_mstring_t *)&user->fullname);
1280fe1c642dSBill Krier (void) NDR_MSTRING(mxa, uinfo->su_desc,
1281fe1c642dSBill Krier (ndr_mstring_t *)&user->desc);
1282fe1c642dSBill Krier user++;
1283fe1c642dSBill Krier }
1284fe1c642dSBill Krier smb_pwd_iterclose(&pwi);
1285fe1c642dSBill Krier
1286fe1c642dSBill Krier if (retcnt >= max_retcnt) {
1287fe1c642dSBill Krier retcnt = max_retcnt;
1288fe1c642dSBill Krier param->status = status;
1289fe1c642dSBill Krier } else {
1290148c5f43SAlan Wright param->status = NT_STATUS_MORE_ENTRIES;
1291fe1c642dSBill Krier }
1292fe1c642dSBill Krier
1293fe1c642dSBill Krier param->users.total_size = num_users;
1294fe1c642dSBill Krier param->users.returned_size = retcnt;
1295fe1c642dSBill Krier param->users.switch_value = param->level;
1296fe1c642dSBill Krier param->users.count = retcnt;
1297fe1c642dSBill Krier
1298fe1c642dSBill Krier break;
1299fe1c642dSBill Krier
1300fe1c642dSBill Krier default:
1301fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
1302fe1c642dSBill Krier goto error;
1303fe1c642dSBill Krier }
1304fe1c642dSBill Krier
1305fe1c642dSBill Krier return (NDR_DRC_OK);
1306fe1c642dSBill Krier
1307fe1c642dSBill Krier no_info:
1308fe1c642dSBill Krier param->users.total_size = 0;
1309fe1c642dSBill Krier param->users.returned_size = 0;
1310fe1c642dSBill Krier param->users.switch_value = param->level;
1311fe1c642dSBill Krier param->users.count = 0;
1312fe1c642dSBill Krier param->users.acct = NULL;
1313fe1c642dSBill Krier param->status = status;
1314fe1c642dSBill Krier return (NDR_DRC_OK);
1315fe1c642dSBill Krier
1316fe1c642dSBill Krier error:
1317fe1c642dSBill Krier bzero(param, sizeof (struct samr_QueryDispInfo));
1318fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
1319fe1c642dSBill Krier return (NDR_DRC_OK);
1320fe1c642dSBill Krier }
1321fe1c642dSBill Krier
1322fe1c642dSBill Krier /*
1323fe1c642dSBill Krier * samr_s_EnumDomainGroups
1324fe1c642dSBill Krier *
1325fe1c642dSBill Krier *
1326fe1c642dSBill Krier * This function is supposed to return local group information.
1327fe1c642dSBill Krier * As we don't support local users, this function dosen't send
1328fe1c642dSBill Krier * back any information.
1329fe1c642dSBill Krier *
1330fe1c642dSBill Krier * Added template that returns information for a domain group as None.
1331fe1c642dSBill Krier * All information is hard-coded from packet captures.
1332fe1c642dSBill Krier */
1333fe1c642dSBill Krier static int
samr_s_EnumDomainGroups(void * arg,ndr_xa_t * mxa)1334fe1c642dSBill Krier samr_s_EnumDomainGroups(void *arg, ndr_xa_t *mxa)
1335fe1c642dSBill Krier {
1336fe1c642dSBill Krier struct samr_EnumDomainGroups *param = arg;
1337fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
1338fe1c642dSBill Krier DWORD status = NT_STATUS_SUCCESS;
1339fe1c642dSBill Krier
1340fe1c642dSBill Krier if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL)
1341fe1c642dSBill Krier status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1342fe1c642dSBill Krier
1343fe1c642dSBill Krier param->total_size = 0;
1344fe1c642dSBill Krier param->returned_size = 0;
1345fe1c642dSBill Krier param->switch_value = 3;
1346fe1c642dSBill Krier param->count = 0;
1347fe1c642dSBill Krier param->groups = 0;
1348fe1c642dSBill Krier param->status = status;
1349fe1c642dSBill Krier return (NDR_DRC_OK);
1350fe1c642dSBill Krier
1351fe1c642dSBill Krier #ifdef SAMR_SUPPORT_GROUPS
1352fe1c642dSBill Krier if ((desc->discrim != SAMR_LOCAL_DOMAIN) || (param->start_idx != 0)) {
1353fe1c642dSBill Krier param->total_size = 0;
1354fe1c642dSBill Krier param->returned_size = 0;
1355fe1c642dSBill Krier param->switch_value = 3;
1356fe1c642dSBill Krier param->count = 0;
1357fe1c642dSBill Krier param->groups = 0;
1358fe1c642dSBill Krier } else {
1359fe1c642dSBill Krier param->total_size = 64;
1360fe1c642dSBill Krier param->returned_size = 64;
1361fe1c642dSBill Krier param->switch_value = 3;
1362fe1c642dSBill Krier param->count = 1;
1363fe1c642dSBill Krier param->groups = (struct group_disp_info *)NDR_MALLOC(
1364fe1c642dSBill Krier mxa, sizeof (struct group_disp_info));
1365fe1c642dSBill Krier
1366fe1c642dSBill Krier param->groups->count = 1;
1367fe1c642dSBill Krier param->groups->acct[0].index = 1;
1368fe1c642dSBill Krier param->groups->acct[0].rid = 513;
1369fe1c642dSBill Krier param->groups->acct[0].ctrl = 0x7;
1370fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "None",
1371fe1c642dSBill Krier (ndr_mstring_t *)¶m->groups->acct[0].name);
1372fe1c642dSBill Krier
1373fe1c642dSBill Krier (void) NDR_MSTRING(mxa, "Ordinary users",
1374fe1c642dSBill Krier (ndr_mstring_t *)¶m->groups->acct[0].desc);
1375fe1c642dSBill Krier }
1376fe1c642dSBill Krier
1377fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
1378fe1c642dSBill Krier return (NDR_DRC_OK);
1379fe1c642dSBill Krier #endif
1380fe1c642dSBill Krier }
1381fe1c642dSBill Krier
1382fe1c642dSBill Krier /*
1383fe1c642dSBill Krier * samr_s_OpenAlias
1384fe1c642dSBill Krier *
1385fe1c642dSBill Krier * Lookup for requested alias, if it exists return a handle
1386fe1c642dSBill Krier * for that alias. The alias domain sid should match with
1387fe1c642dSBill Krier * the passed domain handle.
1388fe1c642dSBill Krier */
1389fe1c642dSBill Krier static int
samr_s_OpenAlias(void * arg,ndr_xa_t * mxa)1390fe1c642dSBill Krier samr_s_OpenAlias(void *arg, ndr_xa_t *mxa)
1391fe1c642dSBill Krier {
1392fe1c642dSBill Krier struct samr_OpenAlias *param = arg;
1393fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
1394fe1c642dSBill Krier ndr_handle_t *hd;
1395fe1c642dSBill Krier samr_keydata_t *data;
13969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_domain_type_t gd_type;
1397f96bd5c8SAlan Wright smb_sid_t *sid;
1398f96bd5c8SAlan Wright smb_wka_t *wka;
1399f96bd5c8SAlan Wright char sidstr[SMB_SID_STRSZ];
1400f96bd5c8SAlan Wright uint32_t rid;
1401f96bd5c8SAlan Wright uint32_t status;
1402fe1c642dSBill Krier int rc;
1403fe1c642dSBill Krier
1404fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
1405fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
1406fe1c642dSBill Krier goto open_alias_err;
1407fe1c642dSBill Krier }
1408fe1c642dSBill Krier
1409c5866007SKeyur Desai if ((param->access_mask & SAMR_ALIAS_ACCESS_ALL_ACCESS) == 0) {
1410fe1c642dSBill Krier status = NT_STATUS_ACCESS_DENIED;
1411fe1c642dSBill Krier goto open_alias_err;
1412fe1c642dSBill Krier }
1413fe1c642dSBill Krier
1414fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
14159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States gd_type = (smb_domain_type_t)data->kd_type;
1416f96bd5c8SAlan Wright rid = param->rid;
1417f96bd5c8SAlan Wright
1418f96bd5c8SAlan Wright switch (gd_type) {
14199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_DOMAIN_BUILTIN:
1420f96bd5c8SAlan Wright (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d",
1421f96bd5c8SAlan Wright NT_BUILTIN_DOMAIN_SIDSTR, rid);
1422f96bd5c8SAlan Wright if ((sid = smb_sid_fromstr(sidstr)) == NULL) {
1423f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1424f96bd5c8SAlan Wright goto open_alias_err;
1425f96bd5c8SAlan Wright }
1426f96bd5c8SAlan Wright
1427f96bd5c8SAlan Wright wka = smb_wka_lookup_sid(sid);
1428f96bd5c8SAlan Wright smb_sid_free(sid);
1429f96bd5c8SAlan Wright
1430f96bd5c8SAlan Wright if (wka == NULL) {
1431f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1432f96bd5c8SAlan Wright goto open_alias_err;
1433f96bd5c8SAlan Wright }
1434f96bd5c8SAlan Wright break;
1435f96bd5c8SAlan Wright
14369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_DOMAIN_LOCAL:
1437f96bd5c8SAlan Wright rc = smb_lgrp_getbyrid(rid, gd_type, NULL);
1438fe1c642dSBill Krier if (rc != SMB_LGRP_SUCCESS) {
1439fe1c642dSBill Krier status = NT_STATUS_NO_SUCH_ALIAS;
1440fe1c642dSBill Krier goto open_alias_err;
1441fe1c642dSBill Krier }
1442f96bd5c8SAlan Wright break;
1443f96bd5c8SAlan Wright
1444f96bd5c8SAlan Wright default:
1445f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1446f96bd5c8SAlan Wright goto open_alias_err;
1447f96bd5c8SAlan Wright }
1448fe1c642dSBill Krier
1449fe1c642dSBill Krier id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, data->kd_type, param->rid);
1450fe1c642dSBill Krier if (id) {
1451fe1c642dSBill Krier bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t));
1452fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
1453fe1c642dSBill Krier return (NDR_DRC_OK);
1454fe1c642dSBill Krier }
1455fe1c642dSBill Krier
1456fe1c642dSBill Krier status = NT_STATUS_NO_MEMORY;
1457fe1c642dSBill Krier
1458fe1c642dSBill Krier open_alias_err:
1459fe1c642dSBill Krier bzero(¶m->alias_handle, sizeof (samr_handle_t));
1460fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
1461fe1c642dSBill Krier return (NDR_DRC_OK);
1462fe1c642dSBill Krier }
1463fe1c642dSBill Krier
1464fe1c642dSBill Krier /*
1465fe1c642dSBill Krier * samr_s_CreateDomainAlias
1466fe1c642dSBill Krier *
1467c5866007SKeyur Desai * Create a local group in the security accounts manager (SAM) database.
1468c5866007SKeyur Desai * A local SAM group can only be added if a Solaris group already exists
1469c5866007SKeyur Desai * with the same name. On success, a valid group handle is returned.
1470c5866007SKeyur Desai *
1471c5866007SKeyur Desai * The caller must have administrator rights to execute this function.
1472fe1c642dSBill Krier */
1473fe1c642dSBill Krier static int
samr_s_CreateDomainAlias(void * arg,ndr_xa_t * mxa)1474fe1c642dSBill Krier samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa)
1475fe1c642dSBill Krier {
1476fe1c642dSBill Krier struct samr_CreateDomainAlias *param = arg;
1477fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1478c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS;
1479c5866007SKeyur Desai smb_group_t grp;
1480c5866007SKeyur Desai uint32_t rc;
1481c5866007SKeyur Desai char *gname;
1482fe1c642dSBill Krier
1483c5866007SKeyur Desai if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) != NULL) {
1484fe1c642dSBill Krier bzero(param, sizeof (struct samr_CreateDomainAlias));
1485fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1486fe1c642dSBill Krier return (NDR_DRC_OK);
1487fe1c642dSBill Krier }
1488fe1c642dSBill Krier
1489c5866007SKeyur Desai gname = (char *)param->alias_name.str;
1490c5866007SKeyur Desai if (gname == NULL) {
1491c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t));
1492c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
1493c5866007SKeyur Desai return (NDR_DRC_OK);
1494c5866007SKeyur Desai }
1495c5866007SKeyur Desai
1496c5866007SKeyur Desai if ((!ndr_is_admin(mxa)) ||
1497c5866007SKeyur Desai ((param->access_mask & SAMR_ALIAS_ACCESS_WRITE_ACCOUNT) == 0)) {
1498c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t));
1499fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
1500fe1c642dSBill Krier return (NDR_DRC_OK);
1501fe1c642dSBill Krier }
1502fe1c642dSBill Krier
1503c5866007SKeyur Desai rc = smb_lgrp_add(gname, "");
1504c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1505c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t));
1506c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1507fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
1508fe1c642dSBill Krier return (NDR_DRC_OK);
1509c5866007SKeyur Desai }
1510c5866007SKeyur Desai
1511c5866007SKeyur Desai rc = smb_lgrp_getbyname((char *)gname, &grp);
1512c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1513c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t));
1514c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1515c5866007SKeyur Desai param->status = NT_SC_ERROR(status);
1516c5866007SKeyur Desai return (NDR_DRC_OK);
1517c5866007SKeyur Desai }
1518c5866007SKeyur Desai
1519c5866007SKeyur Desai id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, SMB_DOMAIN_LOCAL, grp.sg_rid);
1520c5866007SKeyur Desai smb_lgrp_free(&grp);
1521c5866007SKeyur Desai if (id) {
1522c5866007SKeyur Desai bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t));
1523c5866007SKeyur Desai param->status = status;
1524c5866007SKeyur Desai } else {
1525c5866007SKeyur Desai bzero(¶m->alias_handle, sizeof (samr_handle_t));
1526c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1527c5866007SKeyur Desai }
1528c5866007SKeyur Desai
1529c5866007SKeyur Desai return (NDR_DRC_OK);
1530fe1c642dSBill Krier }
1531fe1c642dSBill Krier
1532fe1c642dSBill Krier /*
1533fe1c642dSBill Krier * samr_s_SetAliasInfo
1534fe1c642dSBill Krier *
1535fe1c642dSBill Krier * Similar to NetLocalGroupSetInfo.
1536fe1c642dSBill Krier */
1537fe1c642dSBill Krier static int
samr_s_SetAliasInfo(void * arg,ndr_xa_t * mxa)1538fe1c642dSBill Krier samr_s_SetAliasInfo(void *arg, ndr_xa_t *mxa)
1539fe1c642dSBill Krier {
1540fe1c642dSBill Krier struct samr_SetAliasInfo *param = arg;
1541fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1542fe1c642dSBill Krier DWORD status = NT_STATUS_SUCCESS;
1543fe1c642dSBill Krier
1544fe1c642dSBill Krier if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL)
1545fe1c642dSBill Krier status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1546fe1c642dSBill Krier
1547fe1c642dSBill Krier param->status = status;
1548fe1c642dSBill Krier return (NDR_DRC_OK);
1549fe1c642dSBill Krier }
1550fe1c642dSBill Krier
1551fe1c642dSBill Krier /*
1552fe1c642dSBill Krier * samr_s_QueryAliasInfo
1553fe1c642dSBill Krier *
1554fe1c642dSBill Krier * Retrieves information about the specified local group account
1555fe1c642dSBill Krier * by given handle.
1556fe1c642dSBill Krier */
1557fe1c642dSBill Krier static int
samr_s_QueryAliasInfo(void * arg,ndr_xa_t * mxa)1558fe1c642dSBill Krier samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa)
1559fe1c642dSBill Krier {
1560fe1c642dSBill Krier struct samr_QueryAliasInfo *param = arg;
1561fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1562fe1c642dSBill Krier ndr_handle_t *hd;
1563fe1c642dSBill Krier samr_keydata_t *data;
1564fe1c642dSBill Krier smb_group_t grp;
15659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_domain_type_t gd_type;
1566f96bd5c8SAlan Wright smb_sid_t *sid;
1567f96bd5c8SAlan Wright smb_wka_t *wka;
1568f96bd5c8SAlan Wright char sidstr[SMB_SID_STRSZ];
1569f96bd5c8SAlan Wright char *name;
1570f96bd5c8SAlan Wright char *desc;
1571f96bd5c8SAlan Wright uint32_t rid;
1572fe1c642dSBill Krier uint32_t status;
1573fe1c642dSBill Krier int rc;
1574fe1c642dSBill Krier
1575fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
1576fe1c642dSBill Krier status = NT_STATUS_INVALID_HANDLE;
1577fe1c642dSBill Krier goto query_alias_err;
1578fe1c642dSBill Krier }
1579fe1c642dSBill Krier
1580fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
15819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States gd_type = (smb_domain_type_t)data->kd_type;
1582f96bd5c8SAlan Wright rid = data->kd_rid;
1583f96bd5c8SAlan Wright
1584f96bd5c8SAlan Wright switch (gd_type) {
15859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_DOMAIN_BUILTIN:
1586f96bd5c8SAlan Wright (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d",
1587f96bd5c8SAlan Wright NT_BUILTIN_DOMAIN_SIDSTR, rid);
1588f96bd5c8SAlan Wright if ((sid = smb_sid_fromstr(sidstr)) == NULL) {
1589f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1590f96bd5c8SAlan Wright goto query_alias_err;
1591f96bd5c8SAlan Wright }
1592f96bd5c8SAlan Wright
1593f96bd5c8SAlan Wright wka = smb_wka_lookup_sid(sid);
1594f96bd5c8SAlan Wright smb_sid_free(sid);
1595f96bd5c8SAlan Wright
1596f96bd5c8SAlan Wright if (wka == NULL) {
1597f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1598f96bd5c8SAlan Wright goto query_alias_err;
1599f96bd5c8SAlan Wright }
1600f96bd5c8SAlan Wright
1601f96bd5c8SAlan Wright name = wka->wka_name;
1602f96bd5c8SAlan Wright desc = (wka->wka_desc != NULL) ? wka->wka_desc : "";
1603f96bd5c8SAlan Wright break;
1604f96bd5c8SAlan Wright
16059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_DOMAIN_LOCAL:
1606f96bd5c8SAlan Wright rc = smb_lgrp_getbyrid(rid, gd_type, &grp);
1607fe1c642dSBill Krier if (rc != SMB_LGRP_SUCCESS) {
1608fe1c642dSBill Krier status = NT_STATUS_NO_SUCH_ALIAS;
1609fe1c642dSBill Krier goto query_alias_err;
1610fe1c642dSBill Krier }
1611f96bd5c8SAlan Wright name = grp.sg_name;
1612f96bd5c8SAlan Wright desc = grp.sg_cmnt;
1613f96bd5c8SAlan Wright break;
1614f96bd5c8SAlan Wright
1615f96bd5c8SAlan Wright default:
1616f96bd5c8SAlan Wright status = NT_STATUS_NO_SUCH_ALIAS;
1617f96bd5c8SAlan Wright goto query_alias_err;
1618f96bd5c8SAlan Wright }
1619fe1c642dSBill Krier
1620fe1c642dSBill Krier switch (param->level) {
1621fe1c642dSBill Krier case SAMR_QUERY_ALIAS_INFO_1:
1622fe1c642dSBill Krier param->ru.info1.level = param->level;
1623f96bd5c8SAlan Wright (void) NDR_MSTRING(mxa, name,
1624fe1c642dSBill Krier (ndr_mstring_t *)¶m->ru.info1.name);
1625fe1c642dSBill Krier
1626f96bd5c8SAlan Wright (void) NDR_MSTRING(mxa, desc,
1627fe1c642dSBill Krier (ndr_mstring_t *)¶m->ru.info1.desc);
1628fe1c642dSBill Krier
1629fe1c642dSBill Krier param->ru.info1.unknown = 1;
1630fe1c642dSBill Krier break;
1631fe1c642dSBill Krier
1632fe1c642dSBill Krier case SAMR_QUERY_ALIAS_INFO_3:
1633fe1c642dSBill Krier param->ru.info3.level = param->level;
1634f96bd5c8SAlan Wright (void) NDR_MSTRING(mxa, desc,
1635fe1c642dSBill Krier (ndr_mstring_t *)¶m->ru.info3.desc);
1636fe1c642dSBill Krier break;
1637fe1c642dSBill Krier
1638fe1c642dSBill Krier default:
16399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (gd_type == SMB_DOMAIN_LOCAL)
1640fe1c642dSBill Krier smb_lgrp_free(&grp);
1641fe1c642dSBill Krier status = NT_STATUS_INVALID_INFO_CLASS;
1642fe1c642dSBill Krier goto query_alias_err;
1643fe1c642dSBill Krier };
1644fe1c642dSBill Krier
16459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (gd_type == SMB_DOMAIN_LOCAL)
1646fe1c642dSBill Krier smb_lgrp_free(&grp);
1647fe1c642dSBill Krier param->address = (DWORD)(uintptr_t)¶m->ru;
1648fe1c642dSBill Krier param->status = 0;
1649fe1c642dSBill Krier return (NDR_DRC_OK);
1650fe1c642dSBill Krier
1651fe1c642dSBill Krier query_alias_err:
1652fe1c642dSBill Krier param->status = NT_SC_ERROR(status);
1653fe1c642dSBill Krier return (NDR_DRC_OK);
1654fe1c642dSBill Krier }
1655fe1c642dSBill Krier
1656fe1c642dSBill Krier /*
1657fe1c642dSBill Krier * samr_s_DeleteDomainAlias
1658fe1c642dSBill Krier *
1659c5866007SKeyur Desai * Deletes a local group in the security database, which is the
1660c5866007SKeyur Desai * security accounts manager (SAM). A valid group handle is returned
1661c5866007SKeyur Desai * to the caller upon success.
1662fe1c642dSBill Krier *
1663c5866007SKeyur Desai * The caller must have administrator rights to execute this function.
1664fe1c642dSBill Krier */
1665fe1c642dSBill Krier static int
samr_s_DeleteDomainAlias(void * arg,ndr_xa_t * mxa)1666fe1c642dSBill Krier samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa)
1667fe1c642dSBill Krier {
1668fe1c642dSBill Krier struct samr_DeleteDomainAlias *param = arg;
1669fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle;
1670c5866007SKeyur Desai ndr_handle_t *hd;
1671c5866007SKeyur Desai smb_group_t grp;
1672c5866007SKeyur Desai samr_keydata_t *data;
1673c5866007SKeyur Desai smb_domain_type_t gd_type;
1674c5866007SKeyur Desai uint32_t rid;
1675c5866007SKeyur Desai uint32_t rc;
1676c5866007SKeyur Desai uint32_t status = NT_STATUS_SUCCESS;
1677fe1c642dSBill Krier
1678c5866007SKeyur Desai if (!ndr_is_admin(mxa)) {
1679c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias));
1680c5866007SKeyur Desai param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
1681c5866007SKeyur Desai return (NDR_DRC_OK);
1682c5866007SKeyur Desai }
1683c5866007SKeyur Desai
1684c5866007SKeyur Desai if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
1685fe1c642dSBill Krier bzero(param, sizeof (struct samr_DeleteDomainAlias));
1686fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1687fe1c642dSBill Krier return (NDR_DRC_OK);
1688fe1c642dSBill Krier }
1689fe1c642dSBill Krier
1690c5866007SKeyur Desai data = (samr_keydata_t *)hd->nh_data;
1691c5866007SKeyur Desai gd_type = (smb_domain_type_t)data->kd_type;
1692c5866007SKeyur Desai rid = data->kd_rid;
1693c5866007SKeyur Desai
1694c5866007SKeyur Desai switch (gd_type) {
1695c5866007SKeyur Desai case SMB_DOMAIN_BUILTIN:
1696fe1c642dSBill Krier bzero(param, sizeof (struct samr_DeleteDomainAlias));
1697c5866007SKeyur Desai status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED);
1698c5866007SKeyur Desai break;
1699fe1c642dSBill Krier
1700c5866007SKeyur Desai case SMB_DOMAIN_LOCAL:
1701c5866007SKeyur Desai rc = smb_lgrp_getbyrid(rid, gd_type, &grp);
1702c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1703c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias));
1704c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1705c5866007SKeyur Desai status = NT_SC_ERROR(status);
1706c5866007SKeyur Desai break;
1707fe1c642dSBill Krier }
1708fe1c642dSBill Krier
1709c5866007SKeyur Desai rc = smb_lgrp_delete(grp.sg_name);
1710c5866007SKeyur Desai if (rc != SMB_LGRP_SUCCESS) {
1711c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias));
1712c5866007SKeyur Desai status = smb_lgrp_err_to_ntstatus(rc);
1713c5866007SKeyur Desai status = NT_SC_ERROR(status);
1714c5866007SKeyur Desai }
1715c5866007SKeyur Desai smb_lgrp_free(&grp);
1716c5866007SKeyur Desai break;
1717c5866007SKeyur Desai
1718c5866007SKeyur Desai default:
1719c5866007SKeyur Desai bzero(param, sizeof (struct samr_DeleteDomainAlias));
1720c5866007SKeyur Desai status = NT_SC_ERROR(NT_STATUS_NO_SUCH_ALIAS);
1721fe1c642dSBill Krier }
1722fe1c642dSBill Krier
1723c5866007SKeyur Desai param->status = status;
1724fe1c642dSBill Krier return (NDR_DRC_OK);
1725fe1c642dSBill Krier }
1726fe1c642dSBill Krier
1727fe1c642dSBill Krier /*
1728fe1c642dSBill Krier * samr_s_EnumDomainAliases
1729fe1c642dSBill Krier *
1730fe1c642dSBill Krier * This function sends back a list which contains all local groups' name.
1731fe1c642dSBill Krier */
1732fe1c642dSBill Krier static int
samr_s_EnumDomainAliases(void * arg,ndr_xa_t * mxa)1733fe1c642dSBill Krier samr_s_EnumDomainAliases(void *arg, ndr_xa_t *mxa)
1734fe1c642dSBill Krier {
1735fe1c642dSBill Krier struct samr_EnumDomainAliases *param = arg;
1736fe1c642dSBill Krier ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle;
1737fe1c642dSBill Krier ndr_handle_t *hd;
1738fe1c642dSBill Krier samr_keydata_t *data;
1739fe1c642dSBill Krier smb_group_t grp;
1740fe1c642dSBill Krier smb_giter_t gi;
1741fe1c642dSBill Krier int cnt, skip, i;
1742fe1c642dSBill Krier struct name_rid *info;
1743fe1c642dSBill Krier
1744fe1c642dSBill Krier if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
1745fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumDomainAliases));
1746fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
1747fe1c642dSBill Krier return (NDR_DRC_OK);
1748fe1c642dSBill Krier }
1749fe1c642dSBill Krier
1750fe1c642dSBill Krier data = (samr_keydata_t *)hd->nh_data;
1751fe1c642dSBill Krier
1752fe1c642dSBill Krier cnt = smb_sam_grp_cnt(data->kd_type);
1753fe1c642dSBill Krier if (cnt <= param->resume_handle) {
1754fe1c642dSBill Krier param->aliases = (struct aliases_info *)NDR_MALLOC(mxa,
1755fe1c642dSBill Krier sizeof (struct aliases_info));
1756fe1c642dSBill Krier
1757fe1c642dSBill Krier if (param->aliases == NULL) {
1758fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumDomainAliases));
1759fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1760fe1c642dSBill Krier return (NDR_DRC_OK);
1761fe1c642dSBill Krier }
1762fe1c642dSBill Krier
1763fe1c642dSBill Krier bzero(param->aliases, sizeof (struct aliases_info));
1764fe1c642dSBill Krier param->out_resume = 0;
1765fe1c642dSBill Krier param->entries = 0;
1766fe1c642dSBill Krier param->status = NT_STATUS_SUCCESS;
1767fe1c642dSBill Krier return (NDR_DRC_OK);
1768fe1c642dSBill Krier }
1769fe1c642dSBill Krier
1770fe1c642dSBill Krier cnt -= param->resume_handle;
1771fe1c642dSBill Krier param->aliases = (struct aliases_info *)NDR_MALLOC(mxa,
1772fe1c642dSBill Krier sizeof (struct aliases_info) + (cnt-1) * sizeof (struct name_rid));
1773fe1c642dSBill Krier
1774fe1c642dSBill Krier if (param->aliases == NULL) {
1775fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumDomainAliases));
1776fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1777fe1c642dSBill Krier return (NDR_DRC_OK);
1778fe1c642dSBill Krier }
1779fe1c642dSBill Krier
1780fe1c642dSBill Krier if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
1781fe1c642dSBill Krier bzero(param, sizeof (struct samr_EnumDomainAliases));
1782fe1c642dSBill Krier param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR);
1783fe1c642dSBill Krier return (NDR_DRC_OK);
1784fe1c642dSBill Krier }
1785fe1c642dSBill Krier
1786fe1c642dSBill Krier skip = i = 0;
1787fe1c642dSBill Krier info = param->aliases->info;
1788fe1c642dSBill Krier while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) {
1789fe1c642dSBill Krier if ((skip++ >= param->resume_handle) &&
1790fe1c642dSBill Krier (grp.sg_domain == data->kd_type) && (i++ < cnt)) {
1791fe1c642dSBill Krier info->rid = grp.sg_rid;
1792fe1c642dSBill Krier (void) NDR_MSTRING(mxa, grp.sg_name,
1793fe1c642dSBill Krier (ndr_mstring_t *)&info->name);
1794fe1c642dSBill Krier
1795fe1c642dSBill Krier info++;
1796fe1c642dSBill Krier }
1797fe1c642dSBill Krier smb_lgrp_free(&grp);
1798fe1c642dSBill Krier }
1799fe1c642dSBill Krier smb_lgrp_iterclose(&gi);
1800fe1c642dSBill Krier
1801fe1c642dSBill Krier param->aliases->count = i;
1802fe1c642dSBill Krier param->aliases->address = i;
1803fe1c642dSBill Krier
1804fe1c642dSBill Krier param->out_resume = i;
1805fe1c642dSBill Krier param->entries = i;
1806fe1c642dSBill Krier param->status = 0;
1807fe1c642dSBill Krier return (NDR_DRC_OK);
1808fe1c642dSBill Krier }
1809fe1c642dSBill Krier
1810fe1c642dSBill Krier /*
1811cb174861Sjoyce mcintosh * samr_s_Connect4
1812fe1c642dSBill Krier */
1813fe1c642dSBill Krier static int
samr_s_Connect4(void * arg,ndr_xa_t * mxa)1814cb174861Sjoyce mcintosh samr_s_Connect4(void *arg, ndr_xa_t *mxa)
1815fe1c642dSBill Krier {
1816cb174861Sjoyce mcintosh struct samr_Connect4 *param = arg;
1817f96bd5c8SAlan Wright ndr_hdid_t *id;
1818fe1c642dSBill Krier
1819f96bd5c8SAlan Wright id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
1820f96bd5c8SAlan Wright if (id) {
1821f96bd5c8SAlan Wright bcopy(id, ¶m->handle, sizeof (samr_handle_t));
1822f96bd5c8SAlan Wright param->status = 0;
1823f96bd5c8SAlan Wright } else {
1824f96bd5c8SAlan Wright bzero(¶m->handle, sizeof (samr_handle_t));
1825f96bd5c8SAlan Wright param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
1826fe1c642dSBill Krier }
1827fe1c642dSBill Krier
1828f96bd5c8SAlan Wright return (NDR_DRC_OK);
1829f96bd5c8SAlan Wright }
1830fe1c642dSBill Krier
1831fe1c642dSBill Krier /*
1832cb174861Sjoyce mcintosh * samr_s_Connect5
1833fe1c642dSBill Krier *
1834cb174861Sjoyce mcintosh * This is the connect5 form of the connect request used by Windows XP.
1835fe1c642dSBill Krier * Returns an RPC fault for now.
1836fe1c642dSBill Krier */
1837fe1c642dSBill Krier /*ARGSUSED*/
1838fe1c642dSBill Krier static int
samr_s_Connect5(void * arg,ndr_xa_t * mxa)1839cb174861Sjoyce mcintosh samr_s_Connect5(void *arg, ndr_xa_t *mxa)
1840fe1c642dSBill Krier {
1841cb174861Sjoyce mcintosh struct samr_Connect5 *param = arg;
1842fe1c642dSBill Krier
1843cb174861Sjoyce mcintosh bzero(param, sizeof (struct samr_Connect5));
1844fe1c642dSBill Krier return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
1845fe1c642dSBill Krier }
1846fe1c642dSBill Krier
1847fe1c642dSBill Krier static ndr_stub_table_t samr_stub_table[] = {
1848cb174861Sjoyce mcintosh { samr_s_Connect, SAMR_OPNUM_Connect },
1849fe1c642dSBill Krier { samr_s_CloseHandle, SAMR_OPNUM_CloseHandle },
1850fe1c642dSBill Krier { samr_s_LookupDomain, SAMR_OPNUM_LookupDomain },
1851fe1c642dSBill Krier { samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains },
1852fe1c642dSBill Krier { samr_s_OpenDomain, SAMR_OPNUM_OpenDomain },
1853fe1c642dSBill Krier { samr_s_QueryDomainInfo, SAMR_OPNUM_QueryDomainInfo },
1854f96bd5c8SAlan Wright { samr_s_QueryInfoDomain2, SAMR_OPNUM_QueryInfoDomain2 },
1855fe1c642dSBill Krier { samr_s_LookupNames, SAMR_OPNUM_LookupNames },
1856fe1c642dSBill Krier { samr_s_OpenUser, SAMR_OPNUM_OpenUser },
1857fe1c642dSBill Krier { samr_s_DeleteUser, SAMR_OPNUM_DeleteUser },
1858fe1c642dSBill Krier { samr_s_QueryUserInfo, SAMR_OPNUM_QueryUserInfo },
1859fe1c642dSBill Krier { samr_s_QueryUserGroups, SAMR_OPNUM_QueryUserGroups },
1860fe1c642dSBill Krier { samr_s_OpenGroup, SAMR_OPNUM_OpenGroup },
1861cb174861Sjoyce mcintosh { samr_s_Connect2, SAMR_OPNUM_Connect2 },
1862fe1c642dSBill Krier { samr_s_GetUserPwInfo, SAMR_OPNUM_GetUserPwInfo },
1863fe1c642dSBill Krier { samr_s_CreateUser, SAMR_OPNUM_CreateUser },
1864*1ed6b69aSGordon Ross { samr_s_ChangePasswordUser2, SAMR_OPNUM_ChangePasswordUser2 },
1865fe1c642dSBill Krier { samr_s_GetDomainPwInfo, SAMR_OPNUM_GetDomainPwInfo },
1866fe1c642dSBill Krier { samr_s_SetUserInfo, SAMR_OPNUM_SetUserInfo },
1867fe1c642dSBill Krier { samr_s_Connect4, SAMR_OPNUM_Connect4 },
1868cb174861Sjoyce mcintosh { samr_s_Connect5, SAMR_OPNUM_Connect5 },
1869fe1c642dSBill Krier { samr_s_QueryDispInfo, SAMR_OPNUM_QueryDispInfo },
1870fe1c642dSBill Krier { samr_s_OpenAlias, SAMR_OPNUM_OpenAlias },
1871fe1c642dSBill Krier { samr_s_CreateDomainAlias, SAMR_OPNUM_CreateDomainAlias },
1872fe1c642dSBill Krier { samr_s_SetAliasInfo, SAMR_OPNUM_SetAliasInfo },
1873fe1c642dSBill Krier { samr_s_QueryAliasInfo, SAMR_OPNUM_QueryAliasInfo },
1874fe1c642dSBill Krier { samr_s_DeleteDomainAlias, SAMR_OPNUM_DeleteDomainAlias },
1875fe1c642dSBill Krier { samr_s_EnumDomainAliases, SAMR_OPNUM_EnumDomainAliases },
1876fe1c642dSBill Krier { samr_s_EnumDomainGroups, SAMR_OPNUM_EnumDomainGroups },
1877c5866007SKeyur Desai { samr_s_AddAliasMember, SAMR_OPNUM_AddAliasMember },
1878c5866007SKeyur Desai { samr_s_DeleteAliasMember, SAMR_OPNUM_DeleteAliasMember },
1879c5866007SKeyur Desai { samr_s_ListAliasMembers, SAMR_OPNUM_ListAliasMembers },
1880fe1c642dSBill Krier {0}
1881fe1c642dSBill Krier };
1882fe1c642dSBill Krier
1883fe1c642dSBill Krier /*
1884fe1c642dSBill Krier * There is a bug in the way that midl and the marshalling code handles
1885fe1c642dSBill Krier * unions so we need to fix some of the data offsets at runtime. The
1886fe1c642dSBill Krier * following macros and the fixup functions handle the corrections.
1887fe1c642dSBill Krier */
1888fe1c642dSBill Krier
1889fe1c642dSBill Krier DECL_FIXUP_STRUCT(samr_QueryAliasInfo_ru);
1890fe1c642dSBill Krier DECL_FIXUP_STRUCT(samr_QueryAliasInfoRes);
1891fe1c642dSBill Krier DECL_FIXUP_STRUCT(samr_QueryAliasInfo);
1892fe1c642dSBill Krier
1893fe1c642dSBill Krier DECL_FIXUP_STRUCT(QueryUserInfo_result_u);
1894fe1c642dSBill Krier DECL_FIXUP_STRUCT(QueryUserInfo_result);
1895fe1c642dSBill Krier DECL_FIXUP_STRUCT(samr_QueryUserInfo);
1896fe1c642dSBill Krier
1897fe1c642dSBill Krier void
fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo * val)1898fe1c642dSBill Krier fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo *val)
1899fe1c642dSBill Krier {
1900fe1c642dSBill Krier unsigned short size1 = 0;
1901fe1c642dSBill Krier unsigned short size2 = 0;
1902fe1c642dSBill Krier unsigned short size3 = 0;
1903fe1c642dSBill Krier
1904fe1c642dSBill Krier switch (val->level) {
1905fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryAliasInfo, 1);
1906fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryAliasInfo, 3);
1907fe1c642dSBill Krier
1908fe1c642dSBill Krier default:
1909fe1c642dSBill Krier return;
1910fe1c642dSBill Krier };
1911fe1c642dSBill Krier
1912fe1c642dSBill Krier size2 = size1 + (2 * sizeof (DWORD));
1913fe1c642dSBill Krier size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
1914fe1c642dSBill Krier
1915fe1c642dSBill Krier FIXUP_PDU_SIZE(samr_QueryAliasInfo_ru, size1);
1916fe1c642dSBill Krier FIXUP_PDU_SIZE(samr_QueryAliasInfoRes, size2);
1917fe1c642dSBill Krier FIXUP_PDU_SIZE(samr_QueryAliasInfo, size3);
1918fe1c642dSBill Krier }
1919fe1c642dSBill Krier
1920fe1c642dSBill Krier void
fixup_samr_QueryUserInfo(struct samr_QueryUserInfo * val)1921fe1c642dSBill Krier fixup_samr_QueryUserInfo(struct samr_QueryUserInfo *val)
1922fe1c642dSBill Krier {
1923fe1c642dSBill Krier unsigned short size1 = 0;
1924fe1c642dSBill Krier unsigned short size2 = 0;
1925fe1c642dSBill Krier unsigned short size3 = 0;
1926fe1c642dSBill Krier
1927fe1c642dSBill Krier switch (val->switch_index) {
1928fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 1);
1929fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 6);
1930fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 7);
1931fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 8);
1932fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 9);
1933fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 16);
1934fe1c642dSBill Krier CASE_INFO_ENT(samr_QueryUserInfo, 21);
1935fe1c642dSBill Krier
1936fe1c642dSBill Krier default:
1937fe1c642dSBill Krier return;
1938fe1c642dSBill Krier };
1939fe1c642dSBill Krier
1940fe1c642dSBill Krier size2 = size1 + (2 * sizeof (DWORD));
1941fe1c642dSBill Krier size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
1942fe1c642dSBill Krier
1943fe1c642dSBill Krier FIXUP_PDU_SIZE(QueryUserInfo_result_u, size1);
1944fe1c642dSBill Krier FIXUP_PDU_SIZE(QueryUserInfo_result, size2);
1945fe1c642dSBill Krier FIXUP_PDU_SIZE(samr_QueryUserInfo, size3);
1946fe1c642dSBill Krier }
1947fe1c642dSBill Krier
1948fe1c642dSBill Krier /*
1949fe1c642dSBill Krier * As long as there is only one entry in the union, there is no need
1950fe1c642dSBill Krier * to patch anything.
1951fe1c642dSBill Krier */
1952fe1c642dSBill Krier /*ARGSUSED*/
1953fe1c642dSBill Krier void
fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo * val)1954fe1c642dSBill Krier fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo *val)
1955fe1c642dSBill Krier {
1956fe1c642dSBill Krier }
1957