xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c (revision 12890:16985853e3aa)
111337SWilliam.Krier@Sun.COM /*
211337SWilliam.Krier@Sun.COM  * CDDL HEADER START
311337SWilliam.Krier@Sun.COM  *
411337SWilliam.Krier@Sun.COM  * The contents of this file are subject to the terms of the
511337SWilliam.Krier@Sun.COM  * Common Development and Distribution License (the "License").
611337SWilliam.Krier@Sun.COM  * You may not use this file except in compliance with the License.
711337SWilliam.Krier@Sun.COM  *
811337SWilliam.Krier@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911337SWilliam.Krier@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1011337SWilliam.Krier@Sun.COM  * See the License for the specific language governing permissions
1111337SWilliam.Krier@Sun.COM  * and limitations under the License.
1211337SWilliam.Krier@Sun.COM  *
1311337SWilliam.Krier@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1411337SWilliam.Krier@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511337SWilliam.Krier@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1611337SWilliam.Krier@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1711337SWilliam.Krier@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1811337SWilliam.Krier@Sun.COM  *
1911337SWilliam.Krier@Sun.COM  * CDDL HEADER END
2011337SWilliam.Krier@Sun.COM  */
2112508Samw@Sun.COM 
2211337SWilliam.Krier@Sun.COM /*
2312065SKeyur.Desai@Sun.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2411337SWilliam.Krier@Sun.COM  */
2511337SWilliam.Krier@Sun.COM 
2611337SWilliam.Krier@Sun.COM /*
2711337SWilliam.Krier@Sun.COM  * Security Accounts Manager RPC (SAMR) server-side interface.
2811337SWilliam.Krier@Sun.COM  *
2911337SWilliam.Krier@Sun.COM  * The SAM is a hierarchical database:
3011337SWilliam.Krier@Sun.COM  * - If you want to talk to the SAM you need a SAM handle.
3111337SWilliam.Krier@Sun.COM  * - If you want to work with a domain, use the SAM handle.
3211337SWilliam.Krier@Sun.COM  *   to obtain a domain handle.
3311337SWilliam.Krier@Sun.COM  * - Use domain handles to obtain user handles etc.
3411337SWilliam.Krier@Sun.COM  */
3511337SWilliam.Krier@Sun.COM 
3611337SWilliam.Krier@Sun.COM #include <strings.h>
3711337SWilliam.Krier@Sun.COM #include <unistd.h>
3811337SWilliam.Krier@Sun.COM #include <netdb.h>
3911337SWilliam.Krier@Sun.COM #include <assert.h>
4012065SKeyur.Desai@Sun.COM #include <grp.h>
4111337SWilliam.Krier@Sun.COM #include <smbsrv/libsmb.h>
4211337SWilliam.Krier@Sun.COM #include <smbsrv/libmlrpc.h>
4311337SWilliam.Krier@Sun.COM #include <smbsrv/libmlsvc.h>
4411337SWilliam.Krier@Sun.COM #include <smbsrv/smbinfo.h>
4511337SWilliam.Krier@Sun.COM #include <smbsrv/nmpipes.h>
4611337SWilliam.Krier@Sun.COM #include <smbsrv/ndl/samrpc.ndl>
4711337SWilliam.Krier@Sun.COM #include <samlib.h>
4811337SWilliam.Krier@Sun.COM 
4911337SWilliam.Krier@Sun.COM /*
5011337SWilliam.Krier@Sun.COM  * The keys associated with the various handles dispensed by the SAMR
5111337SWilliam.Krier@Sun.COM  * server.  These keys can be used to validate client activity.
5211337SWilliam.Krier@Sun.COM  * These values are never passed over the wire so security shouldn't
5311337SWilliam.Krier@Sun.COM  * be an issue.
5411337SWilliam.Krier@Sun.COM  */
5511337SWilliam.Krier@Sun.COM typedef enum {
5611337SWilliam.Krier@Sun.COM 	SAMR_KEY_NULL = 0,
5711337SWilliam.Krier@Sun.COM 	SAMR_KEY_CONNECT,
5811337SWilliam.Krier@Sun.COM 	SAMR_KEY_DOMAIN,
5911337SWilliam.Krier@Sun.COM 	SAMR_KEY_USER,
6011337SWilliam.Krier@Sun.COM 	SAMR_KEY_GROUP,
6111337SWilliam.Krier@Sun.COM 	SAMR_KEY_ALIAS
6211337SWilliam.Krier@Sun.COM } samr_key_t;
6311337SWilliam.Krier@Sun.COM 
6411337SWilliam.Krier@Sun.COM typedef struct samr_keydata {
6511337SWilliam.Krier@Sun.COM 	samr_key_t kd_key;
6611337SWilliam.Krier@Sun.COM 	smb_domain_type_t kd_type;
6711337SWilliam.Krier@Sun.COM 	DWORD kd_rid;
6811337SWilliam.Krier@Sun.COM } samr_keydata_t;
6911337SWilliam.Krier@Sun.COM 
7011337SWilliam.Krier@Sun.COM /*
7111337SWilliam.Krier@Sun.COM  * DomainDisplayUser	All user objects (or those derived from user) with
7211337SWilliam.Krier@Sun.COM  * 			userAccountControl containing the UF_NORMAL_ACCOUNT bit.
7311337SWilliam.Krier@Sun.COM  *
7411337SWilliam.Krier@Sun.COM  * DomainDisplayMachine	All user objects (or those derived from user) with
7511337SWilliam.Krier@Sun.COM  * 			userAccountControl containing the
7611337SWilliam.Krier@Sun.COM  * 			UF_WORKSTATION_TRUST_ACCOUNT or UF_SERVER_TRUST_ACCOUNT
7711337SWilliam.Krier@Sun.COM  * 			bit.
7811337SWilliam.Krier@Sun.COM  *
7911337SWilliam.Krier@Sun.COM  * DomainDisplayGroup	All group objects (or those derived from group) with
8011337SWilliam.Krier@Sun.COM  * 			groupType equal to GROUP_TYPE_SECURITY_UNIVERSAL or
8111337SWilliam.Krier@Sun.COM  * 			GROUP_TYPE_SECURITY_ACCOUNT.
8211337SWilliam.Krier@Sun.COM  *
8311337SWilliam.Krier@Sun.COM  * DomainDisplayOemUser	Same as DomainDisplayUser with OEM strings
8411337SWilliam.Krier@Sun.COM  *
8511337SWilliam.Krier@Sun.COM  * DomainDisplayOemGroup Same as DomainDisplayGroup with OEM strings
8611337SWilliam.Krier@Sun.COM  */
8711337SWilliam.Krier@Sun.COM typedef enum {
8811337SWilliam.Krier@Sun.COM 	DomainDisplayUser = 1,
8911337SWilliam.Krier@Sun.COM 	DomainDisplayMachine,
9011337SWilliam.Krier@Sun.COM 	DomainDispalyGroup,
9111337SWilliam.Krier@Sun.COM 	DomainDisplayOemUser,
9211337SWilliam.Krier@Sun.COM 	DomainDisplayOemGroup
9311337SWilliam.Krier@Sun.COM } samr_displvl_t;
9411337SWilliam.Krier@Sun.COM 
9511337SWilliam.Krier@Sun.COM #define	SAMR_VALID_DISPLEVEL(lvl) \
9611337SWilliam.Krier@Sun.COM 	(((lvl) >= DomainDisplayUser) && ((lvl) <= DomainDisplayOemGroup))
9711337SWilliam.Krier@Sun.COM 
9811337SWilliam.Krier@Sun.COM #define	SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser)
9911337SWilliam.Krier@Sun.COM 
10011337SWilliam.Krier@Sun.COM static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t,
10111337SWilliam.Krier@Sun.COM     DWORD);
10211337SWilliam.Krier@Sun.COM static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *);
10311337SWilliam.Krier@Sun.COM static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t);
10411337SWilliam.Krier@Sun.COM static int samr_call_stub(ndr_xa_t *mxa);
10511337SWilliam.Krier@Sun.COM static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *,
10611337SWilliam.Krier@Sun.COM     ndr_xa_t *);
10711337SWilliam.Krier@Sun.COM 
10811337SWilliam.Krier@Sun.COM static ndr_stub_table_t samr_stub_table[];
10911337SWilliam.Krier@Sun.COM 
11011337SWilliam.Krier@Sun.COM static ndr_service_t samr_service = {
11111337SWilliam.Krier@Sun.COM 	"SAMR",				/* name */
11211337SWilliam.Krier@Sun.COM 	"Security Accounts Manager",	/* desc */
11311337SWilliam.Krier@Sun.COM 	"\\samr",			/* endpoint */
11411337SWilliam.Krier@Sun.COM 	PIPE_LSASS,			/* sec_addr_port */
11511337SWilliam.Krier@Sun.COM 	"12345778-1234-abcd-ef00-0123456789ac", 1,	/* abstract */
11611337SWilliam.Krier@Sun.COM 	NDR_TRANSFER_SYNTAX_UUID,		2,	/* transfer */
11711337SWilliam.Krier@Sun.COM 	0,				/* no bind_instance_size */
11811337SWilliam.Krier@Sun.COM 	NULL,				/* no bind_req() */
11911337SWilliam.Krier@Sun.COM 	NULL,				/* no unbind_and_close() */
12011337SWilliam.Krier@Sun.COM 	samr_call_stub,			/* call_stub() */
12111337SWilliam.Krier@Sun.COM 	&TYPEINFO(samr_interface),	/* interface ti */
12211337SWilliam.Krier@Sun.COM 	samr_stub_table			/* stub_table */
12311337SWilliam.Krier@Sun.COM };
12411337SWilliam.Krier@Sun.COM 
12511337SWilliam.Krier@Sun.COM /*
12611337SWilliam.Krier@Sun.COM  * samr_initialize
12711337SWilliam.Krier@Sun.COM  *
12811337SWilliam.Krier@Sun.COM  * This function registers the SAM RPC interface with the RPC runtime
12911337SWilliam.Krier@Sun.COM  * library. It must be called in order to use either the client side
13011337SWilliam.Krier@Sun.COM  * or the server side functions.
13111337SWilliam.Krier@Sun.COM  */
13211337SWilliam.Krier@Sun.COM void
samr_initialize(void)13311337SWilliam.Krier@Sun.COM samr_initialize(void)
13411337SWilliam.Krier@Sun.COM {
13511337SWilliam.Krier@Sun.COM 	(void) ndr_svc_register(&samr_service);
13611337SWilliam.Krier@Sun.COM }
13711337SWilliam.Krier@Sun.COM 
13811337SWilliam.Krier@Sun.COM /*
13911337SWilliam.Krier@Sun.COM  * Custom call_stub to set the stream string policy.
14011337SWilliam.Krier@Sun.COM  */
14111337SWilliam.Krier@Sun.COM static int
samr_call_stub(ndr_xa_t * mxa)14211337SWilliam.Krier@Sun.COM samr_call_stub(ndr_xa_t *mxa)
14311337SWilliam.Krier@Sun.COM {
14411337SWilliam.Krier@Sun.COM 	NDS_SETF(&mxa->send_nds, NDS_F_NOTERM);
14511337SWilliam.Krier@Sun.COM 	NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM);
14611337SWilliam.Krier@Sun.COM 
14711337SWilliam.Krier@Sun.COM 	return (ndr_generic_call_stub(mxa));
14811337SWilliam.Krier@Sun.COM }
14911337SWilliam.Krier@Sun.COM 
15011337SWilliam.Krier@Sun.COM /*
15111337SWilliam.Krier@Sun.COM  * Handle allocation wrapper to setup the local context.
15211337SWilliam.Krier@Sun.COM  */
15311337SWilliam.Krier@Sun.COM static ndr_hdid_t *
samr_hdalloc(ndr_xa_t * mxa,samr_key_t key,smb_domain_type_t domain_type,DWORD rid)15411337SWilliam.Krier@Sun.COM samr_hdalloc(ndr_xa_t *mxa, samr_key_t key, smb_domain_type_t domain_type,
15511337SWilliam.Krier@Sun.COM     DWORD rid)
15611337SWilliam.Krier@Sun.COM {
15711963SAfshin.Ardakani@Sun.COM 	ndr_handle_t	*hd;
15811963SAfshin.Ardakani@Sun.COM 	ndr_hdid_t	*id;
15911963SAfshin.Ardakani@Sun.COM 	samr_keydata_t	*data;
16011337SWilliam.Krier@Sun.COM 
16111337SWilliam.Krier@Sun.COM 	if ((data = malloc(sizeof (samr_keydata_t))) == NULL)
16211337SWilliam.Krier@Sun.COM 		return (NULL);
16311337SWilliam.Krier@Sun.COM 
16411337SWilliam.Krier@Sun.COM 	data->kd_key = key;
16511337SWilliam.Krier@Sun.COM 	data->kd_type = domain_type;
16611337SWilliam.Krier@Sun.COM 	data->kd_rid = rid;
16711337SWilliam.Krier@Sun.COM 
16811963SAfshin.Ardakani@Sun.COM 	if ((id = ndr_hdalloc(mxa, data)) == NULL) {
16911963SAfshin.Ardakani@Sun.COM 		free(data);
17011963SAfshin.Ardakani@Sun.COM 		return (NULL);
17111963SAfshin.Ardakani@Sun.COM 	}
17211963SAfshin.Ardakani@Sun.COM 
17311963SAfshin.Ardakani@Sun.COM 	if ((hd = ndr_hdlookup(mxa, id)) != NULL)
17411963SAfshin.Ardakani@Sun.COM 		hd->nh_data_free = free;
17511963SAfshin.Ardakani@Sun.COM 
17611963SAfshin.Ardakani@Sun.COM 	return (id);
17711337SWilliam.Krier@Sun.COM }
17811337SWilliam.Krier@Sun.COM 
17911337SWilliam.Krier@Sun.COM /*
18011337SWilliam.Krier@Sun.COM  * Handle deallocation wrapper to free the local context.
18111337SWilliam.Krier@Sun.COM  */
18211337SWilliam.Krier@Sun.COM static void
samr_hdfree(ndr_xa_t * mxa,ndr_hdid_t * id)18311337SWilliam.Krier@Sun.COM samr_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id)
18411337SWilliam.Krier@Sun.COM {
18511337SWilliam.Krier@Sun.COM 	ndr_handle_t *hd;
18611337SWilliam.Krier@Sun.COM 
18711337SWilliam.Krier@Sun.COM 	if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
18811337SWilliam.Krier@Sun.COM 		free(hd->nh_data);
18911963SAfshin.Ardakani@Sun.COM 		hd->nh_data = NULL;
19011337SWilliam.Krier@Sun.COM 		ndr_hdfree(mxa, id);
19111337SWilliam.Krier@Sun.COM 	}
19211337SWilliam.Krier@Sun.COM }
19311337SWilliam.Krier@Sun.COM 
19411337SWilliam.Krier@Sun.COM /*
19511337SWilliam.Krier@Sun.COM  * Handle lookup wrapper to validate the local context.
19611337SWilliam.Krier@Sun.COM  */
19711337SWilliam.Krier@Sun.COM static ndr_handle_t *
samr_hdlookup(ndr_xa_t * mxa,ndr_hdid_t * id,samr_key_t key)19811337SWilliam.Krier@Sun.COM samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key)
19911337SWilliam.Krier@Sun.COM {
20011337SWilliam.Krier@Sun.COM 	ndr_handle_t *hd;
20111337SWilliam.Krier@Sun.COM 	samr_keydata_t *data;
20211337SWilliam.Krier@Sun.COM 
20311337SWilliam.Krier@Sun.COM 	if ((hd = ndr_hdlookup(mxa, id)) == NULL)
20411337SWilliam.Krier@Sun.COM 		return (NULL);
20511337SWilliam.Krier@Sun.COM 
20611337SWilliam.Krier@Sun.COM 	if ((data = (samr_keydata_t *)hd->nh_data) == NULL)
20711337SWilliam.Krier@Sun.COM 		return (NULL);
20811337SWilliam.Krier@Sun.COM 
20911337SWilliam.Krier@Sun.COM 	if (data->kd_key != key)
21011337SWilliam.Krier@Sun.COM 		return (NULL);
21111337SWilliam.Krier@Sun.COM 
21211337SWilliam.Krier@Sun.COM 	return (hd);
21311337SWilliam.Krier@Sun.COM }
21411337SWilliam.Krier@Sun.COM 
21511337SWilliam.Krier@Sun.COM /*
216*12890SJoyce.McIntosh@Sun.COM  * samr_s_Connect
21711337SWilliam.Krier@Sun.COM  *
21811337SWilliam.Krier@Sun.COM  * This is a request to connect to the local SAM database. We don't
21911337SWilliam.Krier@Sun.COM  * support any form of update request and our database doesn't
22011337SWilliam.Krier@Sun.COM  * contain any private information, so there is little point in
22111337SWilliam.Krier@Sun.COM  * doing any access access checking here.
22211337SWilliam.Krier@Sun.COM  *
22311337SWilliam.Krier@Sun.COM  * Return a handle for use with subsequent SAM requests.
22411337SWilliam.Krier@Sun.COM  */
22511337SWilliam.Krier@Sun.COM static int
samr_s_Connect(void * arg,ndr_xa_t * mxa)226*12890SJoyce.McIntosh@Sun.COM samr_s_Connect(void *arg, ndr_xa_t *mxa)
22711337SWilliam.Krier@Sun.COM {
228*12890SJoyce.McIntosh@Sun.COM 	struct samr_Connect *param = arg;
22911337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id;
23011337SWilliam.Krier@Sun.COM 
23111337SWilliam.Krier@Sun.COM 	id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
23211337SWilliam.Krier@Sun.COM 	if (id) {
23311337SWilliam.Krier@Sun.COM 		bcopy(id, &param->handle, sizeof (samr_handle_t));
23411337SWilliam.Krier@Sun.COM 		param->status = 0;
23511337SWilliam.Krier@Sun.COM 	} else {
23611337SWilliam.Krier@Sun.COM 		bzero(&param->handle, sizeof (samr_handle_t));
23711337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
23811337SWilliam.Krier@Sun.COM 	}
23911337SWilliam.Krier@Sun.COM 
24011337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
24111337SWilliam.Krier@Sun.COM }
24211337SWilliam.Krier@Sun.COM 
24311337SWilliam.Krier@Sun.COM /*
24411337SWilliam.Krier@Sun.COM  * samr_s_CloseHandle
24511337SWilliam.Krier@Sun.COM  *
24611337SWilliam.Krier@Sun.COM  * Close the SAM interface specified by the handle.
24711337SWilliam.Krier@Sun.COM  * Free the handle and zero out the result handle for the client.
24811337SWilliam.Krier@Sun.COM  */
24911337SWilliam.Krier@Sun.COM static int
samr_s_CloseHandle(void * arg,ndr_xa_t * mxa)25011337SWilliam.Krier@Sun.COM samr_s_CloseHandle(void *arg, ndr_xa_t *mxa)
25111337SWilliam.Krier@Sun.COM {
25211337SWilliam.Krier@Sun.COM 	struct samr_CloseHandle *param = arg;
25311337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
25411337SWilliam.Krier@Sun.COM 
25511337SWilliam.Krier@Sun.COM 	samr_hdfree(mxa, id);
25611337SWilliam.Krier@Sun.COM 
25711337SWilliam.Krier@Sun.COM 	bzero(&param->result_handle, sizeof (samr_handle_t));
25811337SWilliam.Krier@Sun.COM 	param->status = 0;
25911337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
26011337SWilliam.Krier@Sun.COM }
26111337SWilliam.Krier@Sun.COM 
26211337SWilliam.Krier@Sun.COM /*
26311337SWilliam.Krier@Sun.COM  * samr_s_LookupDomain
26411337SWilliam.Krier@Sun.COM  *
26511337SWilliam.Krier@Sun.COM  * This is a request to map a domain name to a domain SID. We can map
26611337SWilliam.Krier@Sun.COM  * the primary domain name, our local domain name (hostname) and the
26711337SWilliam.Krier@Sun.COM  * builtin domain names to the appropriate SID. Anything else will be
26811337SWilliam.Krier@Sun.COM  * rejected.
26911337SWilliam.Krier@Sun.COM  */
27011337SWilliam.Krier@Sun.COM static int
samr_s_LookupDomain(void * arg,ndr_xa_t * mxa)27111337SWilliam.Krier@Sun.COM samr_s_LookupDomain(void *arg, ndr_xa_t *mxa)
27211337SWilliam.Krier@Sun.COM {
27311337SWilliam.Krier@Sun.COM 	struct samr_LookupDomain *param = arg;
27411337SWilliam.Krier@Sun.COM 	char *domain_name;
27511337SWilliam.Krier@Sun.COM 	smb_domain_t di;
27611337SWilliam.Krier@Sun.COM 
27711337SWilliam.Krier@Sun.COM 	if ((domain_name = (char *)param->domain_name.str) == NULL) {
27811337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_LookupDomain));
27911337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
28011337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
28111337SWilliam.Krier@Sun.COM 	}
28211337SWilliam.Krier@Sun.COM 
28311337SWilliam.Krier@Sun.COM 	if (!smb_domain_lookup_name(domain_name, &di)) {
28411337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_LookupDomain));
28511337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_DOMAIN);
28611337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
28711337SWilliam.Krier@Sun.COM 	}
28811337SWilliam.Krier@Sun.COM 
28911337SWilliam.Krier@Sun.COM 	param->sid = (struct samr_sid *)NDR_SIDDUP(mxa, di.di_binsid);
29011337SWilliam.Krier@Sun.COM 	if (param->sid == NULL) {
29111337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_LookupDomain));
29211337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
29311337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
29411337SWilliam.Krier@Sun.COM 	}
29511337SWilliam.Krier@Sun.COM 
29611337SWilliam.Krier@Sun.COM 	param->status = NT_STATUS_SUCCESS;
29711337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
29811337SWilliam.Krier@Sun.COM }
29911337SWilliam.Krier@Sun.COM 
30011337SWilliam.Krier@Sun.COM /*
30111337SWilliam.Krier@Sun.COM  * samr_s_EnumLocalDomains
30211337SWilliam.Krier@Sun.COM  *
30311337SWilliam.Krier@Sun.COM  * This is a request for the local domains supported by this server.
30411337SWilliam.Krier@Sun.COM  * All we do here is validate the handle and set the status. The real
30511337SWilliam.Krier@Sun.COM  * work is done in samr_s_enum_local_domains.
30611337SWilliam.Krier@Sun.COM  */
30711337SWilliam.Krier@Sun.COM static int
samr_s_EnumLocalDomains(void * arg,ndr_xa_t * mxa)30811337SWilliam.Krier@Sun.COM samr_s_EnumLocalDomains(void *arg, ndr_xa_t *mxa)
30911337SWilliam.Krier@Sun.COM {
31011337SWilliam.Krier@Sun.COM 	struct samr_EnumLocalDomain *param = arg;
31111337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
31211337SWilliam.Krier@Sun.COM 	DWORD status;
31311337SWilliam.Krier@Sun.COM 
31411337SWilliam.Krier@Sun.COM 	if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL)
31511337SWilliam.Krier@Sun.COM 		status = NT_STATUS_ACCESS_DENIED;
31611337SWilliam.Krier@Sun.COM 	else
31711337SWilliam.Krier@Sun.COM 		status = samr_s_enum_local_domains(param, mxa);
31811337SWilliam.Krier@Sun.COM 
31911337SWilliam.Krier@Sun.COM 	if (status == NT_STATUS_SUCCESS) {
32011337SWilliam.Krier@Sun.COM 		param->enum_context = param->info->entries_read;
32111337SWilliam.Krier@Sun.COM 		param->total_entries = param->info->entries_read;
32211337SWilliam.Krier@Sun.COM 		param->status = NT_STATUS_SUCCESS;
32311337SWilliam.Krier@Sun.COM 	} else {
32411337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_EnumLocalDomain));
32511337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(status);
32611337SWilliam.Krier@Sun.COM 	}
32711337SWilliam.Krier@Sun.COM 
32811337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
32911337SWilliam.Krier@Sun.COM }
33011337SWilliam.Krier@Sun.COM 
33111337SWilliam.Krier@Sun.COM 
33211337SWilliam.Krier@Sun.COM /*
33311337SWilliam.Krier@Sun.COM  * samr_s_enum_local_domains
33411337SWilliam.Krier@Sun.COM  *
33511337SWilliam.Krier@Sun.COM  * This function should only be called via samr_s_EnumLocalDomains to
33611337SWilliam.Krier@Sun.COM  * ensure that the appropriate validation is performed. We will answer
33711337SWilliam.Krier@Sun.COM  * queries about two domains: the local domain, synonymous with the
33811337SWilliam.Krier@Sun.COM  * local hostname, and the BUILTIN domain. So we return these two
33911337SWilliam.Krier@Sun.COM  * strings.
34011337SWilliam.Krier@Sun.COM  *
34111337SWilliam.Krier@Sun.COM  * Returns NT status values.
34211337SWilliam.Krier@Sun.COM  */
34311337SWilliam.Krier@Sun.COM static DWORD
samr_s_enum_local_domains(struct samr_EnumLocalDomain * param,ndr_xa_t * mxa)34411337SWilliam.Krier@Sun.COM samr_s_enum_local_domains(struct samr_EnumLocalDomain *param,
34511337SWilliam.Krier@Sun.COM     ndr_xa_t *mxa)
34611337SWilliam.Krier@Sun.COM {
34711337SWilliam.Krier@Sun.COM 	struct samr_LocalDomainInfo *info;
34811337SWilliam.Krier@Sun.COM 	struct samr_LocalDomainEntry *entry;
34911337SWilliam.Krier@Sun.COM 	char *hostname;
35011337SWilliam.Krier@Sun.COM 
35111337SWilliam.Krier@Sun.COM 	hostname = NDR_MALLOC(mxa, NETBIOS_NAME_SZ);
35211337SWilliam.Krier@Sun.COM 	if (hostname == NULL)
35311337SWilliam.Krier@Sun.COM 		return (NT_STATUS_NO_MEMORY);
35411337SWilliam.Krier@Sun.COM 
35511337SWilliam.Krier@Sun.COM 	if (smb_getnetbiosname(hostname, NETBIOS_NAME_SZ) != 0)
35611337SWilliam.Krier@Sun.COM 		return (NT_STATUS_NO_MEMORY);
35711337SWilliam.Krier@Sun.COM 
35811337SWilliam.Krier@Sun.COM 	entry = NDR_NEWN(mxa, struct samr_LocalDomainEntry, 2);
35911337SWilliam.Krier@Sun.COM 	if (entry == NULL)
36011337SWilliam.Krier@Sun.COM 		return (NT_STATUS_NO_MEMORY);
36111337SWilliam.Krier@Sun.COM 
36211337SWilliam.Krier@Sun.COM 	bzero(entry, (sizeof (struct samr_LocalDomainEntry) * 2));
36311337SWilliam.Krier@Sun.COM 	(void) NDR_MSTRING(mxa, hostname, (ndr_mstring_t *)&entry[0].name);
36411337SWilliam.Krier@Sun.COM 	(void) NDR_MSTRING(mxa, "Builtin", (ndr_mstring_t *)&entry[1].name);
36511337SWilliam.Krier@Sun.COM 
36611337SWilliam.Krier@Sun.COM 	info = NDR_NEW(mxa, struct samr_LocalDomainInfo);
36711337SWilliam.Krier@Sun.COM 	if (info == NULL)
36811337SWilliam.Krier@Sun.COM 		return (NT_STATUS_NO_MEMORY);
36911337SWilliam.Krier@Sun.COM 
37011337SWilliam.Krier@Sun.COM 	info->entries_read = 2;
37111337SWilliam.Krier@Sun.COM 	info->entry = entry;
37211337SWilliam.Krier@Sun.COM 	param->info = info;
37311337SWilliam.Krier@Sun.COM 	return (NT_STATUS_SUCCESS);
37411337SWilliam.Krier@Sun.COM }
37511337SWilliam.Krier@Sun.COM 
37611337SWilliam.Krier@Sun.COM /*
37711337SWilliam.Krier@Sun.COM  * samr_s_OpenDomain
37811337SWilliam.Krier@Sun.COM  *
37911337SWilliam.Krier@Sun.COM  * This is a request to open a domain within the local SAM database.
38011337SWilliam.Krier@Sun.COM  * The caller must supply a valid connect handle.
38111337SWilliam.Krier@Sun.COM  * We return a handle to be used to access objects within this domain.
38211337SWilliam.Krier@Sun.COM  */
38311337SWilliam.Krier@Sun.COM static int
samr_s_OpenDomain(void * arg,ndr_xa_t * mxa)38411337SWilliam.Krier@Sun.COM samr_s_OpenDomain(void *arg, ndr_xa_t *mxa)
38511337SWilliam.Krier@Sun.COM {
38611337SWilliam.Krier@Sun.COM 	struct samr_OpenDomain *param = arg;
38711337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
38811337SWilliam.Krier@Sun.COM 	smb_domain_t domain;
38911337SWilliam.Krier@Sun.COM 
39011337SWilliam.Krier@Sun.COM 	if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) {
39111337SWilliam.Krier@Sun.COM 		bzero(&param->domain_handle, sizeof (samr_handle_t));
39211337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
39311337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
39411337SWilliam.Krier@Sun.COM 	}
39511337SWilliam.Krier@Sun.COM 
39611337SWilliam.Krier@Sun.COM 	if (!smb_domain_lookup_sid((smb_sid_t *)param->sid, &domain)) {
39711337SWilliam.Krier@Sun.COM 		bzero(&param->domain_handle, sizeof (samr_handle_t));
39811337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
39911337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
40011337SWilliam.Krier@Sun.COM 	}
40111337SWilliam.Krier@Sun.COM 
40211337SWilliam.Krier@Sun.COM 	if ((domain.di_type != SMB_DOMAIN_BUILTIN) &&
40311337SWilliam.Krier@Sun.COM 	    (domain.di_type != SMB_DOMAIN_LOCAL)) {
40411337SWilliam.Krier@Sun.COM 		bzero(&param->domain_handle, sizeof (samr_handle_t));
40511337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
40611337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
40711337SWilliam.Krier@Sun.COM 	}
40811337SWilliam.Krier@Sun.COM 
40911337SWilliam.Krier@Sun.COM 	id = samr_hdalloc(mxa, SAMR_KEY_DOMAIN, domain.di_type, 0);
41011337SWilliam.Krier@Sun.COM 	if (id) {
41111337SWilliam.Krier@Sun.COM 		bcopy(id, &param->domain_handle, sizeof (samr_handle_t));
41211337SWilliam.Krier@Sun.COM 		param->status = 0;
41311337SWilliam.Krier@Sun.COM 	} else {
41411337SWilliam.Krier@Sun.COM 		bzero(&param->domain_handle, sizeof (samr_handle_t));
41511337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
41611337SWilliam.Krier@Sun.COM 	}
41711337SWilliam.Krier@Sun.COM 
41811337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
41911337SWilliam.Krier@Sun.COM }
42011337SWilliam.Krier@Sun.COM 
42111337SWilliam.Krier@Sun.COM /*
42211337SWilliam.Krier@Sun.COM  * samr_s_QueryDomainInfo
42311337SWilliam.Krier@Sun.COM  *
42411337SWilliam.Krier@Sun.COM  * The caller should pass a domain handle.
42511337SWilliam.Krier@Sun.COM  *
42611337SWilliam.Krier@Sun.COM  * Windows 95 Server Manager sends requests for levels 6 and 7 when
42711337SWilliam.Krier@Sun.COM  * the services menu item is selected. Level 2 is basically for getting
42811337SWilliam.Krier@Sun.COM  * number of users, groups, and aliases in a domain.
42911337SWilliam.Krier@Sun.COM  * We have no information on what the various information levels mean.
43011337SWilliam.Krier@Sun.COM  */
43111337SWilliam.Krier@Sun.COM static int
samr_s_QueryDomainInfo(void * arg,ndr_xa_t * mxa)43211337SWilliam.Krier@Sun.COM samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa)
43311337SWilliam.Krier@Sun.COM {
43411337SWilliam.Krier@Sun.COM 	struct samr_QueryDomainInfo *param = arg;
43511337SWilliam.Krier@Sun.COM 	struct samr_QueryDomainInfoRes *info;
43611337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->domain_handle;
43711337SWilliam.Krier@Sun.COM 	ndr_handle_t *hd;
43811337SWilliam.Krier@Sun.COM 	samr_keydata_t *data;
43911337SWilliam.Krier@Sun.COM 	char *domain;
44011337SWilliam.Krier@Sun.COM 	char hostname[NETBIOS_NAME_SZ];
44111337SWilliam.Krier@Sun.COM 	int alias_cnt, user_cnt;
44211337SWilliam.Krier@Sun.COM 	int rc = 0;
44311337SWilliam.Krier@Sun.COM 
44411337SWilliam.Krier@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
44511337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_QueryDomainInfo));
44611337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
44711337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
44811337SWilliam.Krier@Sun.COM 	}
44911337SWilliam.Krier@Sun.COM 
45011337SWilliam.Krier@Sun.COM 	info = NDR_NEW(mxa, struct samr_QueryDomainInfoRes);
45111337SWilliam.Krier@Sun.COM 	if (info == NULL) {
45211337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_QueryDomainInfo));
45311337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
45411337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
45511337SWilliam.Krier@Sun.COM 	}
45611337SWilliam.Krier@Sun.COM 	info->switch_value = param->info_level;
45711337SWilliam.Krier@Sun.COM 	param->info = info;
45811337SWilliam.Krier@Sun.COM 
45911337SWilliam.Krier@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
46011337SWilliam.Krier@Sun.COM 
46111337SWilliam.Krier@Sun.COM 	switch (data->kd_type) {
46211337SWilliam.Krier@Sun.COM 	case SMB_DOMAIN_BUILTIN:
46311337SWilliam.Krier@Sun.COM 		domain = "BUILTIN";
46411337SWilliam.Krier@Sun.COM 		user_cnt = 0;
46511337SWilliam.Krier@Sun.COM 		alias_cnt = smb_sam_grp_cnt(data->kd_type);
46611337SWilliam.Krier@Sun.COM 		break;
46711337SWilliam.Krier@Sun.COM 
46811337SWilliam.Krier@Sun.COM 	case SMB_DOMAIN_LOCAL:
46911337SWilliam.Krier@Sun.COM 		rc = smb_getnetbiosname(hostname, sizeof (hostname));
47011337SWilliam.Krier@Sun.COM 		if (rc == 0) {
47111337SWilliam.Krier@Sun.COM 			domain = hostname;
47211337SWilliam.Krier@Sun.COM 			user_cnt = smb_sam_usr_cnt();
47311337SWilliam.Krier@Sun.COM 			alias_cnt = smb_sam_grp_cnt(data->kd_type);
47411337SWilliam.Krier@Sun.COM 		}
47511337SWilliam.Krier@Sun.COM 		break;
47611337SWilliam.Krier@Sun.COM 
47711337SWilliam.Krier@Sun.COM 	default:
47811337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_QueryDomainInfo));
47911337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
48011337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
48111337SWilliam.Krier@Sun.COM 	}
48211337SWilliam.Krier@Sun.COM 
48311337SWilliam.Krier@Sun.COM 	if (rc != 0) {
48411337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_QueryDomainInfo));
48511337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR);
48611337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
48711337SWilliam.Krier@Sun.COM 	}
48811337SWilliam.Krier@Sun.COM 
48911337SWilliam.Krier@Sun.COM 	switch (param->info_level) {
49011337SWilliam.Krier@Sun.COM 	case SAMR_QUERY_DOMAIN_INFO_6:
49111337SWilliam.Krier@Sun.COM 		info->ru.info6.unknown1 = 0x00000000;
49211337SWilliam.Krier@Sun.COM 		info->ru.info6.unknown2 = 0x00147FB0;
49311337SWilliam.Krier@Sun.COM 		info->ru.info6.unknown3 = 0x00000000;
49411337SWilliam.Krier@Sun.COM 		info->ru.info6.unknown4 = 0x00000000;
49511337SWilliam.Krier@Sun.COM 		info->ru.info6.unknown5 = 0x00000000;
49611337SWilliam.Krier@Sun.COM 		param->status = NT_STATUS_SUCCESS;
49711337SWilliam.Krier@Sun.COM 		break;
49811337SWilliam.Krier@Sun.COM 
49911337SWilliam.Krier@Sun.COM 	case SAMR_QUERY_DOMAIN_INFO_7:
50011337SWilliam.Krier@Sun.COM 		info->ru.info7.unknown1 = 0x00000003;
50111337SWilliam.Krier@Sun.COM 		param->status = NT_STATUS_SUCCESS;
50211337SWilliam.Krier@Sun.COM 		break;
50311337SWilliam.Krier@Sun.COM 
50411337SWilliam.Krier@Sun.COM 	case SAMR_QUERY_DOMAIN_INFO_2:
50511337SWilliam.Krier@Sun.COM 		info->ru.info2.unknown1 = 0x00000000;
50611337SWilliam.Krier@Sun.COM 		info->ru.info2.unknown2 = 0x80000000;
50711337SWilliam.Krier@Sun.COM 
50811337SWilliam.Krier@Sun.COM 		(void) NDR_MSTRING(mxa, "",
50911337SWilliam.Krier@Sun.COM 		    (ndr_mstring_t *)&(info->ru.info2.s1));
51011337SWilliam.Krier@Sun.COM 		(void) NDR_MSTRING(mxa, domain,
51111337SWilliam.Krier@Sun.COM 		    (ndr_mstring_t *)&(info->ru.info2.domain));
51211337SWilliam.Krier@Sun.COM 		(void) NDR_MSTRING(mxa, "",
51311337SWilliam.Krier@Sun.COM 		    (ndr_mstring_t *)&(info->ru.info2.s2));
51411337SWilliam.Krier@Sun.COM 
51511337SWilliam.Krier@Sun.COM 		info->ru.info2.sequence_num = 0x0000002B;
51611337SWilliam.Krier@Sun.COM 		info->ru.info2.unknown3 = 0x00000000;
51711337SWilliam.Krier@Sun.COM 		info->ru.info2.unknown4 = 0x00000001;
51811337SWilliam.Krier@Sun.COM 		info->ru.info2.unknown5 = 0x00000003;
51911337SWilliam.Krier@Sun.COM 		info->ru.info2.unknown6 = 0x00000001;
52011337SWilliam.Krier@Sun.COM 		info->ru.info2.num_users = user_cnt;
52111337SWilliam.Krier@Sun.COM 		info->ru.info2.num_groups = 0;
52211337SWilliam.Krier@Sun.COM 		info->ru.info2.num_aliases = alias_cnt;
52311337SWilliam.Krier@Sun.COM 		param->status = NT_STATUS_SUCCESS;
52411337SWilliam.Krier@Sun.COM 		break;
52511337SWilliam.Krier@Sun.COM 
52611337SWilliam.Krier@Sun.COM 	default:
52711337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_QueryDomainInfo));
52811337SWilliam.Krier@Sun.COM 		return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
52911337SWilliam.Krier@Sun.COM 	};
53011337SWilliam.Krier@Sun.COM 
53111337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
53211337SWilliam.Krier@Sun.COM }
53311337SWilliam.Krier@Sun.COM 
53411337SWilliam.Krier@Sun.COM /*
53511447Samw@Sun.COM  * QueryInfoDomain2: Identical to QueryDomainInfo.
53611447Samw@Sun.COM  */
53711447Samw@Sun.COM static int
samr_s_QueryInfoDomain2(void * arg,ndr_xa_t * mxa)53811447Samw@Sun.COM samr_s_QueryInfoDomain2(void *arg, ndr_xa_t *mxa)
53911447Samw@Sun.COM {
54011447Samw@Sun.COM 	return (samr_s_QueryDomainInfo(arg, mxa));
54111447Samw@Sun.COM }
54211447Samw@Sun.COM 
54311447Samw@Sun.COM /*
54411337SWilliam.Krier@Sun.COM  * Looks up the given name in the specified domain which could
54511337SWilliam.Krier@Sun.COM  * be either the built-in or local domain.
54611337SWilliam.Krier@Sun.COM  *
54711337SWilliam.Krier@Sun.COM  * CAVEAT: this function should be able to handle a list of
54811337SWilliam.Krier@Sun.COM  * names but currently it can only handle one name at a time.
54911337SWilliam.Krier@Sun.COM  */
55011337SWilliam.Krier@Sun.COM static int
samr_s_LookupNames(void * arg,ndr_xa_t * mxa)55111337SWilliam.Krier@Sun.COM samr_s_LookupNames(void *arg, ndr_xa_t *mxa)
55211337SWilliam.Krier@Sun.COM {
55311337SWilliam.Krier@Sun.COM 	struct samr_LookupNames *param = arg;
55411337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
55511337SWilliam.Krier@Sun.COM 	ndr_handle_t *hd;
55611337SWilliam.Krier@Sun.COM 	samr_keydata_t *data;
55711337SWilliam.Krier@Sun.COM 	smb_account_t account;
55811337SWilliam.Krier@Sun.COM 	smb_wka_t *wka;
55911337SWilliam.Krier@Sun.COM 	uint32_t status = NT_STATUS_SUCCESS;
56011337SWilliam.Krier@Sun.COM 
56111337SWilliam.Krier@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL)
56211337SWilliam.Krier@Sun.COM 		status = NT_STATUS_INVALID_HANDLE;
56311337SWilliam.Krier@Sun.COM 
56411337SWilliam.Krier@Sun.COM 	if (param->n_entry != 1)
56511337SWilliam.Krier@Sun.COM 		status = NT_STATUS_ACCESS_DENIED;
56611337SWilliam.Krier@Sun.COM 
56711337SWilliam.Krier@Sun.COM 	if (param->name.str == NULL) {
56811337SWilliam.Krier@Sun.COM 		/*
56911337SWilliam.Krier@Sun.COM 		 * Windows NT returns NT_STATUS_NONE_MAPPED.
57011337SWilliam.Krier@Sun.COM 		 * Windows 2000 returns STATUS_INVALID_ACCOUNT_NAME.
57111337SWilliam.Krier@Sun.COM 		 */
57211337SWilliam.Krier@Sun.COM 		status = NT_STATUS_NONE_MAPPED;
57311337SWilliam.Krier@Sun.COM 	}
57411337SWilliam.Krier@Sun.COM 
57511337SWilliam.Krier@Sun.COM 	if (status != NT_STATUS_SUCCESS) {
57611337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_LookupNames));
57711337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(status);
57811337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
57911337SWilliam.Krier@Sun.COM 	}
58011337SWilliam.Krier@Sun.COM 
58111337SWilliam.Krier@Sun.COM 	param->rids.rid = NDR_NEW(mxa, DWORD);
58211337SWilliam.Krier@Sun.COM 	param->rid_types.rid_type = NDR_NEW(mxa, DWORD);
58311337SWilliam.Krier@Sun.COM 
58411337SWilliam.Krier@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
58511337SWilliam.Krier@Sun.COM 
58611337SWilliam.Krier@Sun.COM 	switch (data->kd_type) {
58711337SWilliam.Krier@Sun.COM 	case SMB_DOMAIN_BUILTIN:
58811447Samw@Sun.COM 		wka = smb_wka_lookup_builtin((char *)param->name.str);
58911337SWilliam.Krier@Sun.COM 		if (wka != NULL) {
59011337SWilliam.Krier@Sun.COM 			param->rids.n_entry = 1;
59111337SWilliam.Krier@Sun.COM 			(void) smb_sid_getrid(wka->wka_binsid,
59211337SWilliam.Krier@Sun.COM 			    &param->rids.rid[0]);
59311337SWilliam.Krier@Sun.COM 			param->rid_types.n_entry = 1;
59411337SWilliam.Krier@Sun.COM 			param->rid_types.rid_type[0] = wka->wka_type;
59511337SWilliam.Krier@Sun.COM 			param->status = NT_STATUS_SUCCESS;
59611337SWilliam.Krier@Sun.COM 			return (NDR_DRC_OK);
59711337SWilliam.Krier@Sun.COM 		}
59811337SWilliam.Krier@Sun.COM 		break;
59911337SWilliam.Krier@Sun.COM 
60011337SWilliam.Krier@Sun.COM 	case SMB_DOMAIN_LOCAL:
60111337SWilliam.Krier@Sun.COM 		status = smb_sam_lookup_name(NULL, (char *)param->name.str,
60211337SWilliam.Krier@Sun.COM 		    SidTypeUnknown, &account);
60311337SWilliam.Krier@Sun.COM 		if (status == NT_STATUS_SUCCESS) {
60411337SWilliam.Krier@Sun.COM 			param->rids.n_entry = 1;
60511337SWilliam.Krier@Sun.COM 			param->rids.rid[0] = account.a_rid;
60611337SWilliam.Krier@Sun.COM 			param->rid_types.n_entry = 1;
60711337SWilliam.Krier@Sun.COM 			param->rid_types.rid_type[0] = account.a_type;
60811337SWilliam.Krier@Sun.COM 			param->status = NT_STATUS_SUCCESS;
60911337SWilliam.Krier@Sun.COM 			smb_account_free(&account);
61011337SWilliam.Krier@Sun.COM 			return (NDR_DRC_OK);
61111337SWilliam.Krier@Sun.COM 		}
61211337SWilliam.Krier@Sun.COM 		break;
61311337SWilliam.Krier@Sun.COM 
61411337SWilliam.Krier@Sun.COM 	default:
61511337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_LookupNames));
61611337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
61711337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
61811337SWilliam.Krier@Sun.COM 	}
61911337SWilliam.Krier@Sun.COM 
62011337SWilliam.Krier@Sun.COM 	param->rids.n_entry = 0;
62111337SWilliam.Krier@Sun.COM 	param->rid_types.n_entry = 0;
62211337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_NONE_MAPPED);
62311337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
62411337SWilliam.Krier@Sun.COM }
62511337SWilliam.Krier@Sun.COM 
62611337SWilliam.Krier@Sun.COM /*
62711337SWilliam.Krier@Sun.COM  * samr_s_OpenUser
62811337SWilliam.Krier@Sun.COM  *
62911337SWilliam.Krier@Sun.COM  * This is a request to open a user within a specified domain in the
63011337SWilliam.Krier@Sun.COM  * local SAM database. The caller must supply a valid domain handle,
63111337SWilliam.Krier@Sun.COM  * obtained via a successful domain open request. The user is
63211337SWilliam.Krier@Sun.COM  * specified by the rid in the request.
63311337SWilliam.Krier@Sun.COM  */
63411337SWilliam.Krier@Sun.COM static int
samr_s_OpenUser(void * arg,ndr_xa_t * mxa)63511337SWilliam.Krier@Sun.COM samr_s_OpenUser(void *arg, ndr_xa_t *mxa)
63611337SWilliam.Krier@Sun.COM {
63711337SWilliam.Krier@Sun.COM 	struct samr_OpenUser *param = arg;
63811337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
63911337SWilliam.Krier@Sun.COM 	ndr_handle_t *hd;
64011337SWilliam.Krier@Sun.COM 	samr_keydata_t *data;
64111337SWilliam.Krier@Sun.COM 
64211337SWilliam.Krier@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
64311337SWilliam.Krier@Sun.COM 		bzero(&param->user_handle, sizeof (samr_handle_t));
64411337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
64511337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
64611337SWilliam.Krier@Sun.COM 	}
64711337SWilliam.Krier@Sun.COM 
64811337SWilliam.Krier@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
64911337SWilliam.Krier@Sun.COM 
65011337SWilliam.Krier@Sun.COM 	id = samr_hdalloc(mxa, SAMR_KEY_USER, data->kd_type, param->rid);
65111337SWilliam.Krier@Sun.COM 	if (id == NULL) {
65211337SWilliam.Krier@Sun.COM 		bzero(&param->user_handle, sizeof (samr_handle_t));
65311337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
65411337SWilliam.Krier@Sun.COM 	} else {
65511337SWilliam.Krier@Sun.COM 		bcopy(id, &param->user_handle, sizeof (samr_handle_t));
65611337SWilliam.Krier@Sun.COM 		param->status = NT_STATUS_SUCCESS;
65711337SWilliam.Krier@Sun.COM 	}
65811337SWilliam.Krier@Sun.COM 
65911337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
66011337SWilliam.Krier@Sun.COM }
66111337SWilliam.Krier@Sun.COM 
66211337SWilliam.Krier@Sun.COM /*
66311337SWilliam.Krier@Sun.COM  * samr_s_DeleteUser
66411337SWilliam.Krier@Sun.COM  *
66511337SWilliam.Krier@Sun.COM  * Request to delete a user within a specified domain in the local
66611337SWilliam.Krier@Sun.COM  * SAM database.  The caller should supply a valid user handle.
66711337SWilliam.Krier@Sun.COM  */
66811337SWilliam.Krier@Sun.COM /*ARGSUSED*/
66911337SWilliam.Krier@Sun.COM static int
samr_s_DeleteUser(void * arg,ndr_xa_t * mxa)67011337SWilliam.Krier@Sun.COM samr_s_DeleteUser(void *arg, ndr_xa_t *mxa)
67111337SWilliam.Krier@Sun.COM {
67211337SWilliam.Krier@Sun.COM 	struct samr_DeleteUser *param = arg;
67311337SWilliam.Krier@Sun.COM 
67411337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct samr_DeleteUser));
67511337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
67611337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
67711337SWilliam.Krier@Sun.COM }
67811337SWilliam.Krier@Sun.COM 
67911337SWilliam.Krier@Sun.COM /*
68011337SWilliam.Krier@Sun.COM  * samr_s_QueryUserInfo
68111337SWilliam.Krier@Sun.COM  *
68211337SWilliam.Krier@Sun.COM  * Returns:
68311337SWilliam.Krier@Sun.COM  * NT_STATUS_SUCCESS
68411337SWilliam.Krier@Sun.COM  * NT_STATUS_ACCESS_DENIED
68511337SWilliam.Krier@Sun.COM  * NT_STATUS_INVALID_INFO_CLASS
68611337SWilliam.Krier@Sun.COM  */
68711337SWilliam.Krier@Sun.COM /*ARGSUSED*/
68811337SWilliam.Krier@Sun.COM static int
samr_s_QueryUserInfo(void * arg,ndr_xa_t * mxa)68911337SWilliam.Krier@Sun.COM samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa)
69011337SWilliam.Krier@Sun.COM {
69111337SWilliam.Krier@Sun.COM 	static uint16_t			owf_buf[8];
69211337SWilliam.Krier@Sun.COM 	static uint8_t			hour_buf[SAMR_SET_USER_HOURS_SZ];
69311337SWilliam.Krier@Sun.COM 	struct samr_QueryUserInfo	*param = arg;
69411337SWilliam.Krier@Sun.COM 	struct samr_QueryUserInfo21	*all_info;
69511337SWilliam.Krier@Sun.COM 	ndr_hdid_t			*id;
69611337SWilliam.Krier@Sun.COM 	ndr_handle_t			*hd;
69711337SWilliam.Krier@Sun.COM 	samr_keydata_t			*data;
69811337SWilliam.Krier@Sun.COM 	smb_domain_t			di;
69911337SWilliam.Krier@Sun.COM 	smb_account_t			account;
70011337SWilliam.Krier@Sun.COM 	smb_sid_t			*sid;
70111337SWilliam.Krier@Sun.COM 	uint32_t			status;
70211337SWilliam.Krier@Sun.COM 
70311337SWilliam.Krier@Sun.COM 	id = (ndr_hdid_t *)&param->user_handle;
70411337SWilliam.Krier@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) {
70511337SWilliam.Krier@Sun.COM 		status = NT_STATUS_INVALID_HANDLE;
70611337SWilliam.Krier@Sun.COM 		goto QueryUserInfoError;
70711337SWilliam.Krier@Sun.COM 	}
70811337SWilliam.Krier@Sun.COM 
70911337SWilliam.Krier@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
71011337SWilliam.Krier@Sun.COM 
71111337SWilliam.Krier@Sun.COM 	if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) {
71211337SWilliam.Krier@Sun.COM 		status = NT_STATUS_ACCESS_DENIED;
71311337SWilliam.Krier@Sun.COM 		goto QueryUserInfoError;
71411337SWilliam.Krier@Sun.COM 	}
71511337SWilliam.Krier@Sun.COM 
71611337SWilliam.Krier@Sun.COM 	if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) {
71711337SWilliam.Krier@Sun.COM 		status = NT_STATUS_ACCESS_DENIED;
71811337SWilliam.Krier@Sun.COM 		goto QueryUserInfoError;
71911337SWilliam.Krier@Sun.COM 	}
72011337SWilliam.Krier@Sun.COM 
72111337SWilliam.Krier@Sun.COM 	if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) {
72211337SWilliam.Krier@Sun.COM 		status = NT_STATUS_ACCESS_DENIED;
72311337SWilliam.Krier@Sun.COM 		goto QueryUserInfoError;
72411337SWilliam.Krier@Sun.COM 	}
72511337SWilliam.Krier@Sun.COM 
72611337SWilliam.Krier@Sun.COM 	if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) {
72711337SWilliam.Krier@Sun.COM 		status = NT_STATUS_ACCESS_DENIED;
72811337SWilliam.Krier@Sun.COM 		goto QueryUserInfoError;
72911337SWilliam.Krier@Sun.COM 	}
73011337SWilliam.Krier@Sun.COM 
73111337SWilliam.Krier@Sun.COM 	all_info = &param->ru.info21;
73211337SWilliam.Krier@Sun.COM 	bzero(all_info, sizeof (struct samr_QueryUserInfo21));
73311337SWilliam.Krier@Sun.COM 
73411337SWilliam.Krier@Sun.COM 	all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID;
73511337SWilliam.Krier@Sun.COM 
73611337SWilliam.Krier@Sun.COM 	(void) NDR_MSTRING(mxa, account.a_name,
73711337SWilliam.Krier@Sun.COM 	    (ndr_mstring_t *)&all_info->UserName);
73811337SWilliam.Krier@Sun.COM 	all_info->UserId = data->kd_rid;
73911337SWilliam.Krier@Sun.COM 
74011337SWilliam.Krier@Sun.COM 	all_info->LmOwfPassword.length = 16;
74111337SWilliam.Krier@Sun.COM 	all_info->LmOwfPassword.maxlen = 16;
74211337SWilliam.Krier@Sun.COM 	all_info->LmOwfPassword.buf = owf_buf;
74311337SWilliam.Krier@Sun.COM 	all_info->NtOwfPassword.length = 16;
74411337SWilliam.Krier@Sun.COM 	all_info->NtOwfPassword.maxlen = 16;
74511337SWilliam.Krier@Sun.COM 	all_info->NtOwfPassword.buf = owf_buf;
74611337SWilliam.Krier@Sun.COM 	all_info->LogonHours.units_per_week = SAMR_HOURS_PER_WEEK;
74711337SWilliam.Krier@Sun.COM 	all_info->LogonHours.hours = hour_buf;
74811337SWilliam.Krier@Sun.COM 
74911337SWilliam.Krier@Sun.COM 	param->address = 1;
75011337SWilliam.Krier@Sun.COM 	param->switch_index = SAMR_QUERY_USER_ALL_INFO;
75111337SWilliam.Krier@Sun.COM 	param->status = NT_STATUS_SUCCESS;
75211963SAfshin.Ardakani@Sun.COM 	smb_account_free(&account);
75311963SAfshin.Ardakani@Sun.COM 	smb_sid_free(sid);
75411337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
75511337SWilliam.Krier@Sun.COM 
75611337SWilliam.Krier@Sun.COM QueryUserInfoError:
75711963SAfshin.Ardakani@Sun.COM 	smb_sid_free(sid);
75811337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct samr_QueryUserInfo));
75911337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(status);
76011337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
76111337SWilliam.Krier@Sun.COM }
76211337SWilliam.Krier@Sun.COM 
76311337SWilliam.Krier@Sun.COM /*
76411337SWilliam.Krier@Sun.COM  * samr_s_QueryUserGroups
76511337SWilliam.Krier@Sun.COM  *
76611337SWilliam.Krier@Sun.COM  * Request the list of groups of which a user is a member.
76711337SWilliam.Krier@Sun.COM  * The user is identified from the handle, which contains an
76811337SWilliam.Krier@Sun.COM  * rid in the discriminator field. Note that this is a local user.
76911337SWilliam.Krier@Sun.COM  */
77011337SWilliam.Krier@Sun.COM static int
samr_s_QueryUserGroups(void * arg,ndr_xa_t * mxa)77111337SWilliam.Krier@Sun.COM samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa)
77211337SWilliam.Krier@Sun.COM {
77311337SWilliam.Krier@Sun.COM 	struct samr_QueryUserGroups *param = arg;
77411337SWilliam.Krier@Sun.COM 	struct samr_UserGroupInfo *info;
77511337SWilliam.Krier@Sun.COM 	struct samr_UserGroups *group;
77611337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->user_handle;
77711337SWilliam.Krier@Sun.COM 	ndr_handle_t *hd;
77811337SWilliam.Krier@Sun.COM 	samr_keydata_t *data;
77911337SWilliam.Krier@Sun.COM 	smb_sid_t *user_sid = NULL;
78011337SWilliam.Krier@Sun.COM 	smb_group_t grp;
78111337SWilliam.Krier@Sun.COM 	smb_giter_t gi;
78211337SWilliam.Krier@Sun.COM 	smb_domain_t di;
78311337SWilliam.Krier@Sun.COM 	uint32_t status;
78411337SWilliam.Krier@Sun.COM 	int size;
78511337SWilliam.Krier@Sun.COM 	int ngrp_max;
78611337SWilliam.Krier@Sun.COM 
78711337SWilliam.Krier@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) {
78811337SWilliam.Krier@Sun.COM 		status = NT_STATUS_ACCESS_DENIED;
78911337SWilliam.Krier@Sun.COM 		goto query_error;
79011337SWilliam.Krier@Sun.COM 	}
79111337SWilliam.Krier@Sun.COM 
79211337SWilliam.Krier@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
79311337SWilliam.Krier@Sun.COM 	switch (data->kd_type) {
79411337SWilliam.Krier@Sun.COM 	case SMB_DOMAIN_BUILTIN:
79511337SWilliam.Krier@Sun.COM 	case SMB_DOMAIN_LOCAL:
79611337SWilliam.Krier@Sun.COM 		if (!smb_domain_lookup_type(data->kd_type, &di)) {
79711337SWilliam.Krier@Sun.COM 			status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
79811337SWilliam.Krier@Sun.COM 			goto query_error;
79911337SWilliam.Krier@Sun.COM 		}
80011337SWilliam.Krier@Sun.COM 		break;
80111337SWilliam.Krier@Sun.COM 	default:
80211337SWilliam.Krier@Sun.COM 		status = NT_STATUS_INVALID_HANDLE;
80311337SWilliam.Krier@Sun.COM 		goto query_error;
80411337SWilliam.Krier@Sun.COM 	}
80511337SWilliam.Krier@Sun.COM 
80611337SWilliam.Krier@Sun.COM 	user_sid = smb_sid_splice(di.di_binsid, data->kd_rid);
80711337SWilliam.Krier@Sun.COM 	if (user_sid == NULL) {
80811337SWilliam.Krier@Sun.COM 		status = NT_STATUS_NO_MEMORY;
80911337SWilliam.Krier@Sun.COM 		goto query_error;
81011337SWilliam.Krier@Sun.COM 	}
81111337SWilliam.Krier@Sun.COM 
81211337SWilliam.Krier@Sun.COM 	info = NDR_NEW(mxa, struct samr_UserGroupInfo);
81311337SWilliam.Krier@Sun.COM 	if (info == NULL) {
81411337SWilliam.Krier@Sun.COM 		status = NT_STATUS_NO_MEMORY;
81511337SWilliam.Krier@Sun.COM 		goto query_error;
81611337SWilliam.Krier@Sun.COM 	}
81711337SWilliam.Krier@Sun.COM 	bzero(info, sizeof (struct samr_UserGroupInfo));
81811337SWilliam.Krier@Sun.COM 
81911337SWilliam.Krier@Sun.COM 	size = 32 * 1024;
82011337SWilliam.Krier@Sun.COM 	info->groups = NDR_MALLOC(mxa, size);
82111337SWilliam.Krier@Sun.COM 	if (info->groups == NULL) {
82211337SWilliam.Krier@Sun.COM 		status = NT_STATUS_NO_MEMORY;
82311337SWilliam.Krier@Sun.COM 		goto query_error;
82411337SWilliam.Krier@Sun.COM 	}
82511337SWilliam.Krier@Sun.COM 	ngrp_max = size / sizeof (struct samr_UserGroups);
82611337SWilliam.Krier@Sun.COM 
82711337SWilliam.Krier@Sun.COM 	if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
82811337SWilliam.Krier@Sun.COM 		status = NT_STATUS_INTERNAL_ERROR;
82911337SWilliam.Krier@Sun.COM 		goto query_error;
83011337SWilliam.Krier@Sun.COM 	}
83111337SWilliam.Krier@Sun.COM 
83211337SWilliam.Krier@Sun.COM 	info->n_entry = 0;
83311337SWilliam.Krier@Sun.COM 	group = info->groups;
83411337SWilliam.Krier@Sun.COM 	while ((info->n_entry < ngrp_max) &&
83511337SWilliam.Krier@Sun.COM 	    (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS)) {
83611337SWilliam.Krier@Sun.COM 		if (smb_lgrp_is_member(&grp, user_sid)) {
83711337SWilliam.Krier@Sun.COM 			group->rid = grp.sg_rid;
83811337SWilliam.Krier@Sun.COM 			group->attr = grp.sg_attr;
83911337SWilliam.Krier@Sun.COM 			group++;
84011337SWilliam.Krier@Sun.COM 			info->n_entry++;
84111337SWilliam.Krier@Sun.COM 		}
84211337SWilliam.Krier@Sun.COM 		smb_lgrp_free(&grp);
84311337SWilliam.Krier@Sun.COM 	}
84411337SWilliam.Krier@Sun.COM 	smb_lgrp_iterclose(&gi);
84511337SWilliam.Krier@Sun.COM 
84611337SWilliam.Krier@Sun.COM 	free(user_sid);
84711337SWilliam.Krier@Sun.COM 	param->info = info;
84811337SWilliam.Krier@Sun.COM 	param->status = NT_STATUS_SUCCESS;
84911337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
85011337SWilliam.Krier@Sun.COM 
85111337SWilliam.Krier@Sun.COM query_error:
85211337SWilliam.Krier@Sun.COM 	free(user_sid);
85311337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct samr_QueryUserGroups));
85411337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(status);
85511337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
85611337SWilliam.Krier@Sun.COM }
85711337SWilliam.Krier@Sun.COM 
85811337SWilliam.Krier@Sun.COM /*
85911337SWilliam.Krier@Sun.COM  * samr_s_OpenGroup
86011337SWilliam.Krier@Sun.COM  *
86111337SWilliam.Krier@Sun.COM  * This is a request to open a group within the specified domain in the
86211337SWilliam.Krier@Sun.COM  * local SAM database. The caller must supply a valid domain handle,
86311337SWilliam.Krier@Sun.COM  * obtained via a successful domain open request. The group is
86411337SWilliam.Krier@Sun.COM  * specified by the rid in the request. If this is a local RID it
86511337SWilliam.Krier@Sun.COM  * should already be encoded with type information.
86611337SWilliam.Krier@Sun.COM  *
86711337SWilliam.Krier@Sun.COM  * We return a handle to be used to access information about this group.
86811337SWilliam.Krier@Sun.COM  */
86911337SWilliam.Krier@Sun.COM static int
samr_s_OpenGroup(void * arg,ndr_xa_t * mxa)87011337SWilliam.Krier@Sun.COM samr_s_OpenGroup(void *arg, ndr_xa_t *mxa)
87111337SWilliam.Krier@Sun.COM {
87211337SWilliam.Krier@Sun.COM 	struct samr_OpenGroup *param = arg;
87311337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
87411337SWilliam.Krier@Sun.COM 	ndr_handle_t *hd;
87511337SWilliam.Krier@Sun.COM 	samr_keydata_t *data;
87611337SWilliam.Krier@Sun.COM 
87711337SWilliam.Krier@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
87811337SWilliam.Krier@Sun.COM 		bzero(&param->group_handle, sizeof (samr_handle_t));
87911337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
88011337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
88111337SWilliam.Krier@Sun.COM 	}
88211337SWilliam.Krier@Sun.COM 
88311337SWilliam.Krier@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
88411337SWilliam.Krier@Sun.COM 	id = samr_hdalloc(mxa, SAMR_KEY_GROUP, data->kd_type, param->rid);
88511337SWilliam.Krier@Sun.COM 
88611337SWilliam.Krier@Sun.COM 	if (id) {
88711337SWilliam.Krier@Sun.COM 		bcopy(id, &param->group_handle, sizeof (samr_handle_t));
88811337SWilliam.Krier@Sun.COM 		param->status = 0;
88911337SWilliam.Krier@Sun.COM 	} else {
89011337SWilliam.Krier@Sun.COM 		bzero(&param->group_handle, sizeof (samr_handle_t));
89111337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
89211337SWilliam.Krier@Sun.COM 	}
89311337SWilliam.Krier@Sun.COM 
89411337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
89511337SWilliam.Krier@Sun.COM }
89611337SWilliam.Krier@Sun.COM 
89711337SWilliam.Krier@Sun.COM /*
89812065SKeyur.Desai@Sun.COM  * samr_s_AddAliasMember
89912065SKeyur.Desai@Sun.COM  *
90012065SKeyur.Desai@Sun.COM  * Add a member to a local SAM group.
90112065SKeyur.Desai@Sun.COM  * The caller must supply a valid group handle.
90212065SKeyur.Desai@Sun.COM  * The member is specified by the sid in the request.
90312065SKeyur.Desai@Sun.COM  */
90412065SKeyur.Desai@Sun.COM static int
samr_s_AddAliasMember(void * arg,ndr_xa_t * mxa)90512065SKeyur.Desai@Sun.COM samr_s_AddAliasMember(void *arg, ndr_xa_t *mxa)
90612065SKeyur.Desai@Sun.COM {
90712065SKeyur.Desai@Sun.COM 	struct samr_AddAliasMember *param = arg;
90812065SKeyur.Desai@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
90912065SKeyur.Desai@Sun.COM 	ndr_handle_t *hd;
91012065SKeyur.Desai@Sun.COM 	samr_keydata_t *data;
91112065SKeyur.Desai@Sun.COM 	smb_group_t grp;
91212065SKeyur.Desai@Sun.COM 	uint32_t rc;
91312065SKeyur.Desai@Sun.COM 	uint32_t status = NT_STATUS_SUCCESS;
91412065SKeyur.Desai@Sun.COM 
91512065SKeyur.Desai@Sun.COM 	if (param->sid == NULL) {
91612065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_AddAliasMember));
91712065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
91812065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
91912065SKeyur.Desai@Sun.COM 	}
92012065SKeyur.Desai@Sun.COM 
92112065SKeyur.Desai@Sun.COM 	if (!ndr_is_admin(mxa)) {
92212065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_AddAliasMember));
92312065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
92412065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
92512065SKeyur.Desai@Sun.COM 	}
92612065SKeyur.Desai@Sun.COM 
92712065SKeyur.Desai@Sun.COM 
92812065SKeyur.Desai@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
92912065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_AddAliasMember));
93012065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
93112065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
93212065SKeyur.Desai@Sun.COM 	}
93312065SKeyur.Desai@Sun.COM 
93412065SKeyur.Desai@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
93512065SKeyur.Desai@Sun.COM 	rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp);
93612065SKeyur.Desai@Sun.COM 	if (rc != SMB_LGRP_SUCCESS) {
93712065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_AddAliasMember));
93812065SKeyur.Desai@Sun.COM 		status = smb_lgrp_err_to_ntstatus(rc);
93912065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(status);
94012065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
94112065SKeyur.Desai@Sun.COM 	}
94212065SKeyur.Desai@Sun.COM 
94312065SKeyur.Desai@Sun.COM 	rc = smb_lgrp_add_member(grp.sg_name,
94412065SKeyur.Desai@Sun.COM 	    (smb_sid_t *)param->sid, SidTypeUser);
94512065SKeyur.Desai@Sun.COM 	if (rc != SMB_LGRP_SUCCESS) {
94612065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_AddAliasMember));
94712065SKeyur.Desai@Sun.COM 		status = smb_lgrp_err_to_ntstatus(rc);
94812065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(status);
94912065SKeyur.Desai@Sun.COM 	}
95012065SKeyur.Desai@Sun.COM 	smb_lgrp_free(&grp);
95112065SKeyur.Desai@Sun.COM 
95212065SKeyur.Desai@Sun.COM 	param->status = status;
95312065SKeyur.Desai@Sun.COM 	return (NDR_DRC_OK);
95412065SKeyur.Desai@Sun.COM }
95512065SKeyur.Desai@Sun.COM 
95612065SKeyur.Desai@Sun.COM /*
95712065SKeyur.Desai@Sun.COM  * samr_s_DeleteAliasMember
95812065SKeyur.Desai@Sun.COM  *
95912065SKeyur.Desai@Sun.COM  * Delete a member from a local SAM group.
96012065SKeyur.Desai@Sun.COM  * The caller must supply a valid group handle.
96112065SKeyur.Desai@Sun.COM  * The member is specified by the sid in the request.
96212065SKeyur.Desai@Sun.COM  */
96312065SKeyur.Desai@Sun.COM static int
samr_s_DeleteAliasMember(void * arg,ndr_xa_t * mxa)96412065SKeyur.Desai@Sun.COM samr_s_DeleteAliasMember(void *arg, ndr_xa_t *mxa)
96512065SKeyur.Desai@Sun.COM {
96612065SKeyur.Desai@Sun.COM 	struct samr_DeleteAliasMember *param = arg;
96712065SKeyur.Desai@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
96812065SKeyur.Desai@Sun.COM 	ndr_handle_t *hd;
96912065SKeyur.Desai@Sun.COM 	samr_keydata_t *data;
97012065SKeyur.Desai@Sun.COM 	smb_group_t grp;
97112065SKeyur.Desai@Sun.COM 	uint32_t rc;
97212065SKeyur.Desai@Sun.COM 	uint32_t status = NT_STATUS_SUCCESS;
97312065SKeyur.Desai@Sun.COM 
97412065SKeyur.Desai@Sun.COM 	if (param->sid == NULL) {
97512065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_DeleteAliasMember));
97612065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
97712065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
97812065SKeyur.Desai@Sun.COM 	}
97912065SKeyur.Desai@Sun.COM 
98012065SKeyur.Desai@Sun.COM 	if (!ndr_is_admin(mxa)) {
98112065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_DeleteAliasMember));
98212065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
98312065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
98412065SKeyur.Desai@Sun.COM 	}
98512065SKeyur.Desai@Sun.COM 
98612065SKeyur.Desai@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
98712065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_DeleteAliasMember));
98812065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
98912065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
99012065SKeyur.Desai@Sun.COM 	}
99112065SKeyur.Desai@Sun.COM 
99212065SKeyur.Desai@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
99312065SKeyur.Desai@Sun.COM 	rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp);
99412065SKeyur.Desai@Sun.COM 	if (rc != SMB_LGRP_SUCCESS) {
99512065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_DeleteAliasMember));
99612065SKeyur.Desai@Sun.COM 		status = smb_lgrp_err_to_ntstatus(rc);
99712065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(status);
99812065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
99912065SKeyur.Desai@Sun.COM 	}
100012065SKeyur.Desai@Sun.COM 
100112065SKeyur.Desai@Sun.COM 	rc = smb_lgrp_del_member(grp.sg_name,
100212065SKeyur.Desai@Sun.COM 	    (smb_sid_t *)param->sid, SidTypeUser);
100312065SKeyur.Desai@Sun.COM 	if (rc != SMB_LGRP_SUCCESS) {
100412065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_DeleteAliasMember));
100512065SKeyur.Desai@Sun.COM 		status = smb_lgrp_err_to_ntstatus(rc);
100612065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(status);
100712065SKeyur.Desai@Sun.COM 	}
100812065SKeyur.Desai@Sun.COM 	smb_lgrp_free(&grp);
100912065SKeyur.Desai@Sun.COM 
101012065SKeyur.Desai@Sun.COM 	param->status = status;
101112065SKeyur.Desai@Sun.COM 	return (NDR_DRC_OK);
101212065SKeyur.Desai@Sun.COM }
101312065SKeyur.Desai@Sun.COM 
101412065SKeyur.Desai@Sun.COM /*
101512065SKeyur.Desai@Sun.COM  * samr_s_ListAliasMembers
101612065SKeyur.Desai@Sun.COM  *
101712065SKeyur.Desai@Sun.COM  * List members from a local SAM group.
101812065SKeyur.Desai@Sun.COM  * The caller must supply a valid group handle.
101912065SKeyur.Desai@Sun.COM  * A list of user SIDs in the specified group is returned to the caller.
102012065SKeyur.Desai@Sun.COM  */
102112065SKeyur.Desai@Sun.COM static int
samr_s_ListAliasMembers(void * arg,ndr_xa_t * mxa)102212065SKeyur.Desai@Sun.COM samr_s_ListAliasMembers(void *arg, ndr_xa_t *mxa)
102312065SKeyur.Desai@Sun.COM {
102412065SKeyur.Desai@Sun.COM 	struct samr_ListAliasMembers *param = arg;
102512065SKeyur.Desai@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
102612065SKeyur.Desai@Sun.COM 	ndr_handle_t *hd;
102712065SKeyur.Desai@Sun.COM 	samr_keydata_t *data;
102812065SKeyur.Desai@Sun.COM 	smb_group_t grp;
102912065SKeyur.Desai@Sun.COM 	smb_gsid_t *members;
103012065SKeyur.Desai@Sun.COM 	struct samr_SidInfo info;
103112065SKeyur.Desai@Sun.COM 	struct samr_SidList *user;
103212065SKeyur.Desai@Sun.COM 	uint32_t num = 0, size;
103312065SKeyur.Desai@Sun.COM 	int i;
103412065SKeyur.Desai@Sun.COM 	uint32_t rc;
103512065SKeyur.Desai@Sun.COM 	uint32_t status = NT_STATUS_SUCCESS;
103612065SKeyur.Desai@Sun.COM 
103712065SKeyur.Desai@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
103812065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_ListAliasMembers));
103912065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
104012065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
104112065SKeyur.Desai@Sun.COM 	}
104212065SKeyur.Desai@Sun.COM 
104312065SKeyur.Desai@Sun.COM 	bzero(&info, sizeof (struct samr_SidInfo));
104412065SKeyur.Desai@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
104512065SKeyur.Desai@Sun.COM 	rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp);
104612065SKeyur.Desai@Sun.COM 	if (rc != SMB_LGRP_SUCCESS) {
104712065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_ListAliasMembers));
104812065SKeyur.Desai@Sun.COM 		status = smb_lgrp_err_to_ntstatus(rc);
104912065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(status);
105012065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
105112065SKeyur.Desai@Sun.COM 	}
105212065SKeyur.Desai@Sun.COM 
105312065SKeyur.Desai@Sun.COM 	num = grp.sg_nmembers;
105412065SKeyur.Desai@Sun.COM 	members = grp.sg_members;
105512065SKeyur.Desai@Sun.COM 	size = num * sizeof (struct samr_SidList);
105612065SKeyur.Desai@Sun.COM 	info.sidlist = NDR_MALLOC(mxa, size);
105712065SKeyur.Desai@Sun.COM 	if (info.sidlist == NULL) {
105812065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_ListAliasMembers));
105912065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
106012065SKeyur.Desai@Sun.COM 		smb_lgrp_free(&grp);
106112065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
106212065SKeyur.Desai@Sun.COM 	}
106312065SKeyur.Desai@Sun.COM 
106412065SKeyur.Desai@Sun.COM 	info.n_entry = num;
106512065SKeyur.Desai@Sun.COM 	user = info.sidlist;
106612065SKeyur.Desai@Sun.COM 	for (i = 0; i < num; i++) {
106712065SKeyur.Desai@Sun.COM 		user->sid = (struct samr_sid *)NDR_SIDDUP(mxa,
106812065SKeyur.Desai@Sun.COM 		    members[i].gs_sid);
106912065SKeyur.Desai@Sun.COM 		if (user->sid == NULL) {
107012065SKeyur.Desai@Sun.COM 			bzero(param, sizeof (struct samr_ListAliasMembers));
107112065SKeyur.Desai@Sun.COM 			param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
107212065SKeyur.Desai@Sun.COM 			smb_lgrp_free(&grp);
107312065SKeyur.Desai@Sun.COM 			return (NDR_DRC_OK);
107412065SKeyur.Desai@Sun.COM 		}
107512065SKeyur.Desai@Sun.COM 		user++;
107612065SKeyur.Desai@Sun.COM 	}
107712065SKeyur.Desai@Sun.COM 	smb_lgrp_free(&grp);
107812065SKeyur.Desai@Sun.COM 
107912065SKeyur.Desai@Sun.COM 	param->info = info;
108012065SKeyur.Desai@Sun.COM 	param->status = status;
108112065SKeyur.Desai@Sun.COM 	return (NDR_DRC_OK);
108212065SKeyur.Desai@Sun.COM }
108312065SKeyur.Desai@Sun.COM 
108412065SKeyur.Desai@Sun.COM /*
1085*12890SJoyce.McIntosh@Sun.COM  * samr_s_Connect2
108611337SWilliam.Krier@Sun.COM  *
108711337SWilliam.Krier@Sun.COM  * This is a request to connect to the local SAM database.
108811337SWilliam.Krier@Sun.COM  * We don't support any form of update request and our database doesn't
108911337SWilliam.Krier@Sun.COM  * contain any private information, so there is little point in doing
109011337SWilliam.Krier@Sun.COM  * any access access checking here.
109111337SWilliam.Krier@Sun.COM  *
109211337SWilliam.Krier@Sun.COM  * Return a handle for use with subsequent SAM requests.
109311337SWilliam.Krier@Sun.COM  */
109411337SWilliam.Krier@Sun.COM static int
samr_s_Connect2(void * arg,ndr_xa_t * mxa)1095*12890SJoyce.McIntosh@Sun.COM samr_s_Connect2(void *arg, ndr_xa_t *mxa)
109611337SWilliam.Krier@Sun.COM {
1097*12890SJoyce.McIntosh@Sun.COM 	struct samr_Connect2 *param = arg;
109811337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id;
109911337SWilliam.Krier@Sun.COM 
110011337SWilliam.Krier@Sun.COM 	id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
110111337SWilliam.Krier@Sun.COM 	if (id) {
110211337SWilliam.Krier@Sun.COM 		bcopy(id, &param->handle, sizeof (samr_handle_t));
110311337SWilliam.Krier@Sun.COM 		param->status = 0;
110411337SWilliam.Krier@Sun.COM 	} else {
110511337SWilliam.Krier@Sun.COM 		bzero(&param->handle, sizeof (samr_handle_t));
110611337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
110711337SWilliam.Krier@Sun.COM 	}
110811337SWilliam.Krier@Sun.COM 
110911337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
111011337SWilliam.Krier@Sun.COM }
111111337SWilliam.Krier@Sun.COM 
111211337SWilliam.Krier@Sun.COM /*
111311337SWilliam.Krier@Sun.COM  * samr_s_GetUserPwInfo
111411337SWilliam.Krier@Sun.COM  *
111511447Samw@Sun.COM  * Request for a user's password policy information.
111611337SWilliam.Krier@Sun.COM  */
111711337SWilliam.Krier@Sun.COM /*ARGSUSED*/
111811337SWilliam.Krier@Sun.COM static int
samr_s_GetUserPwInfo(void * arg,ndr_xa_t * mxa)111911337SWilliam.Krier@Sun.COM samr_s_GetUserPwInfo(void *arg, ndr_xa_t *mxa)
112011337SWilliam.Krier@Sun.COM {
112111447Samw@Sun.COM 	static samr_password_info_t	pwinfo;
112211447Samw@Sun.COM 	struct samr_GetUserPwInfo	*param = arg;
112311337SWilliam.Krier@Sun.COM 
112411447Samw@Sun.COM 	param->pwinfo = &pwinfo;
112511447Samw@Sun.COM 	param->status = NT_STATUS_SUCCESS;
112611337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
112711337SWilliam.Krier@Sun.COM }
112811337SWilliam.Krier@Sun.COM 
112911337SWilliam.Krier@Sun.COM /*
113011337SWilliam.Krier@Sun.COM  * samr_s_CreateUser
113111337SWilliam.Krier@Sun.COM  */
113211337SWilliam.Krier@Sun.COM /*ARGSUSED*/
113311337SWilliam.Krier@Sun.COM static int
samr_s_CreateUser(void * arg,ndr_xa_t * mxa)113411337SWilliam.Krier@Sun.COM samr_s_CreateUser(void *arg, ndr_xa_t *mxa)
113511337SWilliam.Krier@Sun.COM {
113611337SWilliam.Krier@Sun.COM 	struct samr_CreateUser *param = arg;
113711337SWilliam.Krier@Sun.COM 
113811337SWilliam.Krier@Sun.COM 	bzero(&param->user_handle, sizeof (samr_handle_t));
113911337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
114011337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
114111337SWilliam.Krier@Sun.COM }
114211337SWilliam.Krier@Sun.COM 
114311337SWilliam.Krier@Sun.COM /*
114411337SWilliam.Krier@Sun.COM  * samr_s_ChangeUserPasswd
114511337SWilliam.Krier@Sun.COM  */
114611337SWilliam.Krier@Sun.COM /*ARGSUSED*/
114711337SWilliam.Krier@Sun.COM static int
samr_s_ChangeUserPasswd(void * arg,ndr_xa_t * mxa)114811337SWilliam.Krier@Sun.COM samr_s_ChangeUserPasswd(void *arg, ndr_xa_t *mxa)
114911337SWilliam.Krier@Sun.COM {
115011337SWilliam.Krier@Sun.COM 	struct samr_ChangeUserPasswd *param = arg;
115111337SWilliam.Krier@Sun.COM 
115211337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct samr_ChangeUserPasswd));
115311337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
115411337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
115511337SWilliam.Krier@Sun.COM }
115611337SWilliam.Krier@Sun.COM 
115711337SWilliam.Krier@Sun.COM /*
115811337SWilliam.Krier@Sun.COM  * samr_s_GetDomainPwInfo
115911447Samw@Sun.COM  *
116011447Samw@Sun.COM  * Request for the domain password policy information.
116111337SWilliam.Krier@Sun.COM  */
116211337SWilliam.Krier@Sun.COM /*ARGSUSED*/
116311337SWilliam.Krier@Sun.COM static int
samr_s_GetDomainPwInfo(void * arg,ndr_xa_t * mxa)116411337SWilliam.Krier@Sun.COM samr_s_GetDomainPwInfo(void *arg, ndr_xa_t *mxa)
116511337SWilliam.Krier@Sun.COM {
116611447Samw@Sun.COM 	static samr_password_info_t	pwinfo;
116711447Samw@Sun.COM 	struct samr_GetDomainPwInfo	*param = arg;
116811337SWilliam.Krier@Sun.COM 
116911447Samw@Sun.COM 	param->pwinfo = &pwinfo;
117011447Samw@Sun.COM 	param->status = NT_STATUS_SUCCESS;
117111337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
117211337SWilliam.Krier@Sun.COM }
117311337SWilliam.Krier@Sun.COM 
117411337SWilliam.Krier@Sun.COM /*
117511337SWilliam.Krier@Sun.COM  * samr_s_SetUserInfo
117611337SWilliam.Krier@Sun.COM  */
117711337SWilliam.Krier@Sun.COM /*ARGSUSED*/
117811337SWilliam.Krier@Sun.COM static int
samr_s_SetUserInfo(void * arg,ndr_xa_t * mxa)117911337SWilliam.Krier@Sun.COM samr_s_SetUserInfo(void *arg, ndr_xa_t *mxa)
118011337SWilliam.Krier@Sun.COM {
118111337SWilliam.Krier@Sun.COM 	struct samr_SetUserInfo *param = arg;
118211337SWilliam.Krier@Sun.COM 
118311337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct samr_SetUserInfo));
118411337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
118511337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
118611337SWilliam.Krier@Sun.COM }
118711337SWilliam.Krier@Sun.COM 
118811337SWilliam.Krier@Sun.COM /*
118911337SWilliam.Krier@Sun.COM  * samr_s_QueryDispInfo
119011337SWilliam.Krier@Sun.COM  *
119111337SWilliam.Krier@Sun.COM  * This function currently return local users' information only.
119211337SWilliam.Krier@Sun.COM  * This RPC is called repeatedly until all the users info are
119311337SWilliam.Krier@Sun.COM  * retrieved.
119411337SWilliam.Krier@Sun.COM  *
119511337SWilliam.Krier@Sun.COM  * The total count and the returned count are returned as total size
119611337SWilliam.Krier@Sun.COM  * and returned size.  The client doesn't seem to care.
119711337SWilliam.Krier@Sun.COM  */
119811337SWilliam.Krier@Sun.COM static int
samr_s_QueryDispInfo(void * arg,ndr_xa_t * mxa)119911337SWilliam.Krier@Sun.COM samr_s_QueryDispInfo(void *arg, ndr_xa_t *mxa)
120011337SWilliam.Krier@Sun.COM {
120111337SWilliam.Krier@Sun.COM 	struct samr_QueryDispInfo *param = arg;
120211337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->domain_handle;
120311337SWilliam.Krier@Sun.COM 	ndr_handle_t *hd;
120411337SWilliam.Krier@Sun.COM 	samr_keydata_t *data;
120511337SWilliam.Krier@Sun.COM 	DWORD status = NT_STATUS_SUCCESS;
120611337SWilliam.Krier@Sun.COM 	struct user_acct_info *user;
120711337SWilliam.Krier@Sun.COM 	smb_pwditer_t pwi;
120811337SWilliam.Krier@Sun.COM 	smb_luser_t *uinfo;
120911337SWilliam.Krier@Sun.COM 	int num_users;
121011337SWilliam.Krier@Sun.COM 	int start_idx;
121111337SWilliam.Krier@Sun.COM 	int max_retcnt, retcnt;
121211337SWilliam.Krier@Sun.COM 	int skip;
121311337SWilliam.Krier@Sun.COM 
121411337SWilliam.Krier@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
121511337SWilliam.Krier@Sun.COM 		status = NT_STATUS_INVALID_HANDLE;
121611337SWilliam.Krier@Sun.COM 		goto error;
121711337SWilliam.Krier@Sun.COM 	}
121811337SWilliam.Krier@Sun.COM 
121911337SWilliam.Krier@Sun.COM 	if (!SAMR_VALID_DISPLEVEL(param->level)) {
122011337SWilliam.Krier@Sun.COM 		status = NT_STATUS_INVALID_INFO_CLASS;
122111337SWilliam.Krier@Sun.COM 		goto error;
122211337SWilliam.Krier@Sun.COM 	}
122311337SWilliam.Krier@Sun.COM 
122411337SWilliam.Krier@Sun.COM 	if (!SAMR_SUPPORTED_DISPLEVEL(param->level)) {
122511337SWilliam.Krier@Sun.COM 		status = NT_STATUS_NOT_IMPLEMENTED;
122611337SWilliam.Krier@Sun.COM 		goto error;
122711337SWilliam.Krier@Sun.COM 	}
122811337SWilliam.Krier@Sun.COM 
122911337SWilliam.Krier@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
123011337SWilliam.Krier@Sun.COM 
123111337SWilliam.Krier@Sun.COM 	switch (data->kd_type) {
123211337SWilliam.Krier@Sun.COM 	case SMB_DOMAIN_BUILTIN:
123311337SWilliam.Krier@Sun.COM 		goto no_info;
123411337SWilliam.Krier@Sun.COM 
123511337SWilliam.Krier@Sun.COM 	case SMB_DOMAIN_LOCAL:
123611337SWilliam.Krier@Sun.COM 		num_users = smb_sam_usr_cnt();
123711337SWilliam.Krier@Sun.COM 		start_idx = param->start_idx;
123811337SWilliam.Krier@Sun.COM 		if ((num_users == 0) || (start_idx >= num_users))
123911337SWilliam.Krier@Sun.COM 			goto no_info;
124011337SWilliam.Krier@Sun.COM 
124111337SWilliam.Krier@Sun.COM 		max_retcnt = num_users - start_idx;
124211337SWilliam.Krier@Sun.COM 		if (max_retcnt > param->max_entries)
124311337SWilliam.Krier@Sun.COM 			max_retcnt = param->max_entries;
124411337SWilliam.Krier@Sun.COM 		param->users.acct = NDR_MALLOC(mxa,
124511337SWilliam.Krier@Sun.COM 		    max_retcnt * sizeof (struct user_acct_info));
124611337SWilliam.Krier@Sun.COM 		user = param->users.acct;
124711337SWilliam.Krier@Sun.COM 		if (user == NULL) {
124811337SWilliam.Krier@Sun.COM 			status = NT_STATUS_NO_MEMORY;
124911337SWilliam.Krier@Sun.COM 			goto error;
125011337SWilliam.Krier@Sun.COM 		}
125111337SWilliam.Krier@Sun.COM 		bzero(user, max_retcnt * sizeof (struct user_acct_info));
125211337SWilliam.Krier@Sun.COM 
125311337SWilliam.Krier@Sun.COM 		if (smb_pwd_iteropen(&pwi) != SMB_PWE_SUCCESS)
125411337SWilliam.Krier@Sun.COM 			goto no_info;
125511337SWilliam.Krier@Sun.COM 
125611337SWilliam.Krier@Sun.COM 		skip = retcnt = 0;
125711337SWilliam.Krier@Sun.COM 		while ((uinfo = smb_pwd_iterate(&pwi)) != NULL) {
125811337SWilliam.Krier@Sun.COM 			if (skip++ < start_idx)
125911337SWilliam.Krier@Sun.COM 				continue;
126011337SWilliam.Krier@Sun.COM 
126111337SWilliam.Krier@Sun.COM 			if (retcnt++ >= max_retcnt)
126211337SWilliam.Krier@Sun.COM 				break;
126311337SWilliam.Krier@Sun.COM 
126411337SWilliam.Krier@Sun.COM 			assert(uinfo->su_name != NULL);
126511337SWilliam.Krier@Sun.COM 
126611337SWilliam.Krier@Sun.COM 			user->index = start_idx + retcnt;
126711337SWilliam.Krier@Sun.COM 			user->rid = uinfo->su_rid;
126811337SWilliam.Krier@Sun.COM 			user->ctrl = ACF_NORMUSER | ACF_PWDNOEXP;
126911337SWilliam.Krier@Sun.COM 			if (uinfo->su_ctrl & SMB_PWF_DISABLE)
127011337SWilliam.Krier@Sun.COM 				user->ctrl |= ACF_DISABLED;
127111337SWilliam.Krier@Sun.COM 			if (NDR_MSTRING(mxa, uinfo->su_name,
127211337SWilliam.Krier@Sun.COM 			    (ndr_mstring_t *)&user->name) == -1) {
127311337SWilliam.Krier@Sun.COM 				smb_pwd_iterclose(&pwi);
127411337SWilliam.Krier@Sun.COM 				status = NT_STATUS_NO_MEMORY;
127511337SWilliam.Krier@Sun.COM 				goto error;
127611337SWilliam.Krier@Sun.COM 			}
127711337SWilliam.Krier@Sun.COM 			(void) NDR_MSTRING(mxa, uinfo->su_fullname,
127811337SWilliam.Krier@Sun.COM 			    (ndr_mstring_t *)&user->fullname);
127911337SWilliam.Krier@Sun.COM 			(void) NDR_MSTRING(mxa, uinfo->su_desc,
128011337SWilliam.Krier@Sun.COM 			    (ndr_mstring_t *)&user->desc);
128111337SWilliam.Krier@Sun.COM 			user++;
128211337SWilliam.Krier@Sun.COM 		}
128311337SWilliam.Krier@Sun.COM 		smb_pwd_iterclose(&pwi);
128411337SWilliam.Krier@Sun.COM 
128511337SWilliam.Krier@Sun.COM 		if (retcnt >= max_retcnt) {
128611337SWilliam.Krier@Sun.COM 			retcnt = max_retcnt;
128711337SWilliam.Krier@Sun.COM 			param->status = status;
128811337SWilliam.Krier@Sun.COM 		} else {
128912508Samw@Sun.COM 			param->status = NT_STATUS_MORE_ENTRIES;
129011337SWilliam.Krier@Sun.COM 		}
129111337SWilliam.Krier@Sun.COM 
129211337SWilliam.Krier@Sun.COM 		param->users.total_size = num_users;
129311337SWilliam.Krier@Sun.COM 		param->users.returned_size = retcnt;
129411337SWilliam.Krier@Sun.COM 		param->users.switch_value = param->level;
129511337SWilliam.Krier@Sun.COM 		param->users.count = retcnt;
129611337SWilliam.Krier@Sun.COM 
129711337SWilliam.Krier@Sun.COM 		break;
129811337SWilliam.Krier@Sun.COM 
129911337SWilliam.Krier@Sun.COM 	default:
130011337SWilliam.Krier@Sun.COM 		status = NT_STATUS_INVALID_HANDLE;
130111337SWilliam.Krier@Sun.COM 		goto error;
130211337SWilliam.Krier@Sun.COM 	}
130311337SWilliam.Krier@Sun.COM 
130411337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
130511337SWilliam.Krier@Sun.COM 
130611337SWilliam.Krier@Sun.COM no_info:
130711337SWilliam.Krier@Sun.COM 	param->users.total_size = 0;
130811337SWilliam.Krier@Sun.COM 	param->users.returned_size = 0;
130911337SWilliam.Krier@Sun.COM 	param->users.switch_value = param->level;
131011337SWilliam.Krier@Sun.COM 	param->users.count = 0;
131111337SWilliam.Krier@Sun.COM 	param->users.acct = NULL;
131211337SWilliam.Krier@Sun.COM 	param->status = status;
131311337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
131411337SWilliam.Krier@Sun.COM 
131511337SWilliam.Krier@Sun.COM error:
131611337SWilliam.Krier@Sun.COM 	bzero(param, sizeof (struct samr_QueryDispInfo));
131711337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(status);
131811337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
131911337SWilliam.Krier@Sun.COM }
132011337SWilliam.Krier@Sun.COM 
132111337SWilliam.Krier@Sun.COM /*
132211337SWilliam.Krier@Sun.COM  * samr_s_EnumDomainGroups
132311337SWilliam.Krier@Sun.COM  *
132411337SWilliam.Krier@Sun.COM  *
132511337SWilliam.Krier@Sun.COM  * This function is supposed to return local group information.
132611337SWilliam.Krier@Sun.COM  * As we don't support local users, this function dosen't send
132711337SWilliam.Krier@Sun.COM  * back any information.
132811337SWilliam.Krier@Sun.COM  *
132911337SWilliam.Krier@Sun.COM  * Added template that returns information for a domain group as None.
133011337SWilliam.Krier@Sun.COM  * All information is hard-coded from packet captures.
133111337SWilliam.Krier@Sun.COM  */
133211337SWilliam.Krier@Sun.COM static int
samr_s_EnumDomainGroups(void * arg,ndr_xa_t * mxa)133311337SWilliam.Krier@Sun.COM samr_s_EnumDomainGroups(void *arg, ndr_xa_t *mxa)
133411337SWilliam.Krier@Sun.COM {
133511337SWilliam.Krier@Sun.COM 	struct samr_EnumDomainGroups *param = arg;
133611337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->domain_handle;
133711337SWilliam.Krier@Sun.COM 	DWORD status = NT_STATUS_SUCCESS;
133811337SWilliam.Krier@Sun.COM 
133911337SWilliam.Krier@Sun.COM 	if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL)
134011337SWilliam.Krier@Sun.COM 		status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
134111337SWilliam.Krier@Sun.COM 
134211337SWilliam.Krier@Sun.COM 	param->total_size = 0;
134311337SWilliam.Krier@Sun.COM 	param->returned_size = 0;
134411337SWilliam.Krier@Sun.COM 	param->switch_value = 3;
134511337SWilliam.Krier@Sun.COM 	param->count = 0;
134611337SWilliam.Krier@Sun.COM 	param->groups = 0;
134711337SWilliam.Krier@Sun.COM 	param->status = status;
134811337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
134911337SWilliam.Krier@Sun.COM 
135011337SWilliam.Krier@Sun.COM #ifdef SAMR_SUPPORT_GROUPS
135111337SWilliam.Krier@Sun.COM 	if ((desc->discrim != SAMR_LOCAL_DOMAIN) || (param->start_idx != 0)) {
135211337SWilliam.Krier@Sun.COM 		param->total_size = 0;
135311337SWilliam.Krier@Sun.COM 		param->returned_size = 0;
135411337SWilliam.Krier@Sun.COM 		param->switch_value = 3;
135511337SWilliam.Krier@Sun.COM 		param->count = 0;
135611337SWilliam.Krier@Sun.COM 		param->groups = 0;
135711337SWilliam.Krier@Sun.COM 	} else {
135811337SWilliam.Krier@Sun.COM 		param->total_size = 64;
135911337SWilliam.Krier@Sun.COM 		param->returned_size = 64;
136011337SWilliam.Krier@Sun.COM 		param->switch_value = 3;
136111337SWilliam.Krier@Sun.COM 		param->count = 1;
136211337SWilliam.Krier@Sun.COM 		param->groups = (struct group_disp_info *)NDR_MALLOC(
136311337SWilliam.Krier@Sun.COM 		    mxa, sizeof (struct group_disp_info));
136411337SWilliam.Krier@Sun.COM 
136511337SWilliam.Krier@Sun.COM 		param->groups->count = 1;
136611337SWilliam.Krier@Sun.COM 		param->groups->acct[0].index = 1;
136711337SWilliam.Krier@Sun.COM 		param->groups->acct[0].rid = 513;
136811337SWilliam.Krier@Sun.COM 		param->groups->acct[0].ctrl = 0x7;
136911337SWilliam.Krier@Sun.COM 		(void) NDR_MSTRING(mxa, "None",
137011337SWilliam.Krier@Sun.COM 		    (ndr_mstring_t *)&param->groups->acct[0].name);
137111337SWilliam.Krier@Sun.COM 
137211337SWilliam.Krier@Sun.COM 		(void) NDR_MSTRING(mxa, "Ordinary users",
137311337SWilliam.Krier@Sun.COM 		    (ndr_mstring_t *)&param->groups->acct[0].desc);
137411337SWilliam.Krier@Sun.COM 	}
137511337SWilliam.Krier@Sun.COM 
137611337SWilliam.Krier@Sun.COM 	param->status = NT_STATUS_SUCCESS;
137711337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
137811337SWilliam.Krier@Sun.COM #endif
137911337SWilliam.Krier@Sun.COM }
138011337SWilliam.Krier@Sun.COM 
138111337SWilliam.Krier@Sun.COM /*
138211337SWilliam.Krier@Sun.COM  * samr_s_OpenAlias
138311337SWilliam.Krier@Sun.COM  *
138411337SWilliam.Krier@Sun.COM  * Lookup for requested alias, if it exists return a handle
138511337SWilliam.Krier@Sun.COM  * for that alias. The alias domain sid should match with
138611337SWilliam.Krier@Sun.COM  * the passed domain handle.
138711337SWilliam.Krier@Sun.COM  */
138811337SWilliam.Krier@Sun.COM static int
samr_s_OpenAlias(void * arg,ndr_xa_t * mxa)138911337SWilliam.Krier@Sun.COM samr_s_OpenAlias(void *arg, ndr_xa_t *mxa)
139011337SWilliam.Krier@Sun.COM {
139111337SWilliam.Krier@Sun.COM 	struct samr_OpenAlias *param = arg;
139211447Samw@Sun.COM 	ndr_hdid_t	*id = (ndr_hdid_t *)&param->domain_handle;
139311447Samw@Sun.COM 	ndr_handle_t	*hd;
139411447Samw@Sun.COM 	samr_keydata_t	*data;
139511963SAfshin.Ardakani@Sun.COM 	smb_domain_type_t gd_type;
139611447Samw@Sun.COM 	smb_sid_t	*sid;
139711447Samw@Sun.COM 	smb_wka_t	*wka;
139811447Samw@Sun.COM 	char		sidstr[SMB_SID_STRSZ];
139911447Samw@Sun.COM 	uint32_t	rid;
140011447Samw@Sun.COM 	uint32_t	status;
140111447Samw@Sun.COM 	int		rc;
140211337SWilliam.Krier@Sun.COM 
140311337SWilliam.Krier@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
140411337SWilliam.Krier@Sun.COM 		status = NT_STATUS_INVALID_HANDLE;
140511337SWilliam.Krier@Sun.COM 		goto open_alias_err;
140611337SWilliam.Krier@Sun.COM 	}
140711337SWilliam.Krier@Sun.COM 
140812065SKeyur.Desai@Sun.COM 	if ((param->access_mask & SAMR_ALIAS_ACCESS_ALL_ACCESS) == 0) {
140911337SWilliam.Krier@Sun.COM 		status = NT_STATUS_ACCESS_DENIED;
141011337SWilliam.Krier@Sun.COM 		goto open_alias_err;
141111337SWilliam.Krier@Sun.COM 	}
141211337SWilliam.Krier@Sun.COM 
141311337SWilliam.Krier@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
141411963SAfshin.Ardakani@Sun.COM 	gd_type = (smb_domain_type_t)data->kd_type;
141511447Samw@Sun.COM 	rid = param->rid;
141611447Samw@Sun.COM 
141711447Samw@Sun.COM 	switch (gd_type) {
141811963SAfshin.Ardakani@Sun.COM 	case SMB_DOMAIN_BUILTIN:
141911447Samw@Sun.COM 		(void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d",
142011447Samw@Sun.COM 		    NT_BUILTIN_DOMAIN_SIDSTR, rid);
142111447Samw@Sun.COM 		if ((sid = smb_sid_fromstr(sidstr)) == NULL) {
142211447Samw@Sun.COM 			status = NT_STATUS_NO_SUCH_ALIAS;
142311447Samw@Sun.COM 			goto open_alias_err;
142411447Samw@Sun.COM 		}
142511447Samw@Sun.COM 
142611447Samw@Sun.COM 		wka = smb_wka_lookup_sid(sid);
142711447Samw@Sun.COM 		smb_sid_free(sid);
142811447Samw@Sun.COM 
142911447Samw@Sun.COM 		if (wka == NULL) {
143011447Samw@Sun.COM 			status = NT_STATUS_NO_SUCH_ALIAS;
143111447Samw@Sun.COM 			goto open_alias_err;
143211447Samw@Sun.COM 		}
143311447Samw@Sun.COM 		break;
143411447Samw@Sun.COM 
143511963SAfshin.Ardakani@Sun.COM 	case SMB_DOMAIN_LOCAL:
143611447Samw@Sun.COM 		rc = smb_lgrp_getbyrid(rid, gd_type, NULL);
143711447Samw@Sun.COM 		if (rc != SMB_LGRP_SUCCESS) {
143811447Samw@Sun.COM 			status = NT_STATUS_NO_SUCH_ALIAS;
143911447Samw@Sun.COM 			goto open_alias_err;
144011447Samw@Sun.COM 		}
144111447Samw@Sun.COM 		break;
144211447Samw@Sun.COM 
144311447Samw@Sun.COM 	default:
144411337SWilliam.Krier@Sun.COM 		status = NT_STATUS_NO_SUCH_ALIAS;
144511337SWilliam.Krier@Sun.COM 		goto open_alias_err;
144611337SWilliam.Krier@Sun.COM 	}
144711337SWilliam.Krier@Sun.COM 
144811337SWilliam.Krier@Sun.COM 	id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, data->kd_type, param->rid);
144911337SWilliam.Krier@Sun.COM 	if (id) {
145011337SWilliam.Krier@Sun.COM 		bcopy(id, &param->alias_handle, sizeof (samr_handle_t));
145111337SWilliam.Krier@Sun.COM 		param->status = NT_STATUS_SUCCESS;
145211337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
145311337SWilliam.Krier@Sun.COM 	}
145411337SWilliam.Krier@Sun.COM 
145511337SWilliam.Krier@Sun.COM 	status = NT_STATUS_NO_MEMORY;
145611337SWilliam.Krier@Sun.COM 
145711337SWilliam.Krier@Sun.COM open_alias_err:
145811337SWilliam.Krier@Sun.COM 	bzero(&param->alias_handle, sizeof (samr_handle_t));
145911337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(status);
146011337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
146111337SWilliam.Krier@Sun.COM }
146211337SWilliam.Krier@Sun.COM 
146311337SWilliam.Krier@Sun.COM /*
146411337SWilliam.Krier@Sun.COM  * samr_s_CreateDomainAlias
146511337SWilliam.Krier@Sun.COM  *
146612065SKeyur.Desai@Sun.COM  * Create a local group in the security accounts manager (SAM) database.
146712065SKeyur.Desai@Sun.COM  * A local SAM group can only be added if a Solaris group already exists
146812065SKeyur.Desai@Sun.COM  * with the same name.  On success, a valid group handle is returned.
146912065SKeyur.Desai@Sun.COM  *
147012065SKeyur.Desai@Sun.COM  * The caller must have administrator rights to execute this function.
147111337SWilliam.Krier@Sun.COM  */
147211337SWilliam.Krier@Sun.COM static int
samr_s_CreateDomainAlias(void * arg,ndr_xa_t * mxa)147311337SWilliam.Krier@Sun.COM samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa)
147411337SWilliam.Krier@Sun.COM {
147511337SWilliam.Krier@Sun.COM 	struct samr_CreateDomainAlias *param = arg;
147611337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
147712065SKeyur.Desai@Sun.COM 	uint32_t status = NT_STATUS_SUCCESS;
147812065SKeyur.Desai@Sun.COM 	smb_group_t grp;
147912065SKeyur.Desai@Sun.COM 	uint32_t rc;
148012065SKeyur.Desai@Sun.COM 	char *gname;
148111337SWilliam.Krier@Sun.COM 
148212065SKeyur.Desai@Sun.COM 	if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) != NULL) {
148311337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_CreateDomainAlias));
148411337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
148511337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
148611337SWilliam.Krier@Sun.COM 	}
148711337SWilliam.Krier@Sun.COM 
148812065SKeyur.Desai@Sun.COM 	gname = (char *)param->alias_name.str;
148912065SKeyur.Desai@Sun.COM 	if (gname == NULL) {
149012065SKeyur.Desai@Sun.COM 		bzero(&param->alias_handle, sizeof (samr_handle_t));
149112065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
149212065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
149312065SKeyur.Desai@Sun.COM 	}
149411337SWilliam.Krier@Sun.COM 
149512065SKeyur.Desai@Sun.COM 	if ((!ndr_is_admin(mxa)) ||
149612065SKeyur.Desai@Sun.COM 	    ((param->access_mask & SAMR_ALIAS_ACCESS_WRITE_ACCOUNT) == 0)) {
149712065SKeyur.Desai@Sun.COM 		bzero(&param->alias_handle, sizeof (samr_handle_t));
149812065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
149912065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
150012065SKeyur.Desai@Sun.COM 	}
150111337SWilliam.Krier@Sun.COM 
150212065SKeyur.Desai@Sun.COM 	rc = smb_lgrp_add(gname, "");
150312065SKeyur.Desai@Sun.COM 	if (rc != SMB_LGRP_SUCCESS) {
150412065SKeyur.Desai@Sun.COM 		bzero(&param->alias_handle, sizeof (samr_handle_t));
150512065SKeyur.Desai@Sun.COM 		status = smb_lgrp_err_to_ntstatus(rc);
150612065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(status);
150712065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
150811337SWilliam.Krier@Sun.COM 	}
150911337SWilliam.Krier@Sun.COM 
151012065SKeyur.Desai@Sun.COM 	rc = smb_lgrp_getbyname((char *)gname, &grp);
151112065SKeyur.Desai@Sun.COM 	if (rc != SMB_LGRP_SUCCESS) {
151212065SKeyur.Desai@Sun.COM 		bzero(&param->alias_handle, sizeof (samr_handle_t));
151312065SKeyur.Desai@Sun.COM 		status = smb_lgrp_err_to_ntstatus(rc);
151412065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(status);
151512065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
151612065SKeyur.Desai@Sun.COM 	}
151711337SWilliam.Krier@Sun.COM 
151812065SKeyur.Desai@Sun.COM 	id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, SMB_DOMAIN_LOCAL, grp.sg_rid);
151912065SKeyur.Desai@Sun.COM 	smb_lgrp_free(&grp);
152012065SKeyur.Desai@Sun.COM 	if (id) {
152112065SKeyur.Desai@Sun.COM 		bcopy(id, &param->alias_handle, sizeof (samr_handle_t));
152212065SKeyur.Desai@Sun.COM 		param->status = status;
152312065SKeyur.Desai@Sun.COM 	} else {
152412065SKeyur.Desai@Sun.COM 		bzero(&param->alias_handle, sizeof (samr_handle_t));
152512065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
152612065SKeyur.Desai@Sun.COM 	}
152711337SWilliam.Krier@Sun.COM 
152811337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
152911337SWilliam.Krier@Sun.COM }
153011337SWilliam.Krier@Sun.COM 
153111337SWilliam.Krier@Sun.COM /*
153211337SWilliam.Krier@Sun.COM  * samr_s_SetAliasInfo
153311337SWilliam.Krier@Sun.COM  *
153411337SWilliam.Krier@Sun.COM  * Similar to NetLocalGroupSetInfo.
153511337SWilliam.Krier@Sun.COM  */
153611337SWilliam.Krier@Sun.COM static int
samr_s_SetAliasInfo(void * arg,ndr_xa_t * mxa)153711337SWilliam.Krier@Sun.COM samr_s_SetAliasInfo(void *arg, ndr_xa_t *mxa)
153811337SWilliam.Krier@Sun.COM {
153911337SWilliam.Krier@Sun.COM 	struct samr_SetAliasInfo *param = arg;
154011337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
154111337SWilliam.Krier@Sun.COM 	DWORD status = NT_STATUS_SUCCESS;
154211337SWilliam.Krier@Sun.COM 
154311337SWilliam.Krier@Sun.COM 	if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL)
154411337SWilliam.Krier@Sun.COM 		status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
154511337SWilliam.Krier@Sun.COM 
154611337SWilliam.Krier@Sun.COM 	param->status = status;
154711337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
154811337SWilliam.Krier@Sun.COM }
154911337SWilliam.Krier@Sun.COM 
155011337SWilliam.Krier@Sun.COM /*
155111337SWilliam.Krier@Sun.COM  * samr_s_QueryAliasInfo
155211337SWilliam.Krier@Sun.COM  *
155311337SWilliam.Krier@Sun.COM  * Retrieves information about the specified local group account
155411337SWilliam.Krier@Sun.COM  * by given handle.
155511337SWilliam.Krier@Sun.COM  */
155611337SWilliam.Krier@Sun.COM static int
samr_s_QueryAliasInfo(void * arg,ndr_xa_t * mxa)155711337SWilliam.Krier@Sun.COM samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa)
155811337SWilliam.Krier@Sun.COM {
155911337SWilliam.Krier@Sun.COM 	struct samr_QueryAliasInfo *param = arg;
156011447Samw@Sun.COM 	ndr_hdid_t	*id = (ndr_hdid_t *)&param->alias_handle;
156111447Samw@Sun.COM 	ndr_handle_t	*hd;
156211447Samw@Sun.COM 	samr_keydata_t	*data;
156311447Samw@Sun.COM 	smb_group_t	grp;
156411963SAfshin.Ardakani@Sun.COM 	smb_domain_type_t gd_type;
156511447Samw@Sun.COM 	smb_sid_t	*sid;
156611447Samw@Sun.COM 	smb_wka_t	*wka;
156711447Samw@Sun.COM 	char		sidstr[SMB_SID_STRSZ];
156811447Samw@Sun.COM 	char		*name;
156911447Samw@Sun.COM 	char		*desc;
157011447Samw@Sun.COM 	uint32_t	rid;
157111447Samw@Sun.COM 	uint32_t	status;
157211447Samw@Sun.COM 	int		rc;
157311337SWilliam.Krier@Sun.COM 
157411337SWilliam.Krier@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
157511337SWilliam.Krier@Sun.COM 		status = NT_STATUS_INVALID_HANDLE;
157611337SWilliam.Krier@Sun.COM 		goto query_alias_err;
157711337SWilliam.Krier@Sun.COM 	}
157811337SWilliam.Krier@Sun.COM 
157911337SWilliam.Krier@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
158011963SAfshin.Ardakani@Sun.COM 	gd_type = (smb_domain_type_t)data->kd_type;
158111447Samw@Sun.COM 	rid = data->kd_rid;
158211447Samw@Sun.COM 
158311447Samw@Sun.COM 	switch (gd_type) {
158411963SAfshin.Ardakani@Sun.COM 	case SMB_DOMAIN_BUILTIN:
158511447Samw@Sun.COM 		(void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d",
158611447Samw@Sun.COM 		    NT_BUILTIN_DOMAIN_SIDSTR, rid);
158711447Samw@Sun.COM 		if ((sid = smb_sid_fromstr(sidstr)) == NULL) {
158811447Samw@Sun.COM 			status = NT_STATUS_NO_SUCH_ALIAS;
158911447Samw@Sun.COM 			goto query_alias_err;
159011447Samw@Sun.COM 		}
159111447Samw@Sun.COM 
159211447Samw@Sun.COM 		wka = smb_wka_lookup_sid(sid);
159311447Samw@Sun.COM 		smb_sid_free(sid);
159411447Samw@Sun.COM 
159511447Samw@Sun.COM 		if (wka == NULL) {
159611447Samw@Sun.COM 			status = NT_STATUS_NO_SUCH_ALIAS;
159711447Samw@Sun.COM 			goto query_alias_err;
159811447Samw@Sun.COM 		}
159911447Samw@Sun.COM 
160011447Samw@Sun.COM 		name = wka->wka_name;
160111447Samw@Sun.COM 		desc = (wka->wka_desc != NULL) ? wka->wka_desc : "";
160211447Samw@Sun.COM 		break;
160311447Samw@Sun.COM 
160411963SAfshin.Ardakani@Sun.COM 	case SMB_DOMAIN_LOCAL:
160511447Samw@Sun.COM 		rc = smb_lgrp_getbyrid(rid, gd_type, &grp);
160611447Samw@Sun.COM 		if (rc != SMB_LGRP_SUCCESS) {
160711447Samw@Sun.COM 			status = NT_STATUS_NO_SUCH_ALIAS;
160811447Samw@Sun.COM 			goto query_alias_err;
160911447Samw@Sun.COM 		}
161011447Samw@Sun.COM 		name = grp.sg_name;
161111447Samw@Sun.COM 		desc = grp.sg_cmnt;
161211447Samw@Sun.COM 		break;
161311447Samw@Sun.COM 
161411447Samw@Sun.COM 	default:
161511337SWilliam.Krier@Sun.COM 		status = NT_STATUS_NO_SUCH_ALIAS;
161611337SWilliam.Krier@Sun.COM 		goto query_alias_err;
161711337SWilliam.Krier@Sun.COM 	}
161811337SWilliam.Krier@Sun.COM 
161911337SWilliam.Krier@Sun.COM 	switch (param->level) {
162011337SWilliam.Krier@Sun.COM 	case SAMR_QUERY_ALIAS_INFO_1:
162111337SWilliam.Krier@Sun.COM 		param->ru.info1.level = param->level;
162211447Samw@Sun.COM 		(void) NDR_MSTRING(mxa, name,
162311337SWilliam.Krier@Sun.COM 		    (ndr_mstring_t *)&param->ru.info1.name);
162411337SWilliam.Krier@Sun.COM 
162511447Samw@Sun.COM 		(void) NDR_MSTRING(mxa, desc,
162611337SWilliam.Krier@Sun.COM 		    (ndr_mstring_t *)&param->ru.info1.desc);
162711337SWilliam.Krier@Sun.COM 
162811337SWilliam.Krier@Sun.COM 		param->ru.info1.unknown = 1;
162911337SWilliam.Krier@Sun.COM 		break;
163011337SWilliam.Krier@Sun.COM 
163111337SWilliam.Krier@Sun.COM 	case SAMR_QUERY_ALIAS_INFO_3:
163211337SWilliam.Krier@Sun.COM 		param->ru.info3.level = param->level;
163311447Samw@Sun.COM 		(void) NDR_MSTRING(mxa, desc,
163411337SWilliam.Krier@Sun.COM 		    (ndr_mstring_t *)&param->ru.info3.desc);
163511337SWilliam.Krier@Sun.COM 		break;
163611337SWilliam.Krier@Sun.COM 
163711337SWilliam.Krier@Sun.COM 	default:
163811963SAfshin.Ardakani@Sun.COM 		if (gd_type == SMB_DOMAIN_LOCAL)
163911447Samw@Sun.COM 			smb_lgrp_free(&grp);
164011337SWilliam.Krier@Sun.COM 		status = NT_STATUS_INVALID_INFO_CLASS;
164111337SWilliam.Krier@Sun.COM 		goto query_alias_err;
164211337SWilliam.Krier@Sun.COM 	};
164311337SWilliam.Krier@Sun.COM 
164411963SAfshin.Ardakani@Sun.COM 	if (gd_type == SMB_DOMAIN_LOCAL)
164511447Samw@Sun.COM 		smb_lgrp_free(&grp);
164611337SWilliam.Krier@Sun.COM 	param->address = (DWORD)(uintptr_t)&param->ru;
164711337SWilliam.Krier@Sun.COM 	param->status = 0;
164811337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
164911337SWilliam.Krier@Sun.COM 
165011337SWilliam.Krier@Sun.COM query_alias_err:
165111337SWilliam.Krier@Sun.COM 	param->status = NT_SC_ERROR(status);
165211337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
165311337SWilliam.Krier@Sun.COM }
165411337SWilliam.Krier@Sun.COM 
165511337SWilliam.Krier@Sun.COM /*
165611337SWilliam.Krier@Sun.COM  * samr_s_DeleteDomainAlias
165711337SWilliam.Krier@Sun.COM  *
165812065SKeyur.Desai@Sun.COM  * Deletes a local group in the security database, which is the
165912065SKeyur.Desai@Sun.COM  * security accounts manager (SAM). A valid group handle is returned
166012065SKeyur.Desai@Sun.COM  * to the caller upon success.
166111337SWilliam.Krier@Sun.COM  *
166212065SKeyur.Desai@Sun.COM  * The caller must have administrator rights to execute this function.
166311337SWilliam.Krier@Sun.COM  */
166411337SWilliam.Krier@Sun.COM static int
samr_s_DeleteDomainAlias(void * arg,ndr_xa_t * mxa)166511337SWilliam.Krier@Sun.COM samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa)
166611337SWilliam.Krier@Sun.COM {
166711337SWilliam.Krier@Sun.COM 	struct samr_DeleteDomainAlias *param = arg;
166811337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
166912065SKeyur.Desai@Sun.COM 	ndr_handle_t	*hd;
167012065SKeyur.Desai@Sun.COM 	smb_group_t grp;
167112065SKeyur.Desai@Sun.COM 	samr_keydata_t	*data;
167212065SKeyur.Desai@Sun.COM 	smb_domain_type_t	gd_type;
167312065SKeyur.Desai@Sun.COM 	uint32_t	rid;
167412065SKeyur.Desai@Sun.COM 	uint32_t	rc;
167512065SKeyur.Desai@Sun.COM 	uint32_t	status = NT_STATUS_SUCCESS;
167611337SWilliam.Krier@Sun.COM 
167712065SKeyur.Desai@Sun.COM 	if (!ndr_is_admin(mxa)) {
167812065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_DeleteDomainAlias));
167912065SKeyur.Desai@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
168012065SKeyur.Desai@Sun.COM 		return (NDR_DRC_OK);
168112065SKeyur.Desai@Sun.COM 	}
168212065SKeyur.Desai@Sun.COM 
168312065SKeyur.Desai@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
168411337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_DeleteDomainAlias));
168511337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
168611337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
168711337SWilliam.Krier@Sun.COM 	}
168811337SWilliam.Krier@Sun.COM 
168912065SKeyur.Desai@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
169012065SKeyur.Desai@Sun.COM 	gd_type = (smb_domain_type_t)data->kd_type;
169112065SKeyur.Desai@Sun.COM 	rid = data->kd_rid;
169212065SKeyur.Desai@Sun.COM 
169312065SKeyur.Desai@Sun.COM 	switch (gd_type) {
169412065SKeyur.Desai@Sun.COM 	case SMB_DOMAIN_BUILTIN:
169512065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_DeleteDomainAlias));
169612065SKeyur.Desai@Sun.COM 		status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED);
169712065SKeyur.Desai@Sun.COM 		break;
169811337SWilliam.Krier@Sun.COM 
169912065SKeyur.Desai@Sun.COM 	case SMB_DOMAIN_LOCAL:
170012065SKeyur.Desai@Sun.COM 		rc = smb_lgrp_getbyrid(rid, gd_type, &grp);
170112065SKeyur.Desai@Sun.COM 		if (rc != SMB_LGRP_SUCCESS) {
170212065SKeyur.Desai@Sun.COM 			bzero(param, sizeof (struct samr_DeleteDomainAlias));
170312065SKeyur.Desai@Sun.COM 			status = smb_lgrp_err_to_ntstatus(rc);
170412065SKeyur.Desai@Sun.COM 			status = NT_SC_ERROR(status);
170512065SKeyur.Desai@Sun.COM 			break;
170612065SKeyur.Desai@Sun.COM 		}
170711337SWilliam.Krier@Sun.COM 
170812065SKeyur.Desai@Sun.COM 		rc = smb_lgrp_delete(grp.sg_name);
170912065SKeyur.Desai@Sun.COM 		if (rc != SMB_LGRP_SUCCESS) {
171012065SKeyur.Desai@Sun.COM 			bzero(param, sizeof (struct samr_DeleteDomainAlias));
171112065SKeyur.Desai@Sun.COM 			status = smb_lgrp_err_to_ntstatus(rc);
171212065SKeyur.Desai@Sun.COM 			status = NT_SC_ERROR(status);
171312065SKeyur.Desai@Sun.COM 		}
171412065SKeyur.Desai@Sun.COM 		smb_lgrp_free(&grp);
171512065SKeyur.Desai@Sun.COM 		break;
171612065SKeyur.Desai@Sun.COM 
171712065SKeyur.Desai@Sun.COM 	default:
171812065SKeyur.Desai@Sun.COM 		bzero(param, sizeof (struct samr_DeleteDomainAlias));
171912065SKeyur.Desai@Sun.COM 		status = NT_SC_ERROR(NT_STATUS_NO_SUCH_ALIAS);
172011337SWilliam.Krier@Sun.COM 	}
172111337SWilliam.Krier@Sun.COM 
172212065SKeyur.Desai@Sun.COM 	param->status = status;
172311337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
172411337SWilliam.Krier@Sun.COM }
172511337SWilliam.Krier@Sun.COM 
172611337SWilliam.Krier@Sun.COM /*
172711337SWilliam.Krier@Sun.COM  * samr_s_EnumDomainAliases
172811337SWilliam.Krier@Sun.COM  *
172911337SWilliam.Krier@Sun.COM  * This function sends back a list which contains all local groups' name.
173011337SWilliam.Krier@Sun.COM  */
173111337SWilliam.Krier@Sun.COM static int
samr_s_EnumDomainAliases(void * arg,ndr_xa_t * mxa)173211337SWilliam.Krier@Sun.COM samr_s_EnumDomainAliases(void *arg, ndr_xa_t *mxa)
173311337SWilliam.Krier@Sun.COM {
173411337SWilliam.Krier@Sun.COM 	struct samr_EnumDomainAliases *param = arg;
173511337SWilliam.Krier@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->domain_handle;
173611337SWilliam.Krier@Sun.COM 	ndr_handle_t *hd;
173711337SWilliam.Krier@Sun.COM 	samr_keydata_t *data;
173811337SWilliam.Krier@Sun.COM 	smb_group_t grp;
173911337SWilliam.Krier@Sun.COM 	smb_giter_t gi;
174011337SWilliam.Krier@Sun.COM 	int cnt, skip, i;
174111337SWilliam.Krier@Sun.COM 	struct name_rid *info;
174211337SWilliam.Krier@Sun.COM 
174311337SWilliam.Krier@Sun.COM 	if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
174411337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_EnumDomainAliases));
174511337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
174611337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
174711337SWilliam.Krier@Sun.COM 	}
174811337SWilliam.Krier@Sun.COM 
174911337SWilliam.Krier@Sun.COM 	data = (samr_keydata_t *)hd->nh_data;
175011337SWilliam.Krier@Sun.COM 
175111337SWilliam.Krier@Sun.COM 	cnt = smb_sam_grp_cnt(data->kd_type);
175211337SWilliam.Krier@Sun.COM 	if (cnt <= param->resume_handle) {
175311337SWilliam.Krier@Sun.COM 		param->aliases = (struct aliases_info *)NDR_MALLOC(mxa,
175411337SWilliam.Krier@Sun.COM 		    sizeof (struct aliases_info));
175511337SWilliam.Krier@Sun.COM 
175611337SWilliam.Krier@Sun.COM 		if (param->aliases == NULL) {
175711337SWilliam.Krier@Sun.COM 			bzero(param, sizeof (struct samr_EnumDomainAliases));
175811337SWilliam.Krier@Sun.COM 			param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
175911337SWilliam.Krier@Sun.COM 			return (NDR_DRC_OK);
176011337SWilliam.Krier@Sun.COM 		}
176111337SWilliam.Krier@Sun.COM 
176211337SWilliam.Krier@Sun.COM 		bzero(param->aliases, sizeof (struct aliases_info));
176311337SWilliam.Krier@Sun.COM 		param->out_resume = 0;
176411337SWilliam.Krier@Sun.COM 		param->entries = 0;
176511337SWilliam.Krier@Sun.COM 		param->status = NT_STATUS_SUCCESS;
176611337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
176711337SWilliam.Krier@Sun.COM 	}
176811337SWilliam.Krier@Sun.COM 
176911337SWilliam.Krier@Sun.COM 	cnt -= param->resume_handle;
177011337SWilliam.Krier@Sun.COM 	param->aliases = (struct aliases_info *)NDR_MALLOC(mxa,
177111337SWilliam.Krier@Sun.COM 	    sizeof (struct aliases_info) + (cnt-1) * sizeof (struct name_rid));
177211337SWilliam.Krier@Sun.COM 
177311337SWilliam.Krier@Sun.COM 	if (param->aliases == NULL) {
177411337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_EnumDomainAliases));
177511337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
177611337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
177711337SWilliam.Krier@Sun.COM 	}
177811337SWilliam.Krier@Sun.COM 
177911337SWilliam.Krier@Sun.COM 	if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
178011337SWilliam.Krier@Sun.COM 		bzero(param, sizeof (struct samr_EnumDomainAliases));
178111337SWilliam.Krier@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR);
178211337SWilliam.Krier@Sun.COM 		return (NDR_DRC_OK);
178311337SWilliam.Krier@Sun.COM 	}
178411337SWilliam.Krier@Sun.COM 
178511337SWilliam.Krier@Sun.COM 	skip = i = 0;
178611337SWilliam.Krier@Sun.COM 	info = param->aliases->info;
178711337SWilliam.Krier@Sun.COM 	while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) {
178811337SWilliam.Krier@Sun.COM 		if ((skip++ >= param->resume_handle) &&
178911337SWilliam.Krier@Sun.COM 		    (grp.sg_domain == data->kd_type) && (i++ < cnt)) {
179011337SWilliam.Krier@Sun.COM 			info->rid = grp.sg_rid;
179111337SWilliam.Krier@Sun.COM 			(void) NDR_MSTRING(mxa, grp.sg_name,
179211337SWilliam.Krier@Sun.COM 			    (ndr_mstring_t *)&info->name);
179311337SWilliam.Krier@Sun.COM 
179411337SWilliam.Krier@Sun.COM 			info++;
179511337SWilliam.Krier@Sun.COM 		}
179611337SWilliam.Krier@Sun.COM 		smb_lgrp_free(&grp);
179711337SWilliam.Krier@Sun.COM 	}
179811337SWilliam.Krier@Sun.COM 	smb_lgrp_iterclose(&gi);
179911337SWilliam.Krier@Sun.COM 
180011337SWilliam.Krier@Sun.COM 	param->aliases->count = i;
180111337SWilliam.Krier@Sun.COM 	param->aliases->address = i;
180211337SWilliam.Krier@Sun.COM 
180311337SWilliam.Krier@Sun.COM 	param->out_resume = i;
180411337SWilliam.Krier@Sun.COM 	param->entries = i;
180511337SWilliam.Krier@Sun.COM 	param->status = 0;
180611337SWilliam.Krier@Sun.COM 	return (NDR_DRC_OK);
180711337SWilliam.Krier@Sun.COM }
180811337SWilliam.Krier@Sun.COM 
180911337SWilliam.Krier@Sun.COM /*
1810*12890SJoyce.McIntosh@Sun.COM  * samr_s_Connect4
181111337SWilliam.Krier@Sun.COM  */
181211337SWilliam.Krier@Sun.COM static int
samr_s_Connect4(void * arg,ndr_xa_t * mxa)1813*12890SJoyce.McIntosh@Sun.COM samr_s_Connect4(void *arg, ndr_xa_t *mxa)
181411337SWilliam.Krier@Sun.COM {
1815*12890SJoyce.McIntosh@Sun.COM 	struct samr_Connect4	*param = arg;
181611447Samw@Sun.COM 	ndr_hdid_t		*id;
181711337SWilliam.Krier@Sun.COM 
181811447Samw@Sun.COM 	id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
181911447Samw@Sun.COM 	if (id) {
182011447Samw@Sun.COM 		bcopy(id, &param->handle, sizeof (samr_handle_t));
182111447Samw@Sun.COM 		param->status = 0;
182211447Samw@Sun.COM 	} else {
182311447Samw@Sun.COM 		bzero(&param->handle, sizeof (samr_handle_t));
182411447Samw@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
182511447Samw@Sun.COM 	}
182611447Samw@Sun.COM 
182711447Samw@Sun.COM 	return (NDR_DRC_OK);
182811337SWilliam.Krier@Sun.COM }
182911337SWilliam.Krier@Sun.COM 
183011337SWilliam.Krier@Sun.COM /*
1831*12890SJoyce.McIntosh@Sun.COM  * samr_s_Connect5
183211337SWilliam.Krier@Sun.COM  *
1833*12890SJoyce.McIntosh@Sun.COM  * This is the connect5 form of the connect request used by Windows XP.
183411337SWilliam.Krier@Sun.COM  * Returns an RPC fault for now.
183511337SWilliam.Krier@Sun.COM  */
183611337SWilliam.Krier@Sun.COM /*ARGSUSED*/
183711337SWilliam.Krier@Sun.COM static int
samr_s_Connect5(void * arg,ndr_xa_t * mxa)1838*12890SJoyce.McIntosh@Sun.COM samr_s_Connect5(void *arg, ndr_xa_t *mxa)
183911337SWilliam.Krier@Sun.COM {
1840*12890SJoyce.McIntosh@Sun.COM 	struct samr_Connect5 *param = arg;
184111337SWilliam.Krier@Sun.COM 
1842*12890SJoyce.McIntosh@Sun.COM 	bzero(param, sizeof (struct samr_Connect5));
184311337SWilliam.Krier@Sun.COM 	return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
184411337SWilliam.Krier@Sun.COM }
184511337SWilliam.Krier@Sun.COM 
184611337SWilliam.Krier@Sun.COM static ndr_stub_table_t samr_stub_table[] = {
1847*12890SJoyce.McIntosh@Sun.COM 	{ samr_s_Connect,		SAMR_OPNUM_Connect },
184811337SWilliam.Krier@Sun.COM 	{ samr_s_CloseHandle,		SAMR_OPNUM_CloseHandle },
184911337SWilliam.Krier@Sun.COM 	{ samr_s_LookupDomain,		SAMR_OPNUM_LookupDomain },
185011337SWilliam.Krier@Sun.COM 	{ samr_s_EnumLocalDomains,	SAMR_OPNUM_EnumLocalDomains },
185111337SWilliam.Krier@Sun.COM 	{ samr_s_OpenDomain,		SAMR_OPNUM_OpenDomain },
185211337SWilliam.Krier@Sun.COM 	{ samr_s_QueryDomainInfo,	SAMR_OPNUM_QueryDomainInfo },
185311447Samw@Sun.COM 	{ samr_s_QueryInfoDomain2,	SAMR_OPNUM_QueryInfoDomain2 },
185411337SWilliam.Krier@Sun.COM 	{ samr_s_LookupNames,		SAMR_OPNUM_LookupNames },
185511337SWilliam.Krier@Sun.COM 	{ samr_s_OpenUser,		SAMR_OPNUM_OpenUser },
185611337SWilliam.Krier@Sun.COM 	{ samr_s_DeleteUser,		SAMR_OPNUM_DeleteUser },
185711337SWilliam.Krier@Sun.COM 	{ samr_s_QueryUserInfo,		SAMR_OPNUM_QueryUserInfo },
185811337SWilliam.Krier@Sun.COM 	{ samr_s_QueryUserGroups,	SAMR_OPNUM_QueryUserGroups },
185911337SWilliam.Krier@Sun.COM 	{ samr_s_OpenGroup,		SAMR_OPNUM_OpenGroup },
1860*12890SJoyce.McIntosh@Sun.COM 	{ samr_s_Connect2,		SAMR_OPNUM_Connect2 },
186111337SWilliam.Krier@Sun.COM 	{ samr_s_GetUserPwInfo,		SAMR_OPNUM_GetUserPwInfo },
186211337SWilliam.Krier@Sun.COM 	{ samr_s_CreateUser,		SAMR_OPNUM_CreateUser },
186311337SWilliam.Krier@Sun.COM 	{ samr_s_ChangeUserPasswd,	SAMR_OPNUM_ChangeUserPasswd },
186411337SWilliam.Krier@Sun.COM 	{ samr_s_GetDomainPwInfo,	SAMR_OPNUM_GetDomainPwInfo },
186511337SWilliam.Krier@Sun.COM 	{ samr_s_SetUserInfo,		SAMR_OPNUM_SetUserInfo },
186611337SWilliam.Krier@Sun.COM 	{ samr_s_Connect4,		SAMR_OPNUM_Connect4 },
1867*12890SJoyce.McIntosh@Sun.COM 	{ samr_s_Connect5,		SAMR_OPNUM_Connect5 },
186811337SWilliam.Krier@Sun.COM 	{ samr_s_QueryDispInfo,		SAMR_OPNUM_QueryDispInfo },
186911337SWilliam.Krier@Sun.COM 	{ samr_s_OpenAlias,		SAMR_OPNUM_OpenAlias },
187011337SWilliam.Krier@Sun.COM 	{ samr_s_CreateDomainAlias,	SAMR_OPNUM_CreateDomainAlias },
187111337SWilliam.Krier@Sun.COM 	{ samr_s_SetAliasInfo,		SAMR_OPNUM_SetAliasInfo },
187211337SWilliam.Krier@Sun.COM 	{ samr_s_QueryAliasInfo,	SAMR_OPNUM_QueryAliasInfo },
187311337SWilliam.Krier@Sun.COM 	{ samr_s_DeleteDomainAlias,	SAMR_OPNUM_DeleteDomainAlias },
187411337SWilliam.Krier@Sun.COM 	{ samr_s_EnumDomainAliases,	SAMR_OPNUM_EnumDomainAliases },
187511337SWilliam.Krier@Sun.COM 	{ samr_s_EnumDomainGroups,	SAMR_OPNUM_EnumDomainGroups },
187612065SKeyur.Desai@Sun.COM 	{ samr_s_AddAliasMember,	SAMR_OPNUM_AddAliasMember },
187712065SKeyur.Desai@Sun.COM 	{ samr_s_DeleteAliasMember,	SAMR_OPNUM_DeleteAliasMember },
187812065SKeyur.Desai@Sun.COM 	{ samr_s_ListAliasMembers,	SAMR_OPNUM_ListAliasMembers },
187911337SWilliam.Krier@Sun.COM 	{0}
188011337SWilliam.Krier@Sun.COM };
188111337SWilliam.Krier@Sun.COM 
188211337SWilliam.Krier@Sun.COM /*
188311337SWilliam.Krier@Sun.COM  * There is a bug in the way that midl and the marshalling code handles
188411337SWilliam.Krier@Sun.COM  * unions so we need to fix some of the data offsets at runtime. The
188511337SWilliam.Krier@Sun.COM  * following macros and the fixup functions handle the corrections.
188611337SWilliam.Krier@Sun.COM  */
188711337SWilliam.Krier@Sun.COM 
188811337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfo_ru);
188911337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfoRes);
189011337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfo);
189111337SWilliam.Krier@Sun.COM 
189211337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(QueryUserInfo_result_u);
189311337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(QueryUserInfo_result);
189411337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryUserInfo);
189511337SWilliam.Krier@Sun.COM 
189611337SWilliam.Krier@Sun.COM void
fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo * val)189711337SWilliam.Krier@Sun.COM fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo *val)
189811337SWilliam.Krier@Sun.COM {
189911337SWilliam.Krier@Sun.COM 	unsigned short size1 = 0;
190011337SWilliam.Krier@Sun.COM 	unsigned short size2 = 0;
190111337SWilliam.Krier@Sun.COM 	unsigned short size3 = 0;
190211337SWilliam.Krier@Sun.COM 
190311337SWilliam.Krier@Sun.COM 	switch (val->level) {
190411337SWilliam.Krier@Sun.COM 		CASE_INFO_ENT(samr_QueryAliasInfo, 1);
190511337SWilliam.Krier@Sun.COM 		CASE_INFO_ENT(samr_QueryAliasInfo, 3);
190611337SWilliam.Krier@Sun.COM 
190711337SWilliam.Krier@Sun.COM 		default:
190811337SWilliam.Krier@Sun.COM 			return;
190911337SWilliam.Krier@Sun.COM 	};
191011337SWilliam.Krier@Sun.COM 
191111337SWilliam.Krier@Sun.COM 	size2 = size1 + (2 * sizeof (DWORD));
191211337SWilliam.Krier@Sun.COM 	size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
191311337SWilliam.Krier@Sun.COM 
191411337SWilliam.Krier@Sun.COM 	FIXUP_PDU_SIZE(samr_QueryAliasInfo_ru, size1);
191511337SWilliam.Krier@Sun.COM 	FIXUP_PDU_SIZE(samr_QueryAliasInfoRes, size2);
191611337SWilliam.Krier@Sun.COM 	FIXUP_PDU_SIZE(samr_QueryAliasInfo, size3);
191711337SWilliam.Krier@Sun.COM }
191811337SWilliam.Krier@Sun.COM 
191911337SWilliam.Krier@Sun.COM void
fixup_samr_QueryUserInfo(struct samr_QueryUserInfo * val)192011337SWilliam.Krier@Sun.COM fixup_samr_QueryUserInfo(struct samr_QueryUserInfo *val)
192111337SWilliam.Krier@Sun.COM {
192211337SWilliam.Krier@Sun.COM 	unsigned short size1 = 0;
192311337SWilliam.Krier@Sun.COM 	unsigned short size2 = 0;
192411337SWilliam.Krier@Sun.COM 	unsigned short size3 = 0;
192511337SWilliam.Krier@Sun.COM 
192611337SWilliam.Krier@Sun.COM 	switch (val->switch_index) {
192711337SWilliam.Krier@Sun.COM 		CASE_INFO_ENT(samr_QueryUserInfo, 1);
192811337SWilliam.Krier@Sun.COM 		CASE_INFO_ENT(samr_QueryUserInfo, 6);
192911337SWilliam.Krier@Sun.COM 		CASE_INFO_ENT(samr_QueryUserInfo, 7);
193011337SWilliam.Krier@Sun.COM 		CASE_INFO_ENT(samr_QueryUserInfo, 8);
193111337SWilliam.Krier@Sun.COM 		CASE_INFO_ENT(samr_QueryUserInfo, 9);
193211337SWilliam.Krier@Sun.COM 		CASE_INFO_ENT(samr_QueryUserInfo, 16);
193311337SWilliam.Krier@Sun.COM 		CASE_INFO_ENT(samr_QueryUserInfo, 21);
193411337SWilliam.Krier@Sun.COM 
193511337SWilliam.Krier@Sun.COM 		default:
193611337SWilliam.Krier@Sun.COM 			return;
193711337SWilliam.Krier@Sun.COM 	};
193811337SWilliam.Krier@Sun.COM 
193911337SWilliam.Krier@Sun.COM 	size2 = size1 + (2 * sizeof (DWORD));
194011337SWilliam.Krier@Sun.COM 	size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
194111337SWilliam.Krier@Sun.COM 
194211337SWilliam.Krier@Sun.COM 	FIXUP_PDU_SIZE(QueryUserInfo_result_u, size1);
194311337SWilliam.Krier@Sun.COM 	FIXUP_PDU_SIZE(QueryUserInfo_result, size2);
194411337SWilliam.Krier@Sun.COM 	FIXUP_PDU_SIZE(samr_QueryUserInfo, size3);
194511337SWilliam.Krier@Sun.COM }
194611337SWilliam.Krier@Sun.COM 
194711337SWilliam.Krier@Sun.COM /*
194811337SWilliam.Krier@Sun.COM  * As long as there is only one entry in the union, there is no need
194911337SWilliam.Krier@Sun.COM  * to patch anything.
195011337SWilliam.Krier@Sun.COM  */
195111337SWilliam.Krier@Sun.COM /*ARGSUSED*/
195211337SWilliam.Krier@Sun.COM void
fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo * val)195311337SWilliam.Krier@Sun.COM fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo *val)
195411337SWilliam.Krier@Sun.COM {
195511337SWilliam.Krier@Sun.COM }
1956