xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c (revision 12508:edb7861a1533)
15331Samw /*
25331Samw  * CDDL HEADER START
35331Samw  *
45331Samw  * The contents of this file are subject to the terms of the
55331Samw  * Common Development and Distribution License (the "License").
65331Samw  * You may not use this file except in compliance with the License.
75331Samw  *
85331Samw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95331Samw  * or http://www.opensolaris.org/os/licensing.
105331Samw  * See the License for the specific language governing permissions
115331Samw  * and limitations under the License.
125331Samw  *
135331Samw  * When distributing Covered Code, include this CDDL HEADER in each
145331Samw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155331Samw  * If applicable, add the following below this CDDL HEADER, with the
165331Samw  * fields enclosed by brackets "[]" replaced with your own identifying
175331Samw  * information: Portions Copyright [yyyy] [name of copyright owner]
185331Samw  *
195331Samw  * CDDL HEADER END
205331Samw  */
21*12508Samw@Sun.COM 
225331Samw /*
23*12508Samw@Sun.COM  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
245331Samw  */
255331Samw 
265331Samw /*
275331Samw  * This module provides the high level interface to the LSA RPC functions.
285331Samw  */
295331Samw 
305331Samw #include <strings.h>
315331Samw #include <unistd.h>
325331Samw 
335331Samw #include <smbsrv/libsmb.h>
345331Samw #include <smbsrv/libmlsvc.h>
355331Samw #include <smbsrv/smbinfo.h>
365331Samw #include <smbsrv/smb_token.h>
375331Samw 
388474SJose.Borrego@Sun.COM #include <lsalib.h>
395772Sas200622 
408670SJose.Borrego@Sun.COM static uint32_t lsa_lookup_name_builtin(char *, char *, smb_account_t *);
418670SJose.Borrego@Sun.COM static uint32_t lsa_lookup_name_domain(char *, smb_account_t *);
425772Sas200622 
438670SJose.Borrego@Sun.COM static uint32_t lsa_lookup_sid_builtin(smb_sid_t *, smb_account_t *);
448670SJose.Borrego@Sun.COM static uint32_t lsa_lookup_sid_domain(smb_sid_t *, smb_account_t *);
455772Sas200622 
465331Samw static int lsa_list_accounts(mlsvc_handle_t *);
475331Samw 
485331Samw /*
498474SJose.Borrego@Sun.COM  * Lookup the given account and returns the account information
508670SJose.Borrego@Sun.COM  * in the passed smb_account_t structure.
515772Sas200622  *
528474SJose.Borrego@Sun.COM  * The lookup is performed in the following order:
538474SJose.Borrego@Sun.COM  *    well known accounts
548474SJose.Borrego@Sun.COM  *    local accounts
558474SJose.Borrego@Sun.COM  *    domain accounts
568474SJose.Borrego@Sun.COM  *
578474SJose.Borrego@Sun.COM  * If it's established the given account is well know or local
588474SJose.Borrego@Sun.COM  * but the lookup fails for some reason, the next step(s) won't be
598474SJose.Borrego@Sun.COM  * performed.
605772Sas200622  *
615772Sas200622  * If the name is a domain account, it may refer to a user, group or
625772Sas200622  * alias. If it is a local account, its type should be specified
635772Sas200622  * in the sid_type parameter. In case the account type is unknown
645772Sas200622  * sid_type should be set to SidTypeUnknown.
655772Sas200622  *
668474SJose.Borrego@Sun.COM  * account argument could be either [domain\]name or [domain/]name.
678474SJose.Borrego@Sun.COM  *
688474SJose.Borrego@Sun.COM  * Return status:
698474SJose.Borrego@Sun.COM  *
708474SJose.Borrego@Sun.COM  *   NT_STATUS_SUCCESS		Account is successfully translated
718474SJose.Borrego@Sun.COM  *   NT_STATUS_NONE_MAPPED	Couldn't translate the account
725772Sas200622  */
735772Sas200622 uint32_t
lsa_lookup_name(char * account,uint16_t type,smb_account_t * info)748670SJose.Borrego@Sun.COM lsa_lookup_name(char *account, uint16_t type, smb_account_t *info)
755772Sas200622 {
768474SJose.Borrego@Sun.COM 	char nambuf[SMB_USERNAME_MAXLEN];
778474SJose.Borrego@Sun.COM 	char dombuf[SMB_PI_MAX_DOMAIN];
788474SJose.Borrego@Sun.COM 	char *name, *domain;
798474SJose.Borrego@Sun.COM 	uint32_t status;
808474SJose.Borrego@Sun.COM 	char *slash;
815772Sas200622 
828474SJose.Borrego@Sun.COM 	(void) strsubst(account, '/', '\\');
838474SJose.Borrego@Sun.COM 	(void) strcanon(account, "\\");
848474SJose.Borrego@Sun.COM 	/* \john -> john */
858474SJose.Borrego@Sun.COM 	account += strspn(account, "\\");
868474SJose.Borrego@Sun.COM 
878474SJose.Borrego@Sun.COM 	if ((slash = strchr(account, '\\')) != NULL) {
888474SJose.Borrego@Sun.COM 		*slash = '\0';
898474SJose.Borrego@Sun.COM 		(void) strlcpy(dombuf, account, sizeof (dombuf));
908474SJose.Borrego@Sun.COM 		(void) strlcpy(nambuf, slash + 1, sizeof (nambuf));
918474SJose.Borrego@Sun.COM 		*slash = '\\';
928474SJose.Borrego@Sun.COM 		name = nambuf;
938474SJose.Borrego@Sun.COM 		domain = dombuf;
945772Sas200622 	} else {
955772Sas200622 		name = account;
965772Sas200622 		domain = NULL;
975772Sas200622 	}
985772Sas200622 
998474SJose.Borrego@Sun.COM 	status = lsa_lookup_name_builtin(domain, name, info);
1008474SJose.Borrego@Sun.COM 	if (status == NT_STATUS_NOT_FOUND) {
1018670SJose.Borrego@Sun.COM 		status = smb_sam_lookup_name(domain, name, type, info);
1028474SJose.Borrego@Sun.COM 		if (status == NT_STATUS_SUCCESS)
1035772Sas200622 			return (status);
1045772Sas200622 
1058474SJose.Borrego@Sun.COM 		if ((domain == NULL) || (status == NT_STATUS_NOT_FOUND))
1068474SJose.Borrego@Sun.COM 			status = lsa_lookup_name_domain(account, info);
1075772Sas200622 	}
1085772Sas200622 
1098474SJose.Borrego@Sun.COM 	return ((status == NT_STATUS_SUCCESS) ? status : NT_STATUS_NONE_MAPPED);
1105772Sas200622 }
1115772Sas200622 
1125772Sas200622 uint32_t
lsa_lookup_sid(smb_sid_t * sid,smb_account_t * info)1138670SJose.Borrego@Sun.COM lsa_lookup_sid(smb_sid_t *sid, smb_account_t *info)
1145772Sas200622 {
1158670SJose.Borrego@Sun.COM 	uint32_t status;
1168670SJose.Borrego@Sun.COM 
1176432Sas200622 	if (!smb_sid_isvalid(sid))
1185772Sas200622 		return (NT_STATUS_INVALID_SID);
1195772Sas200622 
1208670SJose.Borrego@Sun.COM 	status = lsa_lookup_sid_builtin(sid, info);
1218670SJose.Borrego@Sun.COM 	if (status == NT_STATUS_NOT_FOUND) {
1228670SJose.Borrego@Sun.COM 		status = smb_sam_lookup_sid(sid, info);
1238670SJose.Borrego@Sun.COM 		if (status == NT_STATUS_NOT_FOUND)
1248670SJose.Borrego@Sun.COM 			status = lsa_lookup_sid_domain(sid, info);
1258670SJose.Borrego@Sun.COM 	}
1265772Sas200622 
1278670SJose.Borrego@Sun.COM 	return ((status == NT_STATUS_SUCCESS) ? status : NT_STATUS_NONE_MAPPED);
1285772Sas200622 }
1295772Sas200622 
1305772Sas200622 /*
1315331Samw  * Obtains the primary domain SID and name from the specified server
1329832Samw@Sun.COM  * (domain controller).
1335331Samw  *
1348334SJose.Borrego@Sun.COM  * The requested information will be returned via 'info' argument.
1358334SJose.Borrego@Sun.COM  *
1365331Samw  * Returns NT status codes.
1375331Samw  */
1385331Samw DWORD
lsa_query_primary_domain_info(char * server,char * domain,smb_domain_t * info)1399832Samw@Sun.COM lsa_query_primary_domain_info(char *server, char *domain,
14010717Samw@Sun.COM     smb_domain_t *info)
1415331Samw {
1425331Samw 	mlsvc_handle_t domain_handle;
1435331Samw 	DWORD status;
14410717Samw@Sun.COM 	char user[SMB_USERNAME_MAXLEN];
14510717Samw@Sun.COM 
14610717Samw@Sun.COM 	smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
1475331Samw 
1488334SJose.Borrego@Sun.COM 	if ((lsar_open(server, domain, user, &domain_handle)) != 0)
1495331Samw 		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
1505331Samw 
1515331Samw 	status = lsar_query_info_policy(&domain_handle,
1528334SJose.Borrego@Sun.COM 	    MSLSA_POLICY_PRIMARY_DOMAIN_INFO, info);
1535331Samw 
1545331Samw 	(void) lsar_close(&domain_handle);
1555331Samw 	return (status);
1565331Samw }
1575331Samw 
1585331Samw /*
1595331Samw  * Obtains the account domain SID and name from the current server
1609832Samw@Sun.COM  * (domain controller).
1615331Samw  *
1628334SJose.Borrego@Sun.COM  * The requested information will be returned via 'info' argument.
1638334SJose.Borrego@Sun.COM  *
1645331Samw  * Returns NT status codes.
1655331Samw  */
1665331Samw DWORD
lsa_query_account_domain_info(char * server,char * domain,smb_domain_t * info)1679832Samw@Sun.COM lsa_query_account_domain_info(char *server, char *domain,
16810717Samw@Sun.COM     smb_domain_t *info)
1695331Samw {
1705331Samw 	mlsvc_handle_t domain_handle;
1715331Samw 	DWORD status;
17210717Samw@Sun.COM 	char user[SMB_USERNAME_MAXLEN];
17310717Samw@Sun.COM 
17410717Samw@Sun.COM 	smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
1755331Samw 
1768334SJose.Borrego@Sun.COM 	if ((lsar_open(server, domain, user, &domain_handle)) != 0)
1775331Samw 		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
1785331Samw 
1795331Samw 	status = lsar_query_info_policy(&domain_handle,
1808334SJose.Borrego@Sun.COM 	    MSLSA_POLICY_ACCOUNT_DOMAIN_INFO, info);
1818334SJose.Borrego@Sun.COM 
1828334SJose.Borrego@Sun.COM 	(void) lsar_close(&domain_handle);
1838334SJose.Borrego@Sun.COM 	return (status);
1848334SJose.Borrego@Sun.COM }
1858334SJose.Borrego@Sun.COM 
1868334SJose.Borrego@Sun.COM /*
1878334SJose.Borrego@Sun.COM  * lsa_query_dns_domain_info
1888334SJose.Borrego@Sun.COM  *
1898334SJose.Borrego@Sun.COM  * Obtains the DNS domain info from the specified server
1908334SJose.Borrego@Sun.COM  * (domain controller).
1918334SJose.Borrego@Sun.COM  *
1928334SJose.Borrego@Sun.COM  * The requested information will be returned via 'info' argument.
1938334SJose.Borrego@Sun.COM  *
1948334SJose.Borrego@Sun.COM  * Returns NT status codes.
1958334SJose.Borrego@Sun.COM  */
1968334SJose.Borrego@Sun.COM DWORD
lsa_query_dns_domain_info(char * server,char * domain,smb_domain_t * info)19710717Samw@Sun.COM lsa_query_dns_domain_info(char *server, char *domain, smb_domain_t *info)
1988334SJose.Borrego@Sun.COM {
1998334SJose.Borrego@Sun.COM 	mlsvc_handle_t domain_handle;
2008334SJose.Borrego@Sun.COM 	DWORD status;
20110717Samw@Sun.COM 	char user[SMB_USERNAME_MAXLEN];
20210717Samw@Sun.COM 
20310717Samw@Sun.COM 	smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
2048334SJose.Borrego@Sun.COM 
2058334SJose.Borrego@Sun.COM 	if ((lsar_open(server, domain, user, &domain_handle)) != 0)
2068334SJose.Borrego@Sun.COM 		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
2078334SJose.Borrego@Sun.COM 
2088334SJose.Borrego@Sun.COM 	status = lsar_query_info_policy(&domain_handle,
2098334SJose.Borrego@Sun.COM 	    MSLSA_POLICY_DNS_DOMAIN_INFO, info);
2105331Samw 
2115331Samw 	(void) lsar_close(&domain_handle);
2125331Samw 	return (status);
2135331Samw }
2145331Samw 
2155331Samw /*
2169832Samw@Sun.COM  * Enumerate the trusted domains of  primary domain.
2179832Samw@Sun.COM  * This is the basic enumaration call which only returns the
2189832Samw@Sun.COM  * NetBIOS name of the domain and its SID.
2195331Samw  *
2208334SJose.Borrego@Sun.COM  * The requested information will be returned via 'info' argument.
2218334SJose.Borrego@Sun.COM  *
2225331Samw  * Returns NT status codes.
2235331Samw  */
2245331Samw DWORD
lsa_enum_trusted_domains(char * server,char * domain,smb_trusted_domains_t * info)2259832Samw@Sun.COM lsa_enum_trusted_domains(char *server, char *domain,
2269832Samw@Sun.COM     smb_trusted_domains_t *info)
2275331Samw {
2285331Samw 	mlsvc_handle_t domain_handle;
2295331Samw 	DWORD enum_context;
2305331Samw 	DWORD status;
23110717Samw@Sun.COM 	char user[SMB_USERNAME_MAXLEN];
23210717Samw@Sun.COM 
23310717Samw@Sun.COM 	smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
2345331Samw 
2358334SJose.Borrego@Sun.COM 	if ((lsar_open(server, domain, user, &domain_handle)) != 0)
2365331Samw 		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
2375331Samw 
2385331Samw 	enum_context = 0;
2395331Samw 
2408334SJose.Borrego@Sun.COM 	status = lsar_enum_trusted_domains(&domain_handle, &enum_context, info);
241*12508Samw@Sun.COM 	if (status == NT_STATUS_NO_MORE_ENTRIES) {
2425331Samw 		/*
243*12508Samw@Sun.COM 		 * STATUS_NO_MORE_ENTRIES indicates that we
2445331Samw 		 * have all of the available information.
2455331Samw 		 */
2465331Samw 		status = NT_STATUS_SUCCESS;
2475331Samw 	}
2485331Samw 
2495331Samw 	(void) lsar_close(&domain_handle);
2505331Samw 	return (status);
2515331Samw }
2525331Samw 
2535331Samw /*
2549832Samw@Sun.COM  * Enumerate the trusted domains of the primary domain.
2559832Samw@Sun.COM  * This is the extended enumaration call which besides
2569832Samw@Sun.COM  * NetBIOS name of the domain and its SID, it will return
2579832Samw@Sun.COM  * the FQDN plus some trust information which is not used.
2589832Samw@Sun.COM  *
2599832Samw@Sun.COM  * The requested information will be returned via 'info' argument.
2609832Samw@Sun.COM  *
2619832Samw@Sun.COM  * Returns NT status codes.
2628334SJose.Borrego@Sun.COM  */
2639832Samw@Sun.COM DWORD
lsa_enum_trusted_domains_ex(char * server,char * domain,smb_trusted_domains_t * info)2649832Samw@Sun.COM lsa_enum_trusted_domains_ex(char *server, char *domain,
2659832Samw@Sun.COM     smb_trusted_domains_t *info)
2668334SJose.Borrego@Sun.COM {
2679832Samw@Sun.COM 	mlsvc_handle_t domain_handle;
2689832Samw@Sun.COM 	DWORD enum_context;
2699832Samw@Sun.COM 	DWORD status;
27010717Samw@Sun.COM 	char user[SMB_USERNAME_MAXLEN];
27110717Samw@Sun.COM 
27210717Samw@Sun.COM 	smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
2738334SJose.Borrego@Sun.COM 
2749832Samw@Sun.COM 	if ((lsar_open(server, domain, user, &domain_handle)) != 0)
2759832Samw@Sun.COM 		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
2768334SJose.Borrego@Sun.COM 
2779832Samw@Sun.COM 	enum_context = 0;
2788334SJose.Borrego@Sun.COM 
2799832Samw@Sun.COM 	status = lsar_enum_trusted_domains_ex(&domain_handle, &enum_context,
2809832Samw@Sun.COM 	    info);
281*12508Samw@Sun.COM 	if (status == NT_STATUS_NO_MORE_ENTRIES) {
2829832Samw@Sun.COM 		/*
283*12508Samw@Sun.COM 		 * STATUS_NO_MORE_ENTRIES indicates that we
2849832Samw@Sun.COM 		 * have all of the available information.
2859832Samw@Sun.COM 		 */
2869832Samw@Sun.COM 		status = NT_STATUS_SUCCESS;
2879832Samw@Sun.COM 	}
2888334SJose.Borrego@Sun.COM 
2899832Samw@Sun.COM 	(void) lsar_close(&domain_handle);
2909832Samw@Sun.COM 	return (status);
2918334SJose.Borrego@Sun.COM }
2928334SJose.Borrego@Sun.COM 
2938334SJose.Borrego@Sun.COM /*
2948474SJose.Borrego@Sun.COM  * Lookup well known accounts table
2958474SJose.Borrego@Sun.COM  *
2968474SJose.Borrego@Sun.COM  * Return status:
2975772Sas200622  *
2988474SJose.Borrego@Sun.COM  *   NT_STATUS_SUCCESS		Account is translated successfully
2998474SJose.Borrego@Sun.COM  *   NT_STATUS_NOT_FOUND	This is not a well known account
3008474SJose.Borrego@Sun.COM  *   NT_STATUS_NONE_MAPPED	Account is found but domains don't match
3018474SJose.Borrego@Sun.COM  *   NT_STATUS_NO_MEMORY	Memory shortage
3028474SJose.Borrego@Sun.COM  *   NT_STATUS_INTERNAL_ERROR	Internal error/unexpected failure
3035772Sas200622  */
3045772Sas200622 static uint32_t
lsa_lookup_name_builtin(char * domain,char * name,smb_account_t * info)3058670SJose.Borrego@Sun.COM lsa_lookup_name_builtin(char *domain, char *name, smb_account_t *info)
3065772Sas200622 {
3078474SJose.Borrego@Sun.COM 	smb_wka_t *wka;
3088474SJose.Borrego@Sun.COM 	char *wkadom;
3095772Sas200622 
3108670SJose.Borrego@Sun.COM 	bzero(info, sizeof (smb_account_t));
3118670SJose.Borrego@Sun.COM 
3128670SJose.Borrego@Sun.COM 	if ((wka = smb_wka_lookup_name(name)) == NULL)
3138474SJose.Borrego@Sun.COM 		return (NT_STATUS_NOT_FOUND);
3145772Sas200622 
3158474SJose.Borrego@Sun.COM 	if ((wkadom = smb_wka_get_domain(wka->wka_domidx)) == NULL)
3168474SJose.Borrego@Sun.COM 		return (NT_STATUS_INTERNAL_ERROR);
3178474SJose.Borrego@Sun.COM 
31810966SJordan.Brown@Sun.COM 	if ((domain != NULL) && (smb_strcasecmp(domain, wkadom, 0) != 0))
3195772Sas200622 		return (NT_STATUS_NONE_MAPPED);
3205772Sas200622 
3218670SJose.Borrego@Sun.COM 	info->a_name = strdup(name);
3228670SJose.Borrego@Sun.COM 	info->a_sid = smb_sid_dup(wka->wka_binsid);
3238670SJose.Borrego@Sun.COM 	info->a_domain = strdup(wkadom);
3248670SJose.Borrego@Sun.COM 	info->a_domsid = smb_sid_split(wka->wka_binsid, &info->a_rid);
3258670SJose.Borrego@Sun.COM 	info->a_type = wka->wka_type;
3265772Sas200622 
3278670SJose.Borrego@Sun.COM 	if (!smb_account_validate(info)) {
3288670SJose.Borrego@Sun.COM 		smb_account_free(info);
3298670SJose.Borrego@Sun.COM 		return (NT_STATUS_NO_MEMORY);
3308474SJose.Borrego@Sun.COM 	}
3318474SJose.Borrego@Sun.COM 
3325772Sas200622 	return (NT_STATUS_SUCCESS);
3335772Sas200622 }
3345772Sas200622 
3355772Sas200622 /*
3368474SJose.Borrego@Sun.COM  * Lookup the given account in domain.
3375772Sas200622  *
3388474SJose.Borrego@Sun.COM  * The information is returned in the user_info structure.
3398474SJose.Borrego@Sun.COM  * The caller is responsible for allocating and releasing
3408474SJose.Borrego@Sun.COM  * this structure.
3415772Sas200622  */
3425772Sas200622 static uint32_t
lsa_lookup_name_domain(char * account_name,smb_account_t * info)3438670SJose.Borrego@Sun.COM lsa_lookup_name_domain(char *account_name, smb_account_t *info)
3445772Sas200622 {
3455772Sas200622 	mlsvc_handle_t domain_handle;
34610717Samw@Sun.COM 	smb_domainex_t dinfo;
3475772Sas200622 	uint32_t status;
34810717Samw@Sun.COM 	char user[SMB_USERNAME_MAXLEN];
34910717Samw@Sun.COM 
35010717Samw@Sun.COM 	smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
3515772Sas200622 
3528474SJose.Borrego@Sun.COM 	if (!smb_domain_getinfo(&dinfo))
3538474SJose.Borrego@Sun.COM 		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
3548474SJose.Borrego@Sun.COM 
35510717Samw@Sun.COM 	if (lsar_open(dinfo.d_dc, dinfo.d_primary.di_nbname, user,
3569832Samw@Sun.COM 	    &domain_handle) != 0)
3575772Sas200622 		return (NT_STATUS_INVALID_PARAMETER);
3585772Sas200622 
35911337SWilliam.Krier@Sun.COM 	status = lsar_lookup_names(&domain_handle, account_name, info);
3605772Sas200622 
3615772Sas200622 	(void) lsar_close(&domain_handle);
3625772Sas200622 	return (status);
3635772Sas200622 }
3645772Sas200622 
3655772Sas200622 /*
3665331Samw  * lsa_lookup_privs
3675331Samw  *
3685331Samw  * Request the privileges associated with the specified account. In
3695331Samw  * order to get the privileges, we first have to lookup the name on
3705331Samw  * the specified domain controller and obtain the appropriate SID.
3715331Samw  * The SID can then be used to open the account and obtain the
3725331Samw  * account privileges. The results from both the name lookup and the
3735331Samw  * privileges are returned in the user_info structure. The caller is
3745331Samw  * responsible for allocating and releasing this structure.
3755331Samw  *
3765331Samw  * On success 0 is returned. Otherwise a -ve error code.
3775331Samw  */
3785331Samw /*ARGSUSED*/
3795331Samw int
lsa_lookup_privs(char * account_name,char * target_name,smb_account_t * ainfo)3808670SJose.Borrego@Sun.COM lsa_lookup_privs(char *account_name, char *target_name, smb_account_t *ainfo)
3815331Samw {
3825331Samw 	mlsvc_handle_t domain_handle;
3835331Samw 	int rc;
38410717Samw@Sun.COM 	smb_domainex_t dinfo;
38510717Samw@Sun.COM 	char user[SMB_USERNAME_MAXLEN];
38610717Samw@Sun.COM 
38710717Samw@Sun.COM 	smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
3885331Samw 
3898334SJose.Borrego@Sun.COM 	if (!smb_domain_getinfo(&dinfo))
3908334SJose.Borrego@Sun.COM 		return (-1);
3918334SJose.Borrego@Sun.COM 
39210717Samw@Sun.COM 	if ((lsar_open(dinfo.d_dc, dinfo.d_primary.di_nbname, user,
3938334SJose.Borrego@Sun.COM 	    &domain_handle)) != 0)
3945331Samw 		return (-1);
3955331Samw 
3965331Samw 	rc = lsa_list_accounts(&domain_handle);
3975331Samw 	(void) lsar_close(&domain_handle);
3985331Samw 	return (rc);
3995331Samw }
4005331Samw 
4015331Samw /*
4025331Samw  * lsa_list_privs
4035331Samw  *
4045331Samw  * List the privileges supported by the specified server.
4055331Samw  * This function is only intended for diagnostics.
4065331Samw  *
4075331Samw  * Returns NT status codes.
4085331Samw  */
4095331Samw DWORD
lsa_list_privs(char * server,char * domain)4105331Samw lsa_list_privs(char *server, char *domain)
4115331Samw {
4125331Samw 	static char name[128];
4135331Samw 	static struct ms_luid luid;
4145331Samw 	mlsvc_handle_t domain_handle;
4155331Samw 	int rc;
4165331Samw 	int i;
41710717Samw@Sun.COM 	char user[SMB_USERNAME_MAXLEN];
41810717Samw@Sun.COM 
41910717Samw@Sun.COM 	smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
4205331Samw 
4215521Sas200622 	rc = lsar_open(server, domain, user, &domain_handle);
4225331Samw 	if (rc != 0)
4235331Samw 		return (NT_STATUS_INVALID_PARAMETER);
4245331Samw 
4255331Samw 	for (i = 0; i < 30; ++i) {
4265331Samw 		luid.low_part = i;
4275331Samw 		rc = lsar_lookup_priv_name(&domain_handle, &luid, name, 128);
4285331Samw 		if (rc != 0)
4295331Samw 			continue;
4305331Samw 
4315331Samw 		(void) lsar_lookup_priv_value(&domain_handle, name, &luid);
4325331Samw 		(void) lsar_lookup_priv_display_name(&domain_handle, name,
4335331Samw 		    name, 128);
4345331Samw 	}
4355331Samw 
4365331Samw 	(void) lsar_close(&domain_handle);
4375331Samw 	return (NT_STATUS_SUCCESS);
4385331Samw }
4395331Samw 
4405331Samw /*
4415331Samw  * lsa_list_accounts
4425331Samw  *
4435331Samw  * This function can be used to list the accounts in the specified
4445331Samw  * domain. For now the SIDs are just listed in the system log.
4455331Samw  *
4465331Samw  * On success 0 is returned. Otherwise a -ve error code.
4475331Samw  */
4485331Samw static int
lsa_list_accounts(mlsvc_handle_t * domain_handle)4495331Samw lsa_list_accounts(mlsvc_handle_t *domain_handle)
4505331Samw {
4515331Samw 	mlsvc_handle_t account_handle;
4525331Samw 	struct mslsa_EnumAccountBuf accounts;
4535331Samw 	struct mslsa_sid *sid;
4548670SJose.Borrego@Sun.COM 	smb_account_t ainfo;
4555331Samw 	DWORD enum_context = 0;
4565331Samw 	int rc;
4575331Samw 	int i;
4585331Samw 
4595331Samw 	bzero(&accounts, sizeof (struct mslsa_EnumAccountBuf));
4605331Samw 
4615331Samw 	do {
4625331Samw 		rc = lsar_enum_accounts(domain_handle, &enum_context,
4635331Samw 		    &accounts);
4645331Samw 		if (rc != 0)
4655331Samw 			return (rc);
4665331Samw 
4675331Samw 		for (i = 0; i < accounts.entries_read; ++i) {
4685331Samw 			sid = accounts.info[i].sid;
4695331Samw 
4705331Samw 			if (lsar_open_account(domain_handle, sid,
4715331Samw 			    &account_handle) == 0) {
4725331Samw 				(void) lsar_enum_privs_account(&account_handle,
4738670SJose.Borrego@Sun.COM 				    &ainfo);
4745331Samw 				(void) lsar_close(&account_handle);
4755331Samw 			}
4765331Samw 
4775331Samw 			free(accounts.info[i].sid);
4785331Samw 		}
4795331Samw 
4805331Samw 		if (accounts.info)
4815331Samw 			free(accounts.info);
4825331Samw 	} while (rc == 0 && accounts.entries_read != 0);
4835331Samw 
4845331Samw 	return (0);
4855331Samw }
4865772Sas200622 
4875772Sas200622 /*
4888670SJose.Borrego@Sun.COM  * Lookup well known accounts table for the given SID
4898670SJose.Borrego@Sun.COM  *
4908670SJose.Borrego@Sun.COM  * Return status:
4915772Sas200622  *
4928670SJose.Borrego@Sun.COM  *   NT_STATUS_SUCCESS		Account is translated successfully
4938670SJose.Borrego@Sun.COM  *   NT_STATUS_NOT_FOUND	This is not a well known account
4948670SJose.Borrego@Sun.COM  *   NT_STATUS_NO_MEMORY	Memory shortage
4958670SJose.Borrego@Sun.COM  *   NT_STATUS_INTERNAL_ERROR	Internal error/unexpected failure
4965772Sas200622  */
4975772Sas200622 static uint32_t
lsa_lookup_sid_builtin(smb_sid_t * sid,smb_account_t * ainfo)4988670SJose.Borrego@Sun.COM lsa_lookup_sid_builtin(smb_sid_t *sid, smb_account_t *ainfo)
4995772Sas200622 {
5008670SJose.Borrego@Sun.COM 	smb_wka_t *wka;
5018670SJose.Borrego@Sun.COM 	char *wkadom;
5025772Sas200622 
5038670SJose.Borrego@Sun.COM 	bzero(ainfo, sizeof (smb_account_t));
5048670SJose.Borrego@Sun.COM 
5058670SJose.Borrego@Sun.COM 	if ((wka = smb_wka_lookup_sid(sid)) == NULL)
5068670SJose.Borrego@Sun.COM 		return (NT_STATUS_NOT_FOUND);
5075772Sas200622 
5088670SJose.Borrego@Sun.COM 	if ((wkadom = smb_wka_get_domain(wka->wka_domidx)) == NULL)
5098670SJose.Borrego@Sun.COM 		return (NT_STATUS_INTERNAL_ERROR);
5105772Sas200622 
5118670SJose.Borrego@Sun.COM 	ainfo->a_name = strdup(wka->wka_name);
5128670SJose.Borrego@Sun.COM 	ainfo->a_sid = smb_sid_dup(wka->wka_binsid);
5138670SJose.Borrego@Sun.COM 	ainfo->a_domain = strdup(wkadom);
5148670SJose.Borrego@Sun.COM 	ainfo->a_domsid = smb_sid_split(ainfo->a_sid, &ainfo->a_rid);
5158670SJose.Borrego@Sun.COM 	ainfo->a_type = wka->wka_type;
5168670SJose.Borrego@Sun.COM 
5178670SJose.Borrego@Sun.COM 	if (!smb_account_validate(ainfo)) {
5188670SJose.Borrego@Sun.COM 		smb_account_free(ainfo);
5198670SJose.Borrego@Sun.COM 		return (NT_STATUS_NO_MEMORY);
5208474SJose.Borrego@Sun.COM 	}
5218474SJose.Borrego@Sun.COM 
5225772Sas200622 	return (NT_STATUS_SUCCESS);
5235772Sas200622 }
5245772Sas200622 
5255772Sas200622 static uint32_t
lsa_lookup_sid_domain(smb_sid_t * sid,smb_account_t * ainfo)5268670SJose.Borrego@Sun.COM lsa_lookup_sid_domain(smb_sid_t *sid, smb_account_t *ainfo)
5275772Sas200622 {
5285772Sas200622 	mlsvc_handle_t domain_handle;
5295772Sas200622 	uint32_t status;
53010717Samw@Sun.COM 	smb_domainex_t dinfo;
53110717Samw@Sun.COM 	char user[SMB_USERNAME_MAXLEN];
53210717Samw@Sun.COM 
53310717Samw@Sun.COM 	smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
5345772Sas200622 
5358334SJose.Borrego@Sun.COM 	if (!smb_domain_getinfo(&dinfo))
5368334SJose.Borrego@Sun.COM 		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
5378334SJose.Borrego@Sun.COM 
53810717Samw@Sun.COM 	if (lsar_open(dinfo.d_dc, dinfo.d_primary.di_nbname, user,
5399832Samw@Sun.COM 	    &domain_handle) != 0)
5405772Sas200622 		return (NT_STATUS_INVALID_PARAMETER);
5415772Sas200622 
54211337SWilliam.Krier@Sun.COM 	status = lsar_lookup_sids(&domain_handle, sid, ainfo);
5435772Sas200622 
5445772Sas200622 	(void) lsar_close(&domain_handle);
5455772Sas200622 	return (status);
5465772Sas200622 }
547