xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c (revision 5521:cf62335046cd)
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  */
215331Samw /*
225331Samw  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
235331Samw  * Use is subject to license terms.
245331Samw  */
255331Samw 
265331Samw #pragma ident	"%Z%%M%	%I%	%E% SMI"
275331Samw 
285331Samw /*
295331Samw  * Utility functions to support the RPC interface library.
305331Samw  */
315331Samw 
325331Samw #include <stdio.h>
335331Samw #include <stdarg.h>
345331Samw #include <strings.h>
355331Samw #include <unistd.h>
365331Samw #include <netdb.h>
375331Samw #include <stdlib.h>
385331Samw #include <pwd.h>
395331Samw #include <grp.h>
405331Samw 
415331Samw #include <sys/time.h>
425331Samw #include <sys/systm.h>
435331Samw 
445331Samw #include <smbsrv/libsmb.h>
455331Samw #include <smbsrv/libsmbrdr.h>
465331Samw #include <smbsrv/libsmbns.h>
475331Samw #include <smbsrv/libmlsvc.h>
485331Samw 
495331Samw #include <smbsrv/smbinfo.h>
505331Samw #include <smbsrv/ntsid.h>
515331Samw #include <smbsrv/lsalib.h>
525331Samw #include <smbsrv/samlib.h>
535331Samw #include <smbsrv/mlsvc_util.h>
545331Samw #include <smbsrv/mlsvc.h>
555331Samw 
565331Samw extern int netr_open(char *, char *, mlsvc_handle_t *);
575331Samw extern int netr_close(mlsvc_handle_t *);
585331Samw extern DWORD netlogon_auth(char *, mlsvc_handle_t *, DWORD);
595331Samw extern int mlsvc_user_getauth(char *, char *, smb_auth_info_t *);
605331Samw 
615331Samw static int mlsvc_lookup_local_name(char *name, nt_sid_t **sid);
625331Samw static int mlsvc_lookup_nt_name(char *name, nt_sid_t **sid);
635331Samw static int mlsvc_lookup_nt_sid(nt_sid_t *sid, char *buf, int bufsize);
645331Samw 
655331Samw /*
665331Samw  * Compare the supplied domain name with the local hostname.
675331Samw  * We need to deal with both server names and fully-qualified
685331Samw  * domain names.
695331Samw  *
705331Samw  * Returns:
715331Samw  *	0	The specified domain is not the local domain,
725331Samw  *	1	The Specified domain is the local domain.
735331Samw  *	-1	Invalid parameter or unable to get the local
745331Samw  *		system information.
755331Samw  */
765331Samw int
775331Samw mlsvc_is_local_domain(const char *domain)
785331Samw {
795331Samw 	char hostname[MAXHOSTNAMELEN];
805331Samw 	uint32_t mode;
815331Samw 	int rc;
825331Samw 
835331Samw 	if (strchr(domain, '.') != NULL)
845331Samw 		rc = smb_getfqhostname(hostname, MAXHOSTNAMELEN);
855331Samw 	else
865331Samw 		rc = smb_gethostname(hostname, MAXHOSTNAMELEN, 1);
875331Samw 
885331Samw 	if (rc != 0)
895331Samw 		return (-1);
905331Samw 
915331Samw 	rc = strcasecmp(domain, hostname);
925331Samw 	mode = smb_get_security_mode();
935331Samw 
945331Samw 	if ((rc == 0) || (mode == SMB_SECMODE_WORKGRP))
955331Samw 		return (1);
965331Samw 
975331Samw 	return (0);
985331Samw }
995331Samw 
1005331Samw /*
1015331Samw  * mlsvc_lookup_name
1025331Samw  *
1035331Samw  * Lookup a name in the specified domain and translate it to a SID.
1045331Samw  * If the name is in the NT domain, it may refer to a user, group or
1055331Samw  * alias. Otherwise it must refer to a UNIX username. The memory for
1065331Samw  * the sid is allocated using malloc so the caller should call free
1075331Samw  * when it is no longer required.
1085331Samw  *
1095331Samw  * On success, 0 will be returned and sid will point to a local domain
1105331Samw  * user SID. Otherwise -1 will be returned.
1115331Samw  */
1125331Samw int
1135331Samw mlsvc_lookup_name(char *domain, char *name, nt_sid_t **sid)
1145331Samw {
1155331Samw 	if (domain == NULL || name == NULL || sid == NULL)
1165331Samw 		return (-1);
1175331Samw 
1185331Samw 	if (mlsvc_is_local_domain(domain) == 1)
1195331Samw 		return (mlsvc_lookup_local_name(name, sid));
1205331Samw 	else
1215331Samw 		return (mlsvc_lookup_nt_name(name, sid));
1225331Samw }
1235331Samw 
1245331Samw /*
1255331Samw  * mlsvc_lookup_local_name
1265331Samw  *
1275331Samw  * Lookup a name in the local password file and translate it to a SID.
1285331Samw  * The name must refer to a user. This is a private function intended
1295331Samw  * to support mlsvc_lookup_name so it doesn't perform any parameter
1305331Samw  * validation. The memory for the sid is allocated using malloc so the
1315331Samw  * caller must call free when it is no longer required.
1325331Samw  *
1335331Samw  * On success, 0 will be returned and sid will point to a local domain
1345331Samw  * user SID. Otherwise -1 will be returned.
1355331Samw  */
1365331Samw static int
1375331Samw mlsvc_lookup_local_name(char *name, nt_sid_t **sid)
1385331Samw {
1395331Samw 	struct passwd *pw;
1405331Samw 	nt_sid_t *domain_sid;
1415331Samw 
1425331Samw 	if ((pw = getpwnam(name)) == NULL)
1435331Samw 		return (-1);
1445331Samw 
1455331Samw 	if ((domain_sid = nt_domain_local_sid()) == NULL)
1465331Samw 		return (-1);
1475331Samw 
1485331Samw 	*sid = nt_sid_splice(domain_sid, pw->pw_uid);
1495331Samw 	return (0);
1505331Samw }
1515331Samw 
1525331Samw /*
1535331Samw  * mlsvc_lookup_nt_name
1545331Samw  *
1555331Samw  * Lookup a name in the specified NT domain and translate it to a SID.
1565331Samw  * The name may refer to a user, group or alias. This is a private
1575331Samw  * function intended to support mlsvc_lookup_name so it doesn't do any
1585331Samw  * parameter validation. The memory for the sid is allocated using
1595331Samw  * malloc so the caller should call free when it is no longer required.
1605331Samw  *
1615331Samw  * On success, 0 will be returned and sid will point to an NT domain
1625331Samw  * user SID. Otherwise -1 will be returned.
1635331Samw  */
1645331Samw static int
1655331Samw mlsvc_lookup_nt_name(char *name, nt_sid_t **sid)
1665331Samw {
1675331Samw 	smb_userinfo_t *user_info;
1685331Samw 
1695331Samw 	if ((user_info = mlsvc_alloc_user_info()) == NULL)
1705331Samw 		return (-1);
1715331Samw 
1725331Samw 	if (lsa_lookup_name(0, 0, name, user_info) != 0)
1735331Samw 		return (-1);
1745331Samw 
1755331Samw 	*sid = nt_sid_splice(user_info->domain_sid, user_info->rid);
1765331Samw 	mlsvc_free_user_info(user_info);
1775331Samw 	return (0);
1785331Samw }
1795331Samw 
1805331Samw /*
1815331Samw  * mlsvc_lookup_sid
1825331Samw  *
1835331Samw  * Lookup a SID and translate it to a name. The name returned may refer
1845331Samw  * to a domain, user, group or alias dependent on the SID. On success 0
1855331Samw  * will be returned. Otherwise -1 will be returned.
1865331Samw  */
1875331Samw int
1885331Samw mlsvc_lookup_sid(nt_sid_t *sid, char *buf, int bufsize)
1895331Samw {
1905331Samw 	struct passwd *pw;
1915331Samw 	struct group *gr;
1925331Samw 	nt_group_t *grp;
1935331Samw 	DWORD rid;
1945331Samw 
1955331Samw 	if (sid == NULL || buf == NULL)
1965331Samw 		return (-1);
1975331Samw 
1985331Samw 	if (nt_sid_is_local(sid)) {
1995331Samw 		(void) nt_sid_get_rid(sid, &rid);
2005331Samw 
2015331Samw 		switch (SAM_RID_TYPE(rid)) {
2025331Samw 		case SAM_RT_NT_UID:
2035331Samw 			break;
2045331Samw 
2055331Samw 		case SAM_RT_NT_GID:
2065331Samw 			if ((grp = nt_groups_lookup_rid(rid)) == NULL)
2075331Samw 				return (-1);
2085331Samw 
2095331Samw 			(void) strlcpy(buf, grp->name, bufsize);
2105331Samw 			break;
2115331Samw 
2125331Samw 		case SAM_RT_UNIX_UID:
2135331Samw 			if ((pw = getpwuid(SAM_DECODE_RID(rid))) == NULL)
2145331Samw 				return (-1);
2155331Samw 
2165331Samw 			(void) strlcpy(buf, pw->pw_name, bufsize);
2175331Samw 			break;
2185331Samw 
2195331Samw 		case SAM_RT_UNIX_GID:
2205331Samw 			if ((gr = getgrgid(SAM_DECODE_RID(rid))) == NULL)
2215331Samw 				return (-1);
2225331Samw 
2235331Samw 			(void) strlcpy(buf, gr->gr_name, bufsize);
2245331Samw 			break;
2255331Samw 		}
2265331Samw 
2275331Samw 		return (0);
2285331Samw 	}
2295331Samw 
2305331Samw 	return (mlsvc_lookup_nt_sid(sid, buf, bufsize));
2315331Samw }
2325331Samw 
2335331Samw /*
2345331Samw  * mlsvc_lookup_nt_sid
2355331Samw  *
2365331Samw  * Lookup an NT SID and translate it to a name. This is a private
2375331Samw  * function intended to support mlsvc_lookup_sid so it doesn't do any
2385331Samw  * parameter validation. The input account_name specifies the logon/
2395331Samw  * session to be used for the lookup. It doesn't need to have any
2405331Samw  * association with the SID being looked up. The name returned may
2415331Samw  * refer to a domain, user, group or alias dependent on the SID.
2425331Samw  *
2435331Samw  * On success the name will be copied into buf and 0 will be returned.
2445331Samw  * Otherwise -1 will be returned.
2455331Samw  */
2465331Samw static int
2475331Samw mlsvc_lookup_nt_sid(nt_sid_t *sid, char *buf, int bufsize)
2485331Samw {
2495331Samw 	smb_userinfo_t *user_info;
2505331Samw 	int rc;
2515331Samw 
2525331Samw 	if ((user_info = mlsvc_alloc_user_info()) == NULL)
2535331Samw 		return (-1);
2545331Samw 
2555331Samw 	if ((rc = lsa_lookup_sid(sid, user_info)) == 0)
2565331Samw 		(void) strlcpy(buf, user_info->name, bufsize);
2575331Samw 
2585331Samw 	mlsvc_free_user_info(user_info);
2595331Samw 	return (rc);
2605331Samw }
2615331Samw 
2625331Samw /*
2635331Samw  * mlsvc_alloc_user_info
2645331Samw  *
2655331Samw  * Allocate a user_info structure and set the contents to zero. A
2665331Samw  * pointer to the user_info structure is returned.
2675331Samw  */
2685331Samw smb_userinfo_t *
2695331Samw mlsvc_alloc_user_info(void)
2705331Samw {
2715331Samw 	smb_userinfo_t *user_info;
2725331Samw 
2735331Samw 	user_info = (smb_userinfo_t *)malloc(sizeof (smb_userinfo_t));
2745331Samw 	if (user_info == NULL)
2755331Samw 		return (NULL);
2765331Samw 
2775331Samw 	bzero(user_info, sizeof (smb_userinfo_t));
2785331Samw 	return (user_info);
2795331Samw }
2805331Samw 
2815331Samw /*
2825331Samw  * mlsvc_free_user_info
2835331Samw  *
2845331Samw  * Free a user_info structure. This function ensures that the contents
2855331Samw  * of the user_info are freed as well as the user_info itself.
2865331Samw  */
2875331Samw void
2885331Samw mlsvc_free_user_info(smb_userinfo_t *user_info)
2895331Samw {
2905331Samw 	if (user_info) {
2915331Samw 		mlsvc_release_user_info(user_info);
2925331Samw 		free(user_info);
2935331Samw 	}
2945331Samw }
2955331Samw 
2965331Samw /*
2975331Samw  * mlsvc_release_user_info
2985331Samw  *
2995331Samw  * Release the contents of a user_info structure and zero out the
3005331Samw  * elements but do not free the user_info structure itself. This
3015331Samw  * function cleans out the structure so that it can be reused without
3025331Samw  * worrying about stale contents.
3035331Samw  */
3045331Samw void
3055331Samw mlsvc_release_user_info(smb_userinfo_t *user_info)
3065331Samw {
3075331Samw 	int i;
3085331Samw 
3095331Samw 	if (user_info == NULL)
3105331Samw 		return;
3115331Samw 
3125331Samw 	free(user_info->name);
3135331Samw 	free(user_info->domain_sid);
3145331Samw 	free(user_info->domain_name);
3155331Samw 	free(user_info->groups);
3165331Samw 
3175331Samw 	if (user_info->n_other_grps) {
3185331Samw 		for (i = 0; i < user_info->n_other_grps; i++)
3195331Samw 			free(user_info->other_grps[i].sid);
3205331Samw 
3215331Samw 		free(user_info->other_grps);
3225331Samw 	}
3235331Samw 
3245331Samw 	free(user_info->user_sid);
3255331Samw 	free(user_info->pgrp_sid);
3265331Samw 	bzero(user_info, sizeof (smb_userinfo_t));
3275331Samw }
3285331Samw 
3295331Samw /*
3305331Samw  * mlsvc_setadmin_user_info
3315331Samw  *
3325331Samw  * Determines if the given user is the domain Administrator or a
3335331Samw  * member of Domain Admins or Administrators group and set the
3345331Samw  * user_info->flags accordingly.
3355331Samw  */
3365331Samw void
3375331Samw mlsvc_setadmin_user_info(smb_userinfo_t *user_info)
3385331Samw {
3395331Samw 	nt_domain_t *domain;
3405331Samw 	nt_group_t *grp;
3415331Samw 	int i;
3425331Samw 
3435331Samw 	if ((domain = nt_domain_lookupbytype(NT_DOMAIN_PRIMARY)) == NULL)
3445331Samw 		return;
3455331Samw 
3465331Samw 	if (!nt_sid_is_equal((nt_sid_t *)user_info->domain_sid, domain->sid))
3475331Samw 		return;
3485331Samw 
3495331Samw 	if (user_info->rid == DOMAIN_USER_RID_ADMIN)
3505331Samw 		user_info->flags |= SMB_UINFO_FLAG_DADMIN;
3515331Samw 	else if (user_info->primary_group_rid == DOMAIN_GROUP_RID_ADMINS)
3525331Samw 		user_info->flags |= SMB_UINFO_FLAG_DADMIN;
3535331Samw 	else {
3545331Samw 		for (i = 0; i < user_info->n_groups; i++)
3555331Samw 			if (user_info->groups[i].rid == DOMAIN_GROUP_RID_ADMINS)
3565331Samw 				user_info->flags |= SMB_UINFO_FLAG_DADMIN;
3575331Samw 	}
3585331Samw 
3595331Samw 	grp = nt_group_getinfo("Administrators", RWLOCK_READER);
3605331Samw 	if (grp) {
3615331Samw 		i = nt_group_is_member(grp, user_info->user_sid);
3625331Samw 		nt_group_putinfo(grp);
3635331Samw 		if (i)
3645331Samw 			user_info->flags |= SMB_UINFO_FLAG_LADMIN;
3655331Samw 	}
3665331Samw }
3675331Samw 
3685331Samw /*
3695331Samw  * mlsvc_string_save
3705331Samw  *
3715331Samw  * This is a convenience function to prepare strings for an RPC call.
3725331Samw  * An ms_string_t is set up with the appropriate lengths and str is
3735331Samw  * set up to point to a copy of the original string on the heap. The
3745331Samw  * macro MLRPC_HEAP_STRSAVE is an alias for mlrpc_heap_strsave, which
3755331Samw  * extends the heap and copies the string into the new area.
3765331Samw  */
3775331Samw int
3785331Samw mlsvc_string_save(ms_string_t *ms, char *str, struct mlrpc_xaction *mxa)
3795331Samw {
380*5521Sas200622 	if (str == NULL)
3815331Samw 		return (0);
3825331Samw 
383*5521Sas200622 	ms->length = mts_wcequiv_strlen(str);
384*5521Sas200622 	ms->allosize = ms->length + sizeof (mts_wchar_t);
3855331Samw 
386*5521Sas200622 	if ((ms->str = MLRPC_HEAP_STRSAVE(mxa, str)) == NULL)
387*5521Sas200622 		return (0);
3885331Samw 
3895331Samw 	return (1);
3905331Samw }
3915331Samw 
3925331Samw /*
3935331Samw  * mlsvc_sid_save
3945331Samw  *
3955331Samw  * Expand the heap and copy the sid into the new area.
3965331Samw  * Returns a pointer to the copy of the sid on the heap.
3975331Samw  */
3985331Samw nt_sid_t *
3995331Samw mlsvc_sid_save(nt_sid_t *sid, struct mlrpc_xaction *mxa)
4005331Samw {
4015331Samw 	nt_sid_t *heap_sid;
4025331Samw 	unsigned size;
4035331Samw 
4045331Samw 	if (sid == NULL)
4055331Samw 		return (NULL);
4065331Samw 
4075331Samw 	size = nt_sid_length(sid);
4085331Samw 
4095331Samw 	if ((heap_sid = (nt_sid_t *)MLRPC_HEAP_MALLOC(mxa, size)) == NULL)
4105331Samw 		return (0);
4115331Samw 
4125331Samw 	bcopy(sid, heap_sid, size);
4135331Samw 	return (heap_sid);
4145331Samw }
4155331Samw 
4165331Samw /*
4175331Samw  * mlsvc_is_null_handle
4185331Samw  *
4195331Samw  * Check a handle against a null handle. Returns 1 if the handle is
4205331Samw  * null. Otherwise returns 0.
4215331Samw  */
4225331Samw int
4235331Samw mlsvc_is_null_handle(mlsvc_handle_t *handle)
4245331Samw {
4255331Samw 	static ms_handle_t zero_handle;
4265331Samw 
4275331Samw 	if (handle == NULL || handle->context == NULL)
4285331Samw 		return (1);
4295331Samw 
4305331Samw 	if (!memcmp(&handle->handle, &zero_handle, sizeof (ms_handle_t)))
4315331Samw 		return (1);
4325331Samw 
4335331Samw 	return (0);
4345331Samw }
4355331Samw 
4365331Samw /*
437*5521Sas200622  * mlsvc_join
4385331Samw  *
4395331Samw  * Returns NT status codes.
4405331Samw  */
4415331Samw DWORD
442*5521Sas200622 mlsvc_join(char *server, char *domain, char *plain_user, char *plain_text)
4435331Samw {
4445331Samw 	smb_auth_info_t auth;
4455331Samw 	smb_ntdomain_t *di;
4465331Samw 	int erc;
4475331Samw 	DWORD status;
4485331Samw 	mlsvc_handle_t netr_handle;
4495331Samw 	char machine_passwd[MLSVC_MACHINE_ACCT_PASSWD_MAX];
4505331Samw 
4515331Samw 	machine_passwd[0] = '\0';
4525331Samw 
4535331Samw 	/*
4545331Samw 	 * Ensure that the domain name is uppercase.
4555331Samw 	 */
4565331Samw 	(void) utf8_strupr(domain);
4575331Samw 
4585331Samw 	/*
4595331Samw 	 * There is no point continuing if the domain information is
4605331Samw 	 * not available. Wait for up to 10 seconds and then give up.
4615331Samw 	 */
4625331Samw 	if ((di = smb_getdomaininfo(10)) == 0) {
4635331Samw 		status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4645331Samw 		return (status);
4655331Samw 	}
4665331Samw 
4675331Samw 	if (strcasecmp(domain, di->domain) != 0) {
4685331Samw 		status = NT_STATUS_INVALID_PARAMETER;
4695331Samw 		return (status);
4705331Samw 	}
4715331Samw 
472*5521Sas200622 	erc = mlsvc_logon(server, domain, plain_user);
4735331Samw 
4745331Samw 	if (erc == AUTH_USER_GRANT) {
4755331Samw 		int isenabled;
4765331Samw 
4775331Samw 		smb_config_rdlock();
4785331Samw 		isenabled = smb_config_getyorn(SMB_CI_ADS_ENABLE);
4795331Samw 		smb_config_unlock();
4805331Samw 		if (isenabled) {
481*5521Sas200622 			if (ads_join(plain_user, plain_text, machine_passwd,
482*5521Sas200622 			    sizeof (machine_passwd)) == ADJOIN_SUCCESS)
4835331Samw 				status = NT_STATUS_SUCCESS;
484*5521Sas200622 			else
4855331Samw 				status = NT_STATUS_UNSUCCESSFUL;
4865331Samw 		} else {
4875331Samw 			if (mlsvc_user_getauth(server, plain_user, &auth)
4885331Samw 			    != 0) {
4895331Samw 				status = NT_STATUS_INVALID_PARAMETER;
4905331Samw 				return (status);
4915331Samw 			}
4925331Samw 
4935331Samw 			status = sam_create_trust_account(server, domain,
4945331Samw 			    &auth);
4955331Samw 			if (status == NT_STATUS_SUCCESS) {
4965331Samw 				(void) smb_gethostname(machine_passwd,
4975331Samw 				    sizeof (machine_passwd), 0);
4985331Samw 				(void) utf8_strlwr(machine_passwd);
4995331Samw 			}
5005331Samw 		}
5015331Samw 
5025331Samw 		if (status == NT_STATUS_SUCCESS) {
503*5521Sas200622 			if (smb_set_machine_pwd(machine_passwd) != 0)
5045331Samw 				return (NT_STATUS_UNSUCCESSFUL);
5055331Samw 
5065331Samw 			/*
5075331Samw 			 * If we successfully create a trust account, we mark
5085331Samw 			 * ourselves as a domain member in the environment so
5095331Samw 			 * that we use the SAMLOGON version of the NETLOGON
5105331Samw 			 * PDC location protocol.
5115331Samw 			 */
5125331Samw 			smb_set_domain_member(1);
5135331Samw 
5145331Samw 			if (netr_open(server, domain, &netr_handle) == 0) {
5155331Samw 				status = netlogon_auth(server, &netr_handle,
5165331Samw 				    NETR_FLG_INIT);
5175331Samw 				(void) netr_close(&netr_handle);
5185331Samw 			} else {
5195331Samw 				status = NT_STATUS_OPEN_FAILED;
5205331Samw 			}
5215331Samw 		}
5225331Samw 	} else {
5235331Samw 		status = NT_STATUS_LOGON_FAILURE;
5245331Samw 	}
5255331Samw 
5265331Samw 	return (status);
5275331Samw }
5285331Samw 
5295331Samw /*ARGSUSED*/
5305331Samw void
5315331Samw nt_group_ht_lock(krwmode_t locktype)
5325331Samw {
5335331Samw }
5345331Samw 
5355331Samw void
5365331Samw nt_group_ht_unlock(void)
5375331Samw {
5385331Samw }
5395331Samw 
5405331Samw int
5415331Samw nt_group_num_groups(void)
5425331Samw {
5435331Samw 	return (0);
5445331Samw }
5455331Samw 
5465331Samw /*ARGSUSED*/
5475331Samw uint32_t
5485331Samw nt_group_add(char *gname, char *comment)
5495331Samw {
5505331Samw 	return (NT_STATUS_NOT_SUPPORTED);
5515331Samw }
5525331Samw 
5535331Samw /*ARGSUSED*/
5545331Samw uint32_t
5555331Samw nt_group_modify(char *gname, char *new_gname, char *comment)
5565331Samw {
5575331Samw 	return (NT_STATUS_NOT_SUPPORTED);
5585331Samw }
5595331Samw 
5605331Samw /*ARGSUSED*/
5615331Samw uint32_t
5625331Samw nt_group_delete(char *gname)
5635331Samw {
5645331Samw 	return (NT_STATUS_NOT_SUPPORTED);
5655331Samw }
5665331Samw 
5675331Samw /*ARGSUSED*/
5685331Samw nt_group_t *
5695331Samw nt_group_getinfo(char *gname, krwmode_t locktype)
5705331Samw {
5715331Samw 	return (NULL);
5725331Samw }
5735331Samw 
5745331Samw /*ARGSUSED*/
5755331Samw void
5765331Samw nt_group_putinfo(nt_group_t *grp)
5775331Samw {
5785331Samw }
5795331Samw 
5805331Samw /*ARGSUSED*/
5815331Samw int
5825331Samw nt_group_getpriv(nt_group_t *grp, uint32_t priv_id)
5835331Samw {
5845331Samw 	return (SE_PRIVILEGE_DISABLED);
5855331Samw }
5865331Samw 
5875331Samw /*ARGSUSED*/
5885331Samw uint32_t
5895331Samw nt_group_setpriv(nt_group_t *grp, uint32_t priv_id, uint32_t new_attr)
5905331Samw {
5915331Samw 	return (NT_STATUS_NOT_SUPPORTED);
5925331Samw }
5935331Samw 
5945331Samw /*ARGSUSED*/
5955331Samw int
5965331Samw nt_group_is_member(nt_group_t *grp, nt_sid_t *sid)
5975331Samw {
5985331Samw 	return (0);
5995331Samw }
6005331Samw 
6015331Samw /*ARGSUSED*/
6025331Samw uint32_t
6035331Samw nt_group_add_member(nt_group_t *grp, nt_sid_t *msid, uint16_t sid_name_use,
6045331Samw     char *account)
6055331Samw {
6065331Samw 	return (NT_STATUS_NOT_SUPPORTED);
6075331Samw }
6085331Samw 
6095331Samw /*ARGSUSED*/
6105331Samw uint32_t
6115331Samw nt_group_del_member(nt_group_t *grp, void *key, int keytype)
6125331Samw {
6135331Samw 	return (NT_STATUS_NOT_SUPPORTED);
6145331Samw }
6155331Samw 
6165331Samw /*ARGSUSED*/
6175331Samw int
6185331Samw nt_group_num_members(nt_group_t *grp)
6195331Samw {
6205331Samw 	return (0);
6215331Samw }
6225331Samw 
6235331Samw nt_group_iterator_t *
6245331Samw nt_group_open_iterator(void)
6255331Samw {
6265331Samw 	return (NULL);
6275331Samw }
6285331Samw 
6295331Samw /*ARGSUSED*/
6305331Samw void
6315331Samw nt_group_close_iterator(nt_group_iterator_t *gi)
6325331Samw {
6335331Samw }
6345331Samw 
6355331Samw /*ARGSUSED*/
6365331Samw nt_group_t *
6375331Samw nt_group_iterate(nt_group_iterator_t *gi)
6385331Samw {
6395331Samw 	return (NULL);
6405331Samw }
6415331Samw 
6425331Samw int
6435331Samw nt_group_cache_size(void)
6445331Samw {
6455331Samw 	return (0);
6465331Samw }
6475331Samw 
6485331Samw uint32_t
6495331Samw sam_init(void)
6505331Samw {
6515331Samw 	return (NT_STATUS_SUCCESS);
6525331Samw }
6535331Samw 
6545331Samw /*ARGSUSED*/
6555331Samw uint32_t
6565331Samw nt_group_add_member_byname(char *gname, char *account)
6575331Samw {
6585331Samw 	return (NT_STATUS_NOT_SUPPORTED);
6595331Samw }
6605331Samw 
6615331Samw /*ARGSUSED*/
6625331Samw uint32_t
6635331Samw nt_group_del_member_byname(nt_group_t *grp, char *member_name)
6645331Samw {
6655331Samw 	return (NT_STATUS_NOT_SUPPORTED);
6665331Samw }
6675331Samw 
6685331Samw /*ARGSUSED*/
6695331Samw void
6705331Samw nt_group_add_groupprivs(nt_group_t *grp, smb_privset_t *priv)
6715331Samw {
6725331Samw }
6735331Samw 
6745331Samw /*ARGSUSED*/
6755331Samw uint32_t
6765331Samw nt_groups_member_privs(nt_sid_t *sid, smb_privset_t *priv)
6775331Samw {
6785331Samw 	return (NT_STATUS_SUCCESS);
6795331Samw }
6805331Samw 
6815331Samw /*ARGSUSED*/
6825331Samw int
6835331Samw nt_groups_member_ngroups(nt_sid_t *sid)
6845331Samw {
6855331Samw 	return (0);
6865331Samw }
6875331Samw 
6885331Samw /*ARGSUSED*/
6895331Samw uint32_t
6905331Samw nt_groups_member_groups(nt_sid_t *sid, smb_id_t *grps, int ngrps)
6915331Samw {
6925331Samw 	return (NT_STATUS_SUCCESS);
6935331Samw }
6945331Samw 
6955331Samw /*ARGSUSED*/
6965331Samw nt_group_t *
6975331Samw nt_groups_lookup_rid(uint32_t rid)
6985331Samw {
6995331Samw 	return (NULL);
7005331Samw }
7015331Samw 
7025331Samw /*ARGSUSED*/
7035331Samw int
7045331Samw nt_groups_count(int cnt_opt)
7055331Samw {
7065331Samw 	return (0);
7075331Samw }
7085331Samw 
7095331Samw /*ARGSUSED*/
7105331Samw int
7115331Samw nt_group_member_list(int offset, nt_group_t *grp,
7125331Samw     ntgrp_member_list_t *rmembers)
7135331Samw {
7145331Samw 	return (0);
7155331Samw }
7165331Samw 
7175331Samw /*ARGSUSED*/
7185331Samw void
7195331Samw nt_group_list(int offset, char *pattern, ntgrp_list_t *list)
7205331Samw {
7215331Samw }
722