xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c (revision 8474:7803efd2fa77)
17961SNatalie.Li@Sun.COM /*
27961SNatalie.Li@Sun.COM  * CDDL HEADER START
37961SNatalie.Li@Sun.COM  *
47961SNatalie.Li@Sun.COM  * The contents of this file are subject to the terms of the
57961SNatalie.Li@Sun.COM  * Common Development and Distribution License (the "License").
67961SNatalie.Li@Sun.COM  * You may not use this file except in compliance with the License.
77961SNatalie.Li@Sun.COM  *
87961SNatalie.Li@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97961SNatalie.Li@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107961SNatalie.Li@Sun.COM  * See the License for the specific language governing permissions
117961SNatalie.Li@Sun.COM  * and limitations under the License.
127961SNatalie.Li@Sun.COM  *
137961SNatalie.Li@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147961SNatalie.Li@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157961SNatalie.Li@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167961SNatalie.Li@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177961SNatalie.Li@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187961SNatalie.Li@Sun.COM  *
197961SNatalie.Li@Sun.COM  * CDDL HEADER END
207961SNatalie.Li@Sun.COM  */
217961SNatalie.Li@Sun.COM /*
22*8474SJose.Borrego@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237961SNatalie.Li@Sun.COM  * Use is subject to license terms.
247961SNatalie.Li@Sun.COM  */
257961SNatalie.Li@Sun.COM 
267961SNatalie.Li@Sun.COM /*
277961SNatalie.Li@Sun.COM  * Security database interface.
287961SNatalie.Li@Sun.COM  */
297961SNatalie.Li@Sun.COM #include <unistd.h>
307961SNatalie.Li@Sun.COM #include <strings.h>
317961SNatalie.Li@Sun.COM #include <pwd.h>
327961SNatalie.Li@Sun.COM #include <grp.h>
337961SNatalie.Li@Sun.COM #include <time.h>
347961SNatalie.Li@Sun.COM #include <syslog.h>
357961SNatalie.Li@Sun.COM #include <assert.h>
367961SNatalie.Li@Sun.COM 
377961SNatalie.Li@Sun.COM #include <smbsrv/libsmb.h>
387961SNatalie.Li@Sun.COM #include <smbsrv/libmlsvc.h>
397961SNatalie.Li@Sun.COM 
407961SNatalie.Li@Sun.COM #include <smbsrv/smbinfo.h>
417961SNatalie.Li@Sun.COM #include <smbsrv/smb_token.h>
428334SJose.Borrego@Sun.COM #include <lsalib.h>
437961SNatalie.Li@Sun.COM 
447961SNatalie.Li@Sun.COM extern uint32_t netlogon_logon(netr_client_t *clnt, smb_userinfo_t *uinfo);
457961SNatalie.Li@Sun.COM static uint32_t smb_logon_domain(netr_client_t *clnt, smb_userinfo_t *uinfo);
467961SNatalie.Li@Sun.COM static uint32_t smb_logon_local(netr_client_t *clnt, smb_userinfo_t *uinfo);
477961SNatalie.Li@Sun.COM static uint32_t smb_logon_none(netr_client_t *clnt, smb_userinfo_t *uinfo);
487961SNatalie.Li@Sun.COM 
497961SNatalie.Li@Sun.COM static uint32_t smb_setup_luinfo(smb_userinfo_t *, netr_client_t *, uid_t);
507961SNatalie.Li@Sun.COM 
517961SNatalie.Li@Sun.COM static int smb_token_is_member(smb_token_t *token, smb_sid_t *sid);
527961SNatalie.Li@Sun.COM static int smb_token_is_valid(smb_token_t *token);
537961SNatalie.Li@Sun.COM static smb_win_grps_t *smb_token_create_wingrps(smb_userinfo_t *user_info);
547961SNatalie.Li@Sun.COM 
557961SNatalie.Li@Sun.COM static smb_posix_grps_t *smb_token_create_pxgrps(uid_t uid);
567961SNatalie.Li@Sun.COM 
577961SNatalie.Li@Sun.COM /* Consolidation private function from Network Repository */
587961SNatalie.Li@Sun.COM extern int _getgroupsbymember(const char *, gid_t[], int, int);
597961SNatalie.Li@Sun.COM 
607961SNatalie.Li@Sun.COM static idmap_stat
617961SNatalie.Li@Sun.COM smb_token_idmap(smb_token_t *token, smb_idmap_batch_t *sib)
627961SNatalie.Li@Sun.COM {
637961SNatalie.Li@Sun.COM 	idmap_stat stat;
647961SNatalie.Li@Sun.COM 	smb_idmap_t *sim;
657961SNatalie.Li@Sun.COM 	smb_id_t *id;
667961SNatalie.Li@Sun.COM 	int i;
677961SNatalie.Li@Sun.COM 
687961SNatalie.Li@Sun.COM 	if (!token || !sib)
697961SNatalie.Li@Sun.COM 		return (IDMAP_ERR_ARG);
707961SNatalie.Li@Sun.COM 
717961SNatalie.Li@Sun.COM 	sim = sib->sib_maps;
727961SNatalie.Li@Sun.COM 
737961SNatalie.Li@Sun.COM 	if (token->tkn_flags & SMB_ATF_ANON) {
747961SNatalie.Li@Sun.COM 		token->tkn_user->i_id = UID_NOBODY;
757961SNatalie.Li@Sun.COM 		token->tkn_owner->i_id = UID_NOBODY;
767961SNatalie.Li@Sun.COM 	} else {
777961SNatalie.Li@Sun.COM 		/* User SID */
787961SNatalie.Li@Sun.COM 		id = token->tkn_user;
797961SNatalie.Li@Sun.COM 		sim->sim_id = &id->i_id;
807961SNatalie.Li@Sun.COM 		stat = smb_idmap_batch_getid(sib->sib_idmaph, sim++,
817961SNatalie.Li@Sun.COM 		    id->i_sidattr.sid, SMB_IDMAP_USER);
827961SNatalie.Li@Sun.COM 
837961SNatalie.Li@Sun.COM 		if (stat != IDMAP_SUCCESS)
847961SNatalie.Li@Sun.COM 			return (stat);
857961SNatalie.Li@Sun.COM 
867961SNatalie.Li@Sun.COM 		/* Owner SID */
877961SNatalie.Li@Sun.COM 		id = token->tkn_owner;
887961SNatalie.Li@Sun.COM 		sim->sim_id = &id->i_id;
897961SNatalie.Li@Sun.COM 		stat = smb_idmap_batch_getid(sib->sib_idmaph, sim++,
907961SNatalie.Li@Sun.COM 		    id->i_sidattr.sid, SMB_IDMAP_USER);
917961SNatalie.Li@Sun.COM 
927961SNatalie.Li@Sun.COM 		if (stat != IDMAP_SUCCESS)
937961SNatalie.Li@Sun.COM 			return (stat);
947961SNatalie.Li@Sun.COM 	}
957961SNatalie.Li@Sun.COM 
967961SNatalie.Li@Sun.COM 	/* Primary Group SID */
977961SNatalie.Li@Sun.COM 	id = token->tkn_primary_grp;
987961SNatalie.Li@Sun.COM 	sim->sim_id = &id->i_id;
997961SNatalie.Li@Sun.COM 	stat = smb_idmap_batch_getid(sib->sib_idmaph, sim++,
1007961SNatalie.Li@Sun.COM 	    id->i_sidattr.sid, SMB_IDMAP_GROUP);
1017961SNatalie.Li@Sun.COM 
1027961SNatalie.Li@Sun.COM 	if (stat != IDMAP_SUCCESS)
1037961SNatalie.Li@Sun.COM 		return (stat);
1047961SNatalie.Li@Sun.COM 
1057961SNatalie.Li@Sun.COM 	/* Other Windows Group SIDs */
1067961SNatalie.Li@Sun.COM 	for (i = 0; i < token->tkn_win_grps->wg_count; i++, sim++) {
1077961SNatalie.Li@Sun.COM 		id = &token->tkn_win_grps->wg_groups[i];
1087961SNatalie.Li@Sun.COM 		sim->sim_id = &id->i_id;
1097961SNatalie.Li@Sun.COM 		stat = smb_idmap_batch_getid(sib->sib_idmaph, sim,
1107961SNatalie.Li@Sun.COM 		    id->i_sidattr.sid, SMB_IDMAP_GROUP);
1117961SNatalie.Li@Sun.COM 
1127961SNatalie.Li@Sun.COM 		if (stat != IDMAP_SUCCESS)
1137961SNatalie.Li@Sun.COM 			break;
1147961SNatalie.Li@Sun.COM 	}
1157961SNatalie.Li@Sun.COM 
1167961SNatalie.Li@Sun.COM 	return (stat);
1177961SNatalie.Li@Sun.COM }
1187961SNatalie.Li@Sun.COM 
1197961SNatalie.Li@Sun.COM /*
1207961SNatalie.Li@Sun.COM  * smb_token_sids2ids
1217961SNatalie.Li@Sun.COM  *
1227961SNatalie.Li@Sun.COM  * This will map all the SIDs of the access token to UIDs/GIDs.
1237961SNatalie.Li@Sun.COM  *
1247961SNatalie.Li@Sun.COM  * Returns 0 upon success.  Otherwise, returns -1.
1257961SNatalie.Li@Sun.COM  */
1267961SNatalie.Li@Sun.COM static int
1277961SNatalie.Li@Sun.COM smb_token_sids2ids(smb_token_t *token)
1287961SNatalie.Li@Sun.COM {
1297961SNatalie.Li@Sun.COM 	idmap_stat stat;
1307961SNatalie.Li@Sun.COM 	int nmaps, retries = 0;
1317961SNatalie.Li@Sun.COM 	smb_idmap_batch_t sib;
1327961SNatalie.Li@Sun.COM 
1337961SNatalie.Li@Sun.COM 	/*
1347961SNatalie.Li@Sun.COM 	 * Number of idmap lookups: user SID, owner SID, primary group SID,
1357961SNatalie.Li@Sun.COM 	 * and all Windows group SIDs
1367961SNatalie.Li@Sun.COM 	 */
1377961SNatalie.Li@Sun.COM 	if (token->tkn_flags & SMB_ATF_ANON)
1387961SNatalie.Li@Sun.COM 		/*
1397961SNatalie.Li@Sun.COM 		 * Don't include user and owner SID, they're Anonymous
1407961SNatalie.Li@Sun.COM 		 */
1417961SNatalie.Li@Sun.COM 		nmaps = 1;
1427961SNatalie.Li@Sun.COM 	else
1437961SNatalie.Li@Sun.COM 		nmaps = 3;
1447961SNatalie.Li@Sun.COM 
1457961SNatalie.Li@Sun.COM 	nmaps += token->tkn_win_grps->wg_count;
1467961SNatalie.Li@Sun.COM 
1477961SNatalie.Li@Sun.COM 	do {
1487961SNatalie.Li@Sun.COM 		stat = smb_idmap_batch_create(&sib, nmaps, SMB_IDMAP_SID2ID);
1497961SNatalie.Li@Sun.COM 		if (stat != IDMAP_SUCCESS)
1507961SNatalie.Li@Sun.COM 			return (-1);
1517961SNatalie.Li@Sun.COM 
1527961SNatalie.Li@Sun.COM 		stat = smb_token_idmap(token, &sib);
1537961SNatalie.Li@Sun.COM 		if (stat != IDMAP_SUCCESS) {
1547961SNatalie.Li@Sun.COM 			smb_idmap_batch_destroy(&sib);
1557961SNatalie.Li@Sun.COM 			return (-1);
1567961SNatalie.Li@Sun.COM 		}
1577961SNatalie.Li@Sun.COM 
1587961SNatalie.Li@Sun.COM 		stat = smb_idmap_batch_getmappings(&sib);
1597961SNatalie.Li@Sun.COM 		smb_idmap_batch_destroy(&sib);
1607961SNatalie.Li@Sun.COM 		if (stat == IDMAP_ERR_RPC_HANDLE)
1617961SNatalie.Li@Sun.COM 			if (smb_idmap_restart() < 0)
1627961SNatalie.Li@Sun.COM 				break;
1637961SNatalie.Li@Sun.COM 	} while (stat == IDMAP_ERR_RPC_HANDLE && retries++ < 3);
1647961SNatalie.Li@Sun.COM 
1657961SNatalie.Li@Sun.COM 	return (stat == IDMAP_SUCCESS ? 0 : -1);
1667961SNatalie.Li@Sun.COM }
1677961SNatalie.Li@Sun.COM 
1687961SNatalie.Li@Sun.COM /*
1697961SNatalie.Li@Sun.COM  * smb_token_create_pxgrps
1707961SNatalie.Li@Sun.COM  *
1717961SNatalie.Li@Sun.COM  * Setup the POSIX group membership of the access token if the given UID is
1727961SNatalie.Li@Sun.COM  * a POSIX UID (non-ephemeral). Both the user's primary group and
1737961SNatalie.Li@Sun.COM  * supplementary groups will be added to the POSIX group array of the access
1747961SNatalie.Li@Sun.COM  * token.
1757961SNatalie.Li@Sun.COM  */
1767961SNatalie.Li@Sun.COM static smb_posix_grps_t *
1777961SNatalie.Li@Sun.COM smb_token_create_pxgrps(uid_t uid)
1787961SNatalie.Li@Sun.COM {
1797961SNatalie.Li@Sun.COM 	struct passwd *pwd;
1807961SNatalie.Li@Sun.COM 	smb_posix_grps_t *pgrps;
1817961SNatalie.Li@Sun.COM 	int ngroups_max, num;
1827961SNatalie.Li@Sun.COM 	gid_t *gids;
1837961SNatalie.Li@Sun.COM 
1847961SNatalie.Li@Sun.COM 	if ((ngroups_max = sysconf(_SC_NGROUPS_MAX)) < 0) {
1857961SNatalie.Li@Sun.COM 		syslog(LOG_ERR, "smb_logon: failed to get _SC_NGROUPS_MAX");
1867961SNatalie.Li@Sun.COM 		return (NULL);
1877961SNatalie.Li@Sun.COM 	}
1887961SNatalie.Li@Sun.COM 
1897961SNatalie.Li@Sun.COM 	pwd = getpwuid(uid);
1907961SNatalie.Li@Sun.COM 	if (pwd == NULL) {
1917961SNatalie.Li@Sun.COM 		pgrps = malloc(sizeof (smb_posix_grps_t));
1927961SNatalie.Li@Sun.COM 		if (pgrps == NULL)
1937961SNatalie.Li@Sun.COM 			return (NULL);
1947961SNatalie.Li@Sun.COM 
1957961SNatalie.Li@Sun.COM 		pgrps->pg_ngrps = 0;
1967961SNatalie.Li@Sun.COM 		return (pgrps);
1977961SNatalie.Li@Sun.COM 	}
1987961SNatalie.Li@Sun.COM 
1997961SNatalie.Li@Sun.COM 	if (pwd->pw_name == NULL) {
2007961SNatalie.Li@Sun.COM 		pgrps = malloc(sizeof (smb_posix_grps_t));
2017961SNatalie.Li@Sun.COM 		if (pgrps == NULL)
2027961SNatalie.Li@Sun.COM 			return (NULL);
2037961SNatalie.Li@Sun.COM 
2047961SNatalie.Li@Sun.COM 		pgrps->pg_ngrps = 1;
2057961SNatalie.Li@Sun.COM 		pgrps->pg_grps[0] = pwd->pw_gid;
2067961SNatalie.Li@Sun.COM 		return (pgrps);
2077961SNatalie.Li@Sun.COM 	}
2087961SNatalie.Li@Sun.COM 
2097961SNatalie.Li@Sun.COM 	gids = (gid_t *)malloc(ngroups_max * sizeof (gid_t));
2107961SNatalie.Li@Sun.COM 	if (gids == NULL) {
2117961SNatalie.Li@Sun.COM 		return (NULL);
2127961SNatalie.Li@Sun.COM 	}
2137961SNatalie.Li@Sun.COM 	bzero(gids, ngroups_max * sizeof (gid_t));
2147961SNatalie.Li@Sun.COM 
2157961SNatalie.Li@Sun.COM 	gids[0] = pwd->pw_gid;
2167961SNatalie.Li@Sun.COM 
2177961SNatalie.Li@Sun.COM 	/*
2187961SNatalie.Li@Sun.COM 	 * Setup the groups starting at index 1 (the last arg)
2197961SNatalie.Li@Sun.COM 	 * of gids array.
2207961SNatalie.Li@Sun.COM 	 */
2217961SNatalie.Li@Sun.COM 	num = _getgroupsbymember(pwd->pw_name, gids, ngroups_max, 1);
2227961SNatalie.Li@Sun.COM 
2237961SNatalie.Li@Sun.COM 	if (num == -1) {
2247961SNatalie.Li@Sun.COM 		syslog(LOG_ERR, "smb_logon: unable "
2257961SNatalie.Li@Sun.COM 		    "to get user's supplementary groups");
2267961SNatalie.Li@Sun.COM 		num = 1;
2277961SNatalie.Li@Sun.COM 	}
2287961SNatalie.Li@Sun.COM 
2297961SNatalie.Li@Sun.COM 	pgrps = (smb_posix_grps_t *)malloc(SMB_POSIX_GRPS_SIZE(num));
2307961SNatalie.Li@Sun.COM 	if (pgrps) {
2317961SNatalie.Li@Sun.COM 		pgrps->pg_ngrps = num;
2327961SNatalie.Li@Sun.COM 		bcopy(gids, pgrps->pg_grps, num * sizeof (gid_t));
2337961SNatalie.Li@Sun.COM 	}
2347961SNatalie.Li@Sun.COM 
2357961SNatalie.Li@Sun.COM 	free(gids);
2367961SNatalie.Li@Sun.COM 	return (pgrps);
2377961SNatalie.Li@Sun.COM }
2387961SNatalie.Li@Sun.COM 
2397961SNatalie.Li@Sun.COM /*
2407961SNatalie.Li@Sun.COM  * smb_token_destroy
2417961SNatalie.Li@Sun.COM  *
2427961SNatalie.Li@Sun.COM  * Release all of the memory associated with a token structure. Ensure
2437961SNatalie.Li@Sun.COM  * that the token has been unlinked before calling.
2447961SNatalie.Li@Sun.COM  */
2457961SNatalie.Li@Sun.COM void
2467961SNatalie.Li@Sun.COM smb_token_destroy(smb_token_t *token)
2477961SNatalie.Li@Sun.COM {
2487961SNatalie.Li@Sun.COM 	smb_win_grps_t *groups;
2497961SNatalie.Li@Sun.COM 	int i;
2507961SNatalie.Li@Sun.COM 
2517961SNatalie.Li@Sun.COM 	if (token == NULL)
2527961SNatalie.Li@Sun.COM 		return;
2537961SNatalie.Li@Sun.COM 
2547961SNatalie.Li@Sun.COM 	if (token->tkn_user) {
2557961SNatalie.Li@Sun.COM 		free(token->tkn_user->i_sidattr.sid);
2567961SNatalie.Li@Sun.COM 		free(token->tkn_user);
2577961SNatalie.Li@Sun.COM 	}
2587961SNatalie.Li@Sun.COM 
2597961SNatalie.Li@Sun.COM 	if (token->tkn_owner) {
2607961SNatalie.Li@Sun.COM 		free(token->tkn_owner->i_sidattr.sid);
2617961SNatalie.Li@Sun.COM 		free(token->tkn_owner);
2627961SNatalie.Li@Sun.COM 	}
2637961SNatalie.Li@Sun.COM 
2647961SNatalie.Li@Sun.COM 	if (token->tkn_primary_grp) {
2657961SNatalie.Li@Sun.COM 		free(token->tkn_primary_grp->i_sidattr.sid);
2667961SNatalie.Li@Sun.COM 		free(token->tkn_primary_grp);
2677961SNatalie.Li@Sun.COM 	}
2687961SNatalie.Li@Sun.COM 
2697961SNatalie.Li@Sun.COM 	if ((groups = token->tkn_win_grps) != NULL) {
2707961SNatalie.Li@Sun.COM 		for (i = 0; i < groups->wg_count; ++i)
2717961SNatalie.Li@Sun.COM 			free(groups->wg_groups[i].i_sidattr.sid);
2727961SNatalie.Li@Sun.COM 		free(groups);
2737961SNatalie.Li@Sun.COM 	}
2747961SNatalie.Li@Sun.COM 
2757961SNatalie.Li@Sun.COM 	smb_privset_free(token->tkn_privileges);
2767961SNatalie.Li@Sun.COM 
2777961SNatalie.Li@Sun.COM 	free(token->tkn_posix_grps);
2787961SNatalie.Li@Sun.COM 	free(token->tkn_account_name);
2797961SNatalie.Li@Sun.COM 	free(token->tkn_domain_name);
2807961SNatalie.Li@Sun.COM 	free(token->tkn_session_key);
2817961SNatalie.Li@Sun.COM 
2827961SNatalie.Li@Sun.COM 	free(token);
2837961SNatalie.Li@Sun.COM }
2847961SNatalie.Li@Sun.COM 
2857961SNatalie.Li@Sun.COM static smb_id_t *
2867961SNatalie.Li@Sun.COM smb_token_create_id(smb_sid_t *sid)
2877961SNatalie.Li@Sun.COM {
2887961SNatalie.Li@Sun.COM 	smb_id_t *id;
2897961SNatalie.Li@Sun.COM 
2907961SNatalie.Li@Sun.COM 	if ((id = malloc(sizeof (smb_id_t))) == NULL)
2917961SNatalie.Li@Sun.COM 		return (NULL);
2927961SNatalie.Li@Sun.COM 
2937961SNatalie.Li@Sun.COM 	id->i_id = (uid_t)-1;
2947961SNatalie.Li@Sun.COM 	id->i_sidattr.attrs = 7;
2957961SNatalie.Li@Sun.COM 	id->i_sidattr.sid = smb_sid_dup(sid);
2967961SNatalie.Li@Sun.COM 
2977961SNatalie.Li@Sun.COM 	if (id->i_sidattr.sid == NULL) {
2987961SNatalie.Li@Sun.COM 		free(id);
2997961SNatalie.Li@Sun.COM 		id = NULL;
3007961SNatalie.Li@Sun.COM 	}
3017961SNatalie.Li@Sun.COM 
3027961SNatalie.Li@Sun.COM 	return (id);
3037961SNatalie.Li@Sun.COM }
3047961SNatalie.Li@Sun.COM 
3057961SNatalie.Li@Sun.COM /*
3067961SNatalie.Li@Sun.COM  * Token owner should be set to local Administrators group
3077961SNatalie.Li@Sun.COM  * in two cases:
3087961SNatalie.Li@Sun.COM  *   1. The logged on user is a member of Domain Admins group
3097961SNatalie.Li@Sun.COM  *   2. he/she is a member of local Administrators group
3107961SNatalie.Li@Sun.COM  */
3117961SNatalie.Li@Sun.COM static smb_id_t *
3127961SNatalie.Li@Sun.COM smb_token_create_owner(smb_userinfo_t *user_info)
3137961SNatalie.Li@Sun.COM {
3147961SNatalie.Li@Sun.COM #ifdef SMB_SUPPORT_GROUP_OWNER
3157961SNatalie.Li@Sun.COM 	smb_sid_t *owner_sid;
3167961SNatalie.Li@Sun.COM 	smb_wka_t *wka;
3177961SNatalie.Li@Sun.COM 
3187961SNatalie.Li@Sun.COM 	if (user_info->flags & SMB_UINFO_FLAG_ADMIN) {
3197961SNatalie.Li@Sun.COM 		wka = smb_wka_lookup("Administrators");
3207961SNatalie.Li@Sun.COM 		assert(wka);
3217961SNatalie.Li@Sun.COM 		owner_sid = wka->wka_binsid;
3227961SNatalie.Li@Sun.COM 	} else {
3237961SNatalie.Li@Sun.COM 		owner_sid = user_info->user_sid;
3247961SNatalie.Li@Sun.COM 	}
3257961SNatalie.Li@Sun.COM 
3267961SNatalie.Li@Sun.COM 	return (smb_token_create_id(owner_sid));
3277961SNatalie.Li@Sun.COM #endif
3287961SNatalie.Li@Sun.COM 	return (smb_token_create_id(user_info->user_sid));
3297961SNatalie.Li@Sun.COM }
3307961SNatalie.Li@Sun.COM 
3317961SNatalie.Li@Sun.COM static smb_privset_t *
3327961SNatalie.Li@Sun.COM smb_token_create_privs(smb_userinfo_t *user_info)
3337961SNatalie.Li@Sun.COM {
3347961SNatalie.Li@Sun.COM 	smb_privset_t *privs;
3357961SNatalie.Li@Sun.COM 	smb_giter_t gi;
3367961SNatalie.Li@Sun.COM 	smb_group_t grp;
3377961SNatalie.Li@Sun.COM 	int rc;
3387961SNatalie.Li@Sun.COM 
3397961SNatalie.Li@Sun.COM 	privs = smb_privset_new();
3407961SNatalie.Li@Sun.COM 	if (privs == NULL)
3417961SNatalie.Li@Sun.COM 		return (NULL);
3427961SNatalie.Li@Sun.COM 
3437961SNatalie.Li@Sun.COM 	if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
3447961SNatalie.Li@Sun.COM 		smb_privset_free(privs);
3457961SNatalie.Li@Sun.COM 		return (NULL);
3467961SNatalie.Li@Sun.COM 	}
3477961SNatalie.Li@Sun.COM 
3487961SNatalie.Li@Sun.COM 	while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) {
3497961SNatalie.Li@Sun.COM 		if (smb_lgrp_is_member(&grp, user_info->user_sid)) {
3507961SNatalie.Li@Sun.COM 			smb_privset_merge(privs, grp.sg_privs);
3517961SNatalie.Li@Sun.COM 		}
3527961SNatalie.Li@Sun.COM 		smb_lgrp_free(&grp);
3537961SNatalie.Li@Sun.COM 	}
3547961SNatalie.Li@Sun.COM 	smb_lgrp_iterclose(&gi);
3557961SNatalie.Li@Sun.COM 
3567961SNatalie.Li@Sun.COM 	if (user_info->flags & SMB_UINFO_FLAG_ADMIN) {
3577961SNatalie.Li@Sun.COM 		rc = smb_lgrp_getbyname("Administrators", &grp);
3587961SNatalie.Li@Sun.COM 		if (rc == SMB_LGRP_SUCCESS) {
3597961SNatalie.Li@Sun.COM 			smb_privset_merge(privs, grp.sg_privs);
3607961SNatalie.Li@Sun.COM 			smb_lgrp_free(&grp);
3617961SNatalie.Li@Sun.COM 		}
3627961SNatalie.Li@Sun.COM 
3637961SNatalie.Li@Sun.COM 		/*
3647961SNatalie.Li@Sun.COM 		 * This privilege is required to view/edit SACL
3657961SNatalie.Li@Sun.COM 		 */
3667961SNatalie.Li@Sun.COM 		smb_privset_enable(privs, SE_SECURITY_LUID);
3677961SNatalie.Li@Sun.COM 	}
3687961SNatalie.Li@Sun.COM 
3697961SNatalie.Li@Sun.COM 	return (privs);
3707961SNatalie.Li@Sun.COM }
3717961SNatalie.Li@Sun.COM 
3727961SNatalie.Li@Sun.COM static void
3737961SNatalie.Li@Sun.COM smb_token_set_flags(smb_token_t *token, smb_userinfo_t *user_info)
3747961SNatalie.Li@Sun.COM {
3757961SNatalie.Li@Sun.COM 	smb_wka_t *wka;
3767961SNatalie.Li@Sun.COM 
3777961SNatalie.Li@Sun.COM 	if (user_info->flags & SMB_UINFO_FLAG_ANON) {
3787961SNatalie.Li@Sun.COM 		token->tkn_flags |= SMB_ATF_ANON;
3797961SNatalie.Li@Sun.COM 		return;
3807961SNatalie.Li@Sun.COM 	}
3817961SNatalie.Li@Sun.COM 
3827961SNatalie.Li@Sun.COM 	if (user_info->rid == DOMAIN_USER_RID_GUEST) {
3837961SNatalie.Li@Sun.COM 		token->tkn_flags |= SMB_ATF_GUEST;
3847961SNatalie.Li@Sun.COM 		return;
3857961SNatalie.Li@Sun.COM 	}
3867961SNatalie.Li@Sun.COM 
3877961SNatalie.Li@Sun.COM 	wka = smb_wka_lookup("Administrators");
3887961SNatalie.Li@Sun.COM 	if (wka->wka_binsid && smb_token_is_member(token, wka->wka_binsid))
3897961SNatalie.Li@Sun.COM 		token->tkn_flags |= SMB_ATF_ADMIN;
3907961SNatalie.Li@Sun.COM 
3917961SNatalie.Li@Sun.COM 	wka = smb_wka_lookup("Power Users");
3927961SNatalie.Li@Sun.COM 	if (wka->wka_binsid && smb_token_is_member(token, wka->wka_binsid))
3937961SNatalie.Li@Sun.COM 		token->tkn_flags |= SMB_ATF_POWERUSER;
3947961SNatalie.Li@Sun.COM 
3957961SNatalie.Li@Sun.COM 	wka = smb_wka_lookup("Backup Operators");
3967961SNatalie.Li@Sun.COM 	if (wka->wka_binsid && smb_token_is_member(token, wka->wka_binsid))
3977961SNatalie.Li@Sun.COM 		token->tkn_flags |= SMB_ATF_BACKUPOP;
3987961SNatalie.Li@Sun.COM 
3997961SNatalie.Li@Sun.COM }
4007961SNatalie.Li@Sun.COM 
4017961SNatalie.Li@Sun.COM /*
4027961SNatalie.Li@Sun.COM  * smb_token_create
4037961SNatalie.Li@Sun.COM  *
4047961SNatalie.Li@Sun.COM  * Build an access token based on the given user information (user_info).
4057961SNatalie.Li@Sun.COM  *
4067961SNatalie.Li@Sun.COM  * If everything is successful, a pointer to an access token is
4077961SNatalie.Li@Sun.COM  * returned. Otherwise a null pointer is returned.
4087961SNatalie.Li@Sun.COM  */
4097961SNatalie.Li@Sun.COM static smb_token_t *
4107961SNatalie.Li@Sun.COM smb_token_create(smb_userinfo_t *user_info)
4117961SNatalie.Li@Sun.COM {
4127961SNatalie.Li@Sun.COM 	smb_token_t *token;
4137961SNatalie.Li@Sun.COM 
4147961SNatalie.Li@Sun.COM 	if (user_info->sid_name_use != SidTypeUser)
4157961SNatalie.Li@Sun.COM 		return (NULL);
4167961SNatalie.Li@Sun.COM 
4177961SNatalie.Li@Sun.COM 	token = (smb_token_t *)malloc(sizeof (smb_token_t));
4187961SNatalie.Li@Sun.COM 	if (token == NULL) {
4197961SNatalie.Li@Sun.COM 		syslog(LOG_ERR, "smb_token_create: resource shortage");
4207961SNatalie.Li@Sun.COM 		return (NULL);
4217961SNatalie.Li@Sun.COM 	}
4227961SNatalie.Li@Sun.COM 	bzero(token, sizeof (smb_token_t));
4237961SNatalie.Li@Sun.COM 
4247961SNatalie.Li@Sun.COM 	/* User */
4257961SNatalie.Li@Sun.COM 	token->tkn_user = smb_token_create_id(user_info->user_sid);
4267961SNatalie.Li@Sun.COM 	if (token->tkn_user == NULL) {
4277961SNatalie.Li@Sun.COM 		smb_token_destroy(token);
4287961SNatalie.Li@Sun.COM 		return (NULL);
4297961SNatalie.Li@Sun.COM 	}
4307961SNatalie.Li@Sun.COM 
4317961SNatalie.Li@Sun.COM 	/* Owner */
4327961SNatalie.Li@Sun.COM 	token->tkn_owner = smb_token_create_owner(user_info);
4337961SNatalie.Li@Sun.COM 	if (token->tkn_owner == NULL) {
4347961SNatalie.Li@Sun.COM 		smb_token_destroy(token);
4357961SNatalie.Li@Sun.COM 		return (NULL);
4367961SNatalie.Li@Sun.COM 	}
4377961SNatalie.Li@Sun.COM 
4387961SNatalie.Li@Sun.COM 	/* Primary Group */
4397961SNatalie.Li@Sun.COM 	token->tkn_primary_grp = smb_token_create_id(user_info->pgrp_sid);
4407961SNatalie.Li@Sun.COM 	if (token->tkn_primary_grp == NULL) {
4417961SNatalie.Li@Sun.COM 		smb_token_destroy(token);
4427961SNatalie.Li@Sun.COM 		return (NULL);
4437961SNatalie.Li@Sun.COM 	}
4447961SNatalie.Li@Sun.COM 
4457961SNatalie.Li@Sun.COM 	/* Privileges */
4467961SNatalie.Li@Sun.COM 	token->tkn_privileges = smb_token_create_privs(user_info);
4477961SNatalie.Li@Sun.COM 	if (token->tkn_privileges == NULL) {
4487961SNatalie.Li@Sun.COM 		smb_token_destroy(token);
4497961SNatalie.Li@Sun.COM 		return (NULL);
4507961SNatalie.Li@Sun.COM 	}
4517961SNatalie.Li@Sun.COM 
4527961SNatalie.Li@Sun.COM 	/* Windows Groups */
4537961SNatalie.Li@Sun.COM 	token->tkn_win_grps = smb_token_create_wingrps(user_info);
4547961SNatalie.Li@Sun.COM 
4557961SNatalie.Li@Sun.COM 	smb_token_set_flags(token, user_info);
4567961SNatalie.Li@Sun.COM 
4577961SNatalie.Li@Sun.COM 	/*
4587961SNatalie.Li@Sun.COM 	 * IMPORTANT
4597961SNatalie.Li@Sun.COM 	 *
4607961SNatalie.Li@Sun.COM 	 * This function has to be called after all the SIDs in the
4617961SNatalie.Li@Sun.COM 	 * token are setup (i.e. user, owner, primary and supplementary
4627961SNatalie.Li@Sun.COM 	 * groups) and before setting up Solaris groups.
4637961SNatalie.Li@Sun.COM 	 */
4647961SNatalie.Li@Sun.COM 	if (smb_token_sids2ids(token) != 0) {
4657961SNatalie.Li@Sun.COM 		syslog(LOG_ERR, "%s\\%s: idmap failed",
4667961SNatalie.Li@Sun.COM 		    (user_info->domain_name) ? user_info->domain_name : "",
4677961SNatalie.Li@Sun.COM 		    (user_info->name) ? user_info->name : "");
4687961SNatalie.Li@Sun.COM 		smb_token_destroy(token);
4697961SNatalie.Li@Sun.COM 		return (NULL);
4707961SNatalie.Li@Sun.COM 	}
4717961SNatalie.Li@Sun.COM 
4727961SNatalie.Li@Sun.COM 	/* Solaris Groups */
4737961SNatalie.Li@Sun.COM 	token->tkn_posix_grps = smb_token_create_pxgrps(token->tkn_user->i_id);
4747961SNatalie.Li@Sun.COM 
4757961SNatalie.Li@Sun.COM 	if (user_info->session_key) {
4767961SNatalie.Li@Sun.COM 		token->tkn_session_key = malloc(sizeof (smb_session_key_t));
4777961SNatalie.Li@Sun.COM 		if (token->tkn_session_key == NULL) {
4787961SNatalie.Li@Sun.COM 			smb_token_destroy(token);
4797961SNatalie.Li@Sun.COM 			return (NULL);
4807961SNatalie.Li@Sun.COM 		}
4817961SNatalie.Li@Sun.COM 
4827961SNatalie.Li@Sun.COM 		(void) memcpy(token->tkn_session_key,
4837961SNatalie.Li@Sun.COM 		    user_info->session_key, sizeof (smb_session_key_t));
4847961SNatalie.Li@Sun.COM 	}
4857961SNatalie.Li@Sun.COM 
4867961SNatalie.Li@Sun.COM 	token->tkn_account_name = strdup(user_info->name);
4877961SNatalie.Li@Sun.COM 	token->tkn_domain_name = strdup(user_info->domain_name);
4887961SNatalie.Li@Sun.COM 
4897961SNatalie.Li@Sun.COM 	if (!smb_token_is_valid(token)) {
4907961SNatalie.Li@Sun.COM 		smb_token_destroy(token);
4917961SNatalie.Li@Sun.COM 		return (NULL);
4927961SNatalie.Li@Sun.COM 	}
4937961SNatalie.Li@Sun.COM 
4947961SNatalie.Li@Sun.COM 	return (token);
4957961SNatalie.Li@Sun.COM }
4967961SNatalie.Li@Sun.COM 
4977961SNatalie.Li@Sun.COM /*
4987961SNatalie.Li@Sun.COM  * smb_token_create_wingrps
4997961SNatalie.Li@Sun.COM  *
5007961SNatalie.Li@Sun.COM  * This private function supports smb_token_create() by mapping the group
5017961SNatalie.Li@Sun.COM  * information in the user_info structure to the form required in an
5027961SNatalie.Li@Sun.COM  * access token. The main difference is that the user_info contains
5037961SNatalie.Li@Sun.COM  * RIDs while and access token contains full SIDs. Memory allocated
5047961SNatalie.Li@Sun.COM  * here will be deallocated as part of smb_token_destroy().
5057961SNatalie.Li@Sun.COM  *
5067961SNatalie.Li@Sun.COM  * If everything is successful, a pointer to a smb_win_grps_t
5077961SNatalie.Li@Sun.COM  * structure is returned. Otherwise a null pointer is returned.
5087961SNatalie.Li@Sun.COM  */
5097961SNatalie.Li@Sun.COM static smb_win_grps_t *
5107961SNatalie.Li@Sun.COM smb_token_create_wingrps(smb_userinfo_t *user_info)
5117961SNatalie.Li@Sun.COM {
5127961SNatalie.Li@Sun.COM 	static char *wk_grps[] =
5137961SNatalie.Li@Sun.COM 		{"Authenticated Users", "NETWORK", "Administrators"};
5147961SNatalie.Li@Sun.COM 	smb_win_grps_t *tkn_grps;
5157961SNatalie.Li@Sun.COM 	smb_sid_attrs_t *dlg_grps;
5167961SNatalie.Li@Sun.COM 	smb_rid_attrs_t *g_grps;
5177961SNatalie.Li@Sun.COM 	smb_sid_attrs_t *grp;
5187961SNatalie.Li@Sun.COM 	smb_sid_t *builtin_sid;
5197961SNatalie.Li@Sun.COM 	smb_giter_t gi;
5207961SNatalie.Li@Sun.COM 	smb_group_t lgrp;
5217961SNatalie.Li@Sun.COM 	uint32_t n_gg, n_lg, n_dlg, n_wg;
5227961SNatalie.Li@Sun.COM 	uint32_t i, j;
5237961SNatalie.Li@Sun.COM 	int size, count;
5247961SNatalie.Li@Sun.COM 
5257961SNatalie.Li@Sun.COM 	if (user_info == NULL)
5267961SNatalie.Li@Sun.COM 		return (NULL);
5277961SNatalie.Li@Sun.COM 
5287961SNatalie.Li@Sun.COM 	n_gg = user_info->n_groups;		/* Global Groups */
5297961SNatalie.Li@Sun.COM 	n_dlg = user_info->n_other_grps;	/* Domain Local Groups */
5307961SNatalie.Li@Sun.COM 
5317961SNatalie.Li@Sun.COM 	/* Local Groups */
5327961SNatalie.Li@Sun.COM 	(void) smb_lgrp_numbymember(user_info->user_sid, (int *)&n_lg);
5337961SNatalie.Li@Sun.COM 
5347961SNatalie.Li@Sun.COM 	/* Well known Groups */
5357961SNatalie.Li@Sun.COM 	if ((user_info->flags & SMB_UINFO_FLAG_ADMIN) == SMB_UINFO_FLAG_DADMIN)
5367961SNatalie.Li@Sun.COM 		/* if user is a domain admin but not a local admin */
5377961SNatalie.Li@Sun.COM 		n_wg = 3;
5387961SNatalie.Li@Sun.COM 	else if (user_info->flags & SMB_UINFO_FLAG_ANON)
5397961SNatalie.Li@Sun.COM 		n_wg = 0;
5407961SNatalie.Li@Sun.COM 	else
5417961SNatalie.Li@Sun.COM 		n_wg = 2;
5427961SNatalie.Li@Sun.COM 
5437961SNatalie.Li@Sun.COM 	count = n_gg + n_dlg + n_lg + n_wg;
5447961SNatalie.Li@Sun.COM 	size = sizeof (smb_win_grps_t) + (count * sizeof (smb_id_t));
5457961SNatalie.Li@Sun.COM 
5467961SNatalie.Li@Sun.COM 	if ((tkn_grps = malloc(size)) == NULL)
5477961SNatalie.Li@Sun.COM 		return (NULL);
5487961SNatalie.Li@Sun.COM 	bzero(tkn_grps, size);
5497961SNatalie.Li@Sun.COM 
5507961SNatalie.Li@Sun.COM 	/* Add global groups */
5517961SNatalie.Li@Sun.COM 	g_grps = user_info->groups;
5527961SNatalie.Li@Sun.COM 	for (i = 0; i < n_gg; i++) {
5537961SNatalie.Li@Sun.COM 		grp = &tkn_grps->wg_groups[i].i_sidattr;
5547961SNatalie.Li@Sun.COM 		grp->sid = smb_sid_splice(user_info->domain_sid, g_grps[i].rid);
5557961SNatalie.Li@Sun.COM 		if (grp->sid == NULL)
5567961SNatalie.Li@Sun.COM 			break;
5577961SNatalie.Li@Sun.COM 		grp->attrs = g_grps[i].attributes;
5587961SNatalie.Li@Sun.COM 	}
5597961SNatalie.Li@Sun.COM 
5607961SNatalie.Li@Sun.COM 	if (n_gg == 0) {
5617961SNatalie.Li@Sun.COM 		/*
5627961SNatalie.Li@Sun.COM 		 * if there's no global group should add the
5637961SNatalie.Li@Sun.COM 		 * primary group.
5647961SNatalie.Li@Sun.COM 		 */
5657961SNatalie.Li@Sun.COM 		grp = &tkn_grps->wg_groups[i].i_sidattr;
5667961SNatalie.Li@Sun.COM 		grp->sid = smb_sid_dup(user_info->pgrp_sid);
5677961SNatalie.Li@Sun.COM 		if (grp->sid != NULL) {
5687961SNatalie.Li@Sun.COM 			grp->attrs = 0x7;
5697961SNatalie.Li@Sun.COM 			i++;
5707961SNatalie.Li@Sun.COM 		}
5717961SNatalie.Li@Sun.COM 	}
5727961SNatalie.Li@Sun.COM 
5737961SNatalie.Li@Sun.COM 	/* Add domain local groups */
5747961SNatalie.Li@Sun.COM 	dlg_grps = user_info->other_grps;
5757961SNatalie.Li@Sun.COM 	for (j = 0; j < n_dlg; j++, i++) {
5767961SNatalie.Li@Sun.COM 		grp = &tkn_grps->wg_groups[i].i_sidattr;
5777961SNatalie.Li@Sun.COM 		grp->sid = smb_sid_dup(dlg_grps[j].sid);
5787961SNatalie.Li@Sun.COM 		if (grp->sid == NULL)
5797961SNatalie.Li@Sun.COM 			break;
5807961SNatalie.Li@Sun.COM 		grp->attrs = dlg_grps[j].attrs;
5817961SNatalie.Li@Sun.COM 	}
5827961SNatalie.Li@Sun.COM 
5837961SNatalie.Li@Sun.COM 	/* Add local groups */
5847961SNatalie.Li@Sun.COM 	if (n_lg && (smb_lgrp_iteropen(&gi) == SMB_LGRP_SUCCESS)) {
5857961SNatalie.Li@Sun.COM 		j = 0;
5867961SNatalie.Li@Sun.COM 		while (smb_lgrp_iterate(&gi, &lgrp) == SMB_LGRP_SUCCESS) {
5877961SNatalie.Li@Sun.COM 			if ((j < n_lg) &&
5887961SNatalie.Li@Sun.COM 			    smb_lgrp_is_member(&lgrp, user_info->user_sid)) {
5897961SNatalie.Li@Sun.COM 				grp = &tkn_grps->wg_groups[i].i_sidattr;
5907961SNatalie.Li@Sun.COM 				grp->sid = smb_sid_dup(lgrp.sg_id.gs_sid);
5917961SNatalie.Li@Sun.COM 				if (grp->sid == NULL) {
5927961SNatalie.Li@Sun.COM 					smb_lgrp_free(&lgrp);
5937961SNatalie.Li@Sun.COM 					break;
5947961SNatalie.Li@Sun.COM 				}
5957961SNatalie.Li@Sun.COM 				grp->attrs = lgrp.sg_attr;
5967961SNatalie.Li@Sun.COM 				i++;
5977961SNatalie.Li@Sun.COM 				j++;
5987961SNatalie.Li@Sun.COM 			}
5997961SNatalie.Li@Sun.COM 			smb_lgrp_free(&lgrp);
6007961SNatalie.Li@Sun.COM 		}
6017961SNatalie.Li@Sun.COM 		smb_lgrp_iterclose(&gi);
6027961SNatalie.Li@Sun.COM 	}
6037961SNatalie.Li@Sun.COM 
6047961SNatalie.Li@Sun.COM 	/* Add well known groups */
6057961SNatalie.Li@Sun.COM 	for (j = 0; j < n_wg; j++, i++) {
6067961SNatalie.Li@Sun.COM 		builtin_sid = smb_wka_lookup_name(wk_grps[j], NULL);
6077961SNatalie.Li@Sun.COM 		if (builtin_sid == NULL)
6087961SNatalie.Li@Sun.COM 			break;
6097961SNatalie.Li@Sun.COM 		tkn_grps->wg_groups[i].i_sidattr.sid = builtin_sid;
6107961SNatalie.Li@Sun.COM 		tkn_grps->wg_groups[i].i_sidattr.attrs = 0x7;
6117961SNatalie.Li@Sun.COM 	}
6127961SNatalie.Li@Sun.COM 
6137961SNatalie.Li@Sun.COM 	tkn_grps->wg_count = i;
6147961SNatalie.Li@Sun.COM 	return (tkn_grps);
6157961SNatalie.Li@Sun.COM }
6167961SNatalie.Li@Sun.COM 
6177961SNatalie.Li@Sun.COM /*
6187961SNatalie.Li@Sun.COM  * smb_logon
6197961SNatalie.Li@Sun.COM  *
6207961SNatalie.Li@Sun.COM  * Performs user authentication and creates a token if the
6217961SNatalie.Li@Sun.COM  * authentication is successful.
6227961SNatalie.Li@Sun.COM  *
6237961SNatalie.Li@Sun.COM  * Returns pointer to the created token.
6247961SNatalie.Li@Sun.COM  */
6257961SNatalie.Li@Sun.COM smb_token_t *
6267961SNatalie.Li@Sun.COM smb_logon(netr_client_t *clnt)
6277961SNatalie.Li@Sun.COM {
6287961SNatalie.Li@Sun.COM 	smb_token_t *token = NULL;
6297961SNatalie.Li@Sun.COM 	smb_userinfo_t *uinfo;
6307961SNatalie.Li@Sun.COM 	uint32_t status;
6317961SNatalie.Li@Sun.COM 
6327961SNatalie.Li@Sun.COM 	if ((uinfo = mlsvc_alloc_user_info()) == 0)
6337961SNatalie.Li@Sun.COM 		return (NULL);
6347961SNatalie.Li@Sun.COM 
6357961SNatalie.Li@Sun.COM 	switch (clnt->flags) {
6367961SNatalie.Li@Sun.COM 	case NETR_CFLG_DOMAIN:
6377961SNatalie.Li@Sun.COM 		/* Pass through authentication with DC */
6387961SNatalie.Li@Sun.COM 		status = smb_logon_domain(clnt, uinfo);
6397961SNatalie.Li@Sun.COM 		break;
6407961SNatalie.Li@Sun.COM 
6417961SNatalie.Li@Sun.COM 	case NETR_CFLG_LOCAL:
6427961SNatalie.Li@Sun.COM 		/* Local authentication */
6437961SNatalie.Li@Sun.COM 		status = smb_logon_local(clnt, uinfo);
6447961SNatalie.Li@Sun.COM 		break;
6457961SNatalie.Li@Sun.COM 
6467961SNatalie.Li@Sun.COM 	case NETR_CFLG_ANON:
6477961SNatalie.Li@Sun.COM 		/* Anonymous user; no authentication */
6487961SNatalie.Li@Sun.COM 		status = smb_logon_none(clnt, uinfo);
6497961SNatalie.Li@Sun.COM 		break;
6507961SNatalie.Li@Sun.COM 
6517961SNatalie.Li@Sun.COM 	default:
6527961SNatalie.Li@Sun.COM 		status = NT_STATUS_INVALID_PARAMETER;
6537961SNatalie.Li@Sun.COM 		break;
6547961SNatalie.Li@Sun.COM 	}
6557961SNatalie.Li@Sun.COM 
6567961SNatalie.Li@Sun.COM 	if (status == NT_STATUS_SUCCESS)
6577961SNatalie.Li@Sun.COM 		token = smb_token_create(uinfo);
6587961SNatalie.Li@Sun.COM 
6597961SNatalie.Li@Sun.COM 	mlsvc_free_user_info(uinfo);
6607961SNatalie.Li@Sun.COM 	return (token);
6617961SNatalie.Li@Sun.COM }
6627961SNatalie.Li@Sun.COM 
6637961SNatalie.Li@Sun.COM /*
6647961SNatalie.Li@Sun.COM  * smb_logon_domain
6657961SNatalie.Li@Sun.COM  *
6667961SNatalie.Li@Sun.COM  * Performs pass through authentication with PDC.
6677961SNatalie.Li@Sun.COM  */
6687961SNatalie.Li@Sun.COM static uint32_t
6697961SNatalie.Li@Sun.COM smb_logon_domain(netr_client_t *clnt, smb_userinfo_t *uinfo)
6707961SNatalie.Li@Sun.COM {
6717961SNatalie.Li@Sun.COM 	uint32_t status;
6727961SNatalie.Li@Sun.COM 
6737961SNatalie.Li@Sun.COM 	if ((status = netlogon_logon(clnt, uinfo)) != 0) {
6747961SNatalie.Li@Sun.COM 		if (status == NT_STATUS_CANT_ACCESS_DOMAIN_INFO) {
6757961SNatalie.Li@Sun.COM 			if ((status = netlogon_logon(clnt, uinfo)) != 0) {
6767961SNatalie.Li@Sun.COM 				syslog(LOG_INFO, "SmbLogon[%s\\%s]: %s",
6777961SNatalie.Li@Sun.COM 				    clnt->domain, clnt->username,
6787961SNatalie.Li@Sun.COM 				    xlate_nt_status(status));
6797961SNatalie.Li@Sun.COM 				return (status);
6807961SNatalie.Li@Sun.COM 			}
6817961SNatalie.Li@Sun.COM 		}
6827961SNatalie.Li@Sun.COM 	}
6837961SNatalie.Li@Sun.COM 
6847961SNatalie.Li@Sun.COM 	return (status);
6857961SNatalie.Li@Sun.COM }
6867961SNatalie.Li@Sun.COM 
6877961SNatalie.Li@Sun.COM /*
6887961SNatalie.Li@Sun.COM  * smb_logon_local
6897961SNatalie.Li@Sun.COM  *
6907961SNatalie.Li@Sun.COM  * Check to see if connected user has an entry in the local
6917961SNatalie.Li@Sun.COM  * smbpasswd database. If it has, tries both LM hash and NT
6927961SNatalie.Li@Sun.COM  * hash with user's password(s) to authenticate the user.
6937961SNatalie.Li@Sun.COM  */
6947961SNatalie.Li@Sun.COM static uint32_t
6957961SNatalie.Li@Sun.COM smb_logon_local(netr_client_t *clnt, smb_userinfo_t *uinfo)
6967961SNatalie.Li@Sun.COM {
6977961SNatalie.Li@Sun.COM 	smb_passwd_t smbpw;
6987961SNatalie.Li@Sun.COM 	boolean_t lm_ok, nt_ok;
6997961SNatalie.Li@Sun.COM 	uint32_t status;
7007961SNatalie.Li@Sun.COM 
701*8474SJose.Borrego@Sun.COM 	if (smb_pwd_getpwnam(clnt->username, &smbpw) == NULL) {
7027961SNatalie.Li@Sun.COM 		/*
7037961SNatalie.Li@Sun.COM 		 * If user doesn't have entry either in smbpasswd
7047961SNatalie.Li@Sun.COM 		 * or passwd it's considered as an invalid user.
7057961SNatalie.Li@Sun.COM 		 */
7067961SNatalie.Li@Sun.COM 		status = NT_STATUS_NO_SUCH_USER;
7077961SNatalie.Li@Sun.COM 		syslog(LOG_NOTICE, "SmbLogon[%s\\%s]: %s",
7087961SNatalie.Li@Sun.COM 		    clnt->domain, clnt->username,
7097961SNatalie.Li@Sun.COM 		    xlate_nt_status(status));
7107961SNatalie.Li@Sun.COM 		return (status);
7117961SNatalie.Li@Sun.COM 	}
7127961SNatalie.Li@Sun.COM 	if (smbpw.pw_flags & SMB_PWF_DISABLE)
7137961SNatalie.Li@Sun.COM 		return (NT_STATUS_ACCOUNT_DISABLED);
7147961SNatalie.Li@Sun.COM 
7157961SNatalie.Li@Sun.COM 	nt_ok = lm_ok = B_FALSE;
7167961SNatalie.Li@Sun.COM 	if ((smbpw.pw_flags & SMB_PWF_LM) &&
7177961SNatalie.Li@Sun.COM 	    (clnt->lm_password.lm_password_len != 0)) {
7187961SNatalie.Li@Sun.COM 		lm_ok = smb_auth_validate_lm(
7197961SNatalie.Li@Sun.COM 		    clnt->challenge_key.challenge_key_val,
7207961SNatalie.Li@Sun.COM 		    clnt->challenge_key.challenge_key_len,
7217961SNatalie.Li@Sun.COM 		    &smbpw,
7227961SNatalie.Li@Sun.COM 		    clnt->lm_password.lm_password_val,
7237961SNatalie.Li@Sun.COM 		    clnt->lm_password.lm_password_len,
7247961SNatalie.Li@Sun.COM 		    clnt->domain,
7257961SNatalie.Li@Sun.COM 		    clnt->username);
7267961SNatalie.Li@Sun.COM 		uinfo->session_key = NULL;
7277961SNatalie.Li@Sun.COM 	}
7287961SNatalie.Li@Sun.COM 
7297961SNatalie.Li@Sun.COM 	if (!lm_ok && (clnt->nt_password.nt_password_len != 0)) {
7307961SNatalie.Li@Sun.COM 		if ((uinfo->session_key =
7317961SNatalie.Li@Sun.COM 		    malloc(SMBAUTH_SESSION_KEY_SZ)) == NULL)
7327961SNatalie.Li@Sun.COM 			return (NT_STATUS_NO_MEMORY);
7337961SNatalie.Li@Sun.COM 		nt_ok = smb_auth_validate_nt(
7347961SNatalie.Li@Sun.COM 		    clnt->challenge_key.challenge_key_val,
7357961SNatalie.Li@Sun.COM 		    clnt->challenge_key.challenge_key_len,
7367961SNatalie.Li@Sun.COM 		    &smbpw,
7377961SNatalie.Li@Sun.COM 		    clnt->nt_password.nt_password_val,
7387961SNatalie.Li@Sun.COM 		    clnt->nt_password.nt_password_len,
7397961SNatalie.Li@Sun.COM 		    clnt->domain,
7407961SNatalie.Li@Sun.COM 		    clnt->username,
7417961SNatalie.Li@Sun.COM 		    (uchar_t *)uinfo->session_key);
7427961SNatalie.Li@Sun.COM 	}
7437961SNatalie.Li@Sun.COM 
7447961SNatalie.Li@Sun.COM 	if (!nt_ok && !lm_ok) {
7457961SNatalie.Li@Sun.COM 		status = NT_STATUS_WRONG_PASSWORD;
7467961SNatalie.Li@Sun.COM 		syslog(LOG_NOTICE, "SmbLogon[%s\\%s]: %s",
7477961SNatalie.Li@Sun.COM 		    clnt->domain, clnt->username,
7487961SNatalie.Li@Sun.COM 		    xlate_nt_status(status));
7497961SNatalie.Li@Sun.COM 		return (status);
7507961SNatalie.Li@Sun.COM 	}
7517961SNatalie.Li@Sun.COM 
7527961SNatalie.Li@Sun.COM 	status = smb_setup_luinfo(uinfo, clnt, smbpw.pw_uid);
7537961SNatalie.Li@Sun.COM 	return (status);
7547961SNatalie.Li@Sun.COM }
7557961SNatalie.Li@Sun.COM 
7567961SNatalie.Li@Sun.COM /*
7577961SNatalie.Li@Sun.COM  * smb_logon_none
7587961SNatalie.Li@Sun.COM  *
7597961SNatalie.Li@Sun.COM  * Setup user information for anonymous user.
7607961SNatalie.Li@Sun.COM  * No authentication is required.
7617961SNatalie.Li@Sun.COM  */
7627961SNatalie.Li@Sun.COM static uint32_t
7637961SNatalie.Li@Sun.COM smb_logon_none(netr_client_t *clnt, smb_userinfo_t *uinfo)
7647961SNatalie.Li@Sun.COM {
7657961SNatalie.Li@Sun.COM 	return (smb_setup_luinfo(uinfo, clnt, (uid_t)-1));
7667961SNatalie.Li@Sun.COM }
7677961SNatalie.Li@Sun.COM 
7687961SNatalie.Li@Sun.COM /*
7697961SNatalie.Li@Sun.COM  * smb_setup_luinfo
7707961SNatalie.Li@Sun.COM  *
7717961SNatalie.Li@Sun.COM  * Setup local user information based on the client information and
7727961SNatalie.Li@Sun.COM  * user's record in the local password file.
7737961SNatalie.Li@Sun.COM  */
7747961SNatalie.Li@Sun.COM static uint32_t
7757961SNatalie.Li@Sun.COM smb_setup_luinfo(smb_userinfo_t *lui, netr_client_t *clnt, uid_t uid)
7767961SNatalie.Li@Sun.COM {
7777961SNatalie.Li@Sun.COM 	idmap_stat stat;
7787961SNatalie.Li@Sun.COM 	smb_idmap_batch_t sib;
7797961SNatalie.Li@Sun.COM 	smb_idmap_t *umap, *gmap;
7807961SNatalie.Li@Sun.COM 	smb_group_t grp;
7817961SNatalie.Li@Sun.COM 	struct passwd pw;
7827961SNatalie.Li@Sun.COM 	char pwbuf[1024];
7837961SNatalie.Li@Sun.COM 	char nbname[NETBIOS_NAME_SZ];
7847961SNatalie.Li@Sun.COM 
7857961SNatalie.Li@Sun.COM 	(void) smb_getnetbiosname(nbname, sizeof (nbname));
7867961SNatalie.Li@Sun.COM 	lui->sid_name_use = SidTypeUser;
7877961SNatalie.Li@Sun.COM 	lui->domain_sid = smb_sid_dup(nt_domain_local_sid());
7887961SNatalie.Li@Sun.COM 	lui->name = strdup(clnt->username);
7897961SNatalie.Li@Sun.COM 	lui->domain_name = strdup(nbname);
7907961SNatalie.Li@Sun.COM 	lui->n_groups = 0;
7917961SNatalie.Li@Sun.COM 	lui->groups = NULL;
7927961SNatalie.Li@Sun.COM 	lui->n_other_grps = 0;
7937961SNatalie.Li@Sun.COM 	lui->other_grps = NULL;
7947961SNatalie.Li@Sun.COM 	lui->flags = 0;
7957961SNatalie.Li@Sun.COM 
7967961SNatalie.Li@Sun.COM 	if (lui->name == NULL || lui->domain_name == NULL ||
7977961SNatalie.Li@Sun.COM 	    lui->domain_sid == NULL)
7987961SNatalie.Li@Sun.COM 		return (NT_STATUS_INVALID_PARAMETER);
7997961SNatalie.Li@Sun.COM 
8007961SNatalie.Li@Sun.COM 	if (clnt->flags & NETR_CFLG_ANON) {
8017961SNatalie.Li@Sun.COM 		lui->user_sid = smb_wka_lookup_name("Anonymous", NULL);
8027961SNatalie.Li@Sun.COM 		lui->pgrp_sid = smb_wka_lookup_name("Anonymous", NULL);
8037961SNatalie.Li@Sun.COM 		lui->flags = SMB_UINFO_FLAG_ANON;
8047961SNatalie.Li@Sun.COM 
8057961SNatalie.Li@Sun.COM 		if (lui->user_sid == NULL || lui->pgrp_sid == NULL)
8067961SNatalie.Li@Sun.COM 			return (NT_STATUS_NO_MEMORY);
8077961SNatalie.Li@Sun.COM 
8087961SNatalie.Li@Sun.COM 		return (NT_STATUS_SUCCESS);
8097961SNatalie.Li@Sun.COM 	}
8107961SNatalie.Li@Sun.COM 
8117961SNatalie.Li@Sun.COM 	if (getpwuid_r(uid, &pw, pwbuf, sizeof (pwbuf)) == NULL)
8127961SNatalie.Li@Sun.COM 		return (NT_STATUS_NO_SUCH_USER);
8137961SNatalie.Li@Sun.COM 
8147961SNatalie.Li@Sun.COM 	/* Get the SID for user's uid & gid */
8157961SNatalie.Li@Sun.COM 	stat = smb_idmap_batch_create(&sib, 2, SMB_IDMAP_ID2SID);
8167961SNatalie.Li@Sun.COM 	if (stat != IDMAP_SUCCESS) {
8177961SNatalie.Li@Sun.COM 		return (NT_STATUS_INTERNAL_ERROR);
8187961SNatalie.Li@Sun.COM 	}
8197961SNatalie.Li@Sun.COM 
8207961SNatalie.Li@Sun.COM 	umap = &sib.sib_maps[0];
8217961SNatalie.Li@Sun.COM 	stat = smb_idmap_batch_getsid(sib.sib_idmaph, umap, pw.pw_uid,
8227961SNatalie.Li@Sun.COM 	    SMB_IDMAP_USER);
8237961SNatalie.Li@Sun.COM 
8247961SNatalie.Li@Sun.COM 	if (stat != IDMAP_SUCCESS) {
8257961SNatalie.Li@Sun.COM 		smb_idmap_batch_destroy(&sib);
8267961SNatalie.Li@Sun.COM 		return (NT_STATUS_INTERNAL_ERROR);
8277961SNatalie.Li@Sun.COM 	}
8287961SNatalie.Li@Sun.COM 
8297961SNatalie.Li@Sun.COM 	gmap = &sib.sib_maps[1];
8307961SNatalie.Li@Sun.COM 	stat = smb_idmap_batch_getsid(sib.sib_idmaph, gmap, pw.pw_gid,
8317961SNatalie.Li@Sun.COM 	    SMB_IDMAP_GROUP);
8327961SNatalie.Li@Sun.COM 
8337961SNatalie.Li@Sun.COM 	if (stat != IDMAP_SUCCESS) {
8347961SNatalie.Li@Sun.COM 		smb_idmap_batch_destroy(&sib);
8357961SNatalie.Li@Sun.COM 		return (NT_STATUS_INTERNAL_ERROR);
8367961SNatalie.Li@Sun.COM 	}
8377961SNatalie.Li@Sun.COM 
8387961SNatalie.Li@Sun.COM 	stat = smb_idmap_batch_getmappings(&sib);
8397961SNatalie.Li@Sun.COM 
8407961SNatalie.Li@Sun.COM 	if (stat != IDMAP_SUCCESS) {
8417961SNatalie.Li@Sun.COM 		return (NT_STATUS_INTERNAL_ERROR);
8427961SNatalie.Li@Sun.COM 	}
8437961SNatalie.Li@Sun.COM 
8447961SNatalie.Li@Sun.COM 	lui->rid = umap->sim_rid;
8457961SNatalie.Li@Sun.COM 	lui->user_sid = smb_sid_dup(umap->sim_sid);
8467961SNatalie.Li@Sun.COM 
8477961SNatalie.Li@Sun.COM 	lui->primary_group_rid = gmap->sim_rid;
8487961SNatalie.Li@Sun.COM 	lui->pgrp_sid = smb_sid_dup(gmap->sim_sid);
8497961SNatalie.Li@Sun.COM 
8507961SNatalie.Li@Sun.COM 	smb_idmap_batch_destroy(&sib);
8517961SNatalie.Li@Sun.COM 
8527961SNatalie.Li@Sun.COM 	if ((lui->user_sid == NULL) || (lui->pgrp_sid == NULL))
8537961SNatalie.Li@Sun.COM 		return (NT_STATUS_NO_MEMORY);
8547961SNatalie.Li@Sun.COM 
8557961SNatalie.Li@Sun.COM 	if (smb_lgrp_getbyname("Administrators", &grp) == SMB_LGRP_SUCCESS) {
8567961SNatalie.Li@Sun.COM 		if (smb_lgrp_is_member(&grp, lui->user_sid))
8577961SNatalie.Li@Sun.COM 			lui->flags = SMB_UINFO_FLAG_LADMIN;
8587961SNatalie.Li@Sun.COM 		smb_lgrp_free(&grp);
8597961SNatalie.Li@Sun.COM 	}
8607961SNatalie.Li@Sun.COM 
8617961SNatalie.Li@Sun.COM 	return (NT_STATUS_SUCCESS);
8627961SNatalie.Li@Sun.COM }
8637961SNatalie.Li@Sun.COM 
8647961SNatalie.Li@Sun.COM /*
8657961SNatalie.Li@Sun.COM  * smb_token_is_valid
8667961SNatalie.Li@Sun.COM  *
8677961SNatalie.Li@Sun.COM  * check to see if specified fields of the given access
8687961SNatalie.Li@Sun.COM  * token are valid.
8697961SNatalie.Li@Sun.COM  * Returns 1 if all of them are valid; otherwise 0.
8707961SNatalie.Li@Sun.COM  */
8717961SNatalie.Li@Sun.COM static int
8727961SNatalie.Li@Sun.COM smb_token_is_valid(smb_token_t *token)
8737961SNatalie.Li@Sun.COM {
8747961SNatalie.Li@Sun.COM 	int valid;
8757961SNatalie.Li@Sun.COM 
8767961SNatalie.Li@Sun.COM 	valid = (token->tkn_user != 0) &&
8777961SNatalie.Li@Sun.COM 	    (token->tkn_user->i_sidattr.sid != 0) &&
8787961SNatalie.Li@Sun.COM 	    (token->tkn_privileges != 0) &&
8797961SNatalie.Li@Sun.COM 	    (token->tkn_win_grps != 0) &&
8807961SNatalie.Li@Sun.COM 	    (token->tkn_owner != 0) &&
8817961SNatalie.Li@Sun.COM 	    (token->tkn_owner->i_sidattr.sid != 0) &&
8827961SNatalie.Li@Sun.COM 	    (token->tkn_primary_grp != 0) &&
8837961SNatalie.Li@Sun.COM 	    (token->tkn_primary_grp->i_sidattr.sid != 0);
8847961SNatalie.Li@Sun.COM 
8857961SNatalie.Li@Sun.COM 	return (valid);
8867961SNatalie.Li@Sun.COM }
8877961SNatalie.Li@Sun.COM 
8887961SNatalie.Li@Sun.COM /*
8897961SNatalie.Li@Sun.COM  * smb_token_user_sid
8907961SNatalie.Li@Sun.COM  *
8917961SNatalie.Li@Sun.COM  * Return a pointer to the user SID in the specified token. A null
8927961SNatalie.Li@Sun.COM  * pointer indicates an error.
8937961SNatalie.Li@Sun.COM  */
8947961SNatalie.Li@Sun.COM static smb_sid_t *
8957961SNatalie.Li@Sun.COM smb_token_user_sid(smb_token_t *token)
8967961SNatalie.Li@Sun.COM {
8977961SNatalie.Li@Sun.COM 	if (token && token->tkn_user)
8987961SNatalie.Li@Sun.COM 		return ((token)->tkn_user->i_sidattr.sid);
8997961SNatalie.Li@Sun.COM 
9007961SNatalie.Li@Sun.COM 	return (NULL);
9017961SNatalie.Li@Sun.COM }
9027961SNatalie.Li@Sun.COM 
9037961SNatalie.Li@Sun.COM /*
9047961SNatalie.Li@Sun.COM  * smb_token_group_sid
9057961SNatalie.Li@Sun.COM  *
9067961SNatalie.Li@Sun.COM  * Return a pointer to the group SID as indicated by the iterator.
9077961SNatalie.Li@Sun.COM  * Setting the iterator to 0 before calling this function will return
9087961SNatalie.Li@Sun.COM  * the first group, which will always be the primary group. The
9097961SNatalie.Li@Sun.COM  * iterator will be incremented before returning the SID so that this
9107961SNatalie.Li@Sun.COM  * function can be used to cycle through the groups. The caller can
9117961SNatalie.Li@Sun.COM  * adjust the iterator as required between calls to obtain any specific
9127961SNatalie.Li@Sun.COM  * group.
9137961SNatalie.Li@Sun.COM  *
9147961SNatalie.Li@Sun.COM  * On success a pointer to the appropriate group SID will be returned.
9157961SNatalie.Li@Sun.COM  * Otherwise a null pointer will be returned.
9167961SNatalie.Li@Sun.COM  */
9177961SNatalie.Li@Sun.COM static smb_sid_t *
9187961SNatalie.Li@Sun.COM smb_token_group_sid(smb_token_t *token, int *iterator)
9197961SNatalie.Li@Sun.COM {
9207961SNatalie.Li@Sun.COM 	smb_win_grps_t *groups;
9217961SNatalie.Li@Sun.COM 	int index;
9227961SNatalie.Li@Sun.COM 
9237961SNatalie.Li@Sun.COM 	if (token == NULL || iterator == NULL) {
9247961SNatalie.Li@Sun.COM 		return (NULL);
9257961SNatalie.Li@Sun.COM 	}
9267961SNatalie.Li@Sun.COM 
9277961SNatalie.Li@Sun.COM 	if ((groups = token->tkn_win_grps) == NULL) {
9287961SNatalie.Li@Sun.COM 		return (NULL);
9297961SNatalie.Li@Sun.COM 	}
9307961SNatalie.Li@Sun.COM 
9317961SNatalie.Li@Sun.COM 	index = *iterator;
9327961SNatalie.Li@Sun.COM 
9337961SNatalie.Li@Sun.COM 	if (index < 0 || index >= groups->wg_count) {
9347961SNatalie.Li@Sun.COM 		return (NULL);
9357961SNatalie.Li@Sun.COM 	}
9367961SNatalie.Li@Sun.COM 
9377961SNatalie.Li@Sun.COM 	++(*iterator);
9387961SNatalie.Li@Sun.COM 	return (groups->wg_groups[index].i_sidattr.sid);
9397961SNatalie.Li@Sun.COM }
9407961SNatalie.Li@Sun.COM 
9417961SNatalie.Li@Sun.COM /*
9427961SNatalie.Li@Sun.COM  * smb_token_is_member
9437961SNatalie.Li@Sun.COM  *
9447961SNatalie.Li@Sun.COM  * This function will determine whether or not the specified SID is a
9457961SNatalie.Li@Sun.COM  * member of a token. The user SID and all group SIDs are tested.
9467961SNatalie.Li@Sun.COM  * Returns 1 if the SID is a member of the token. Otherwise returns 0.
9477961SNatalie.Li@Sun.COM  */
9487961SNatalie.Li@Sun.COM static int
9497961SNatalie.Li@Sun.COM smb_token_is_member(smb_token_t *token, smb_sid_t *sid)
9507961SNatalie.Li@Sun.COM {
9517961SNatalie.Li@Sun.COM 	smb_sid_t *tsid;
9527961SNatalie.Li@Sun.COM 	int iterator = 0;
9537961SNatalie.Li@Sun.COM 
9547961SNatalie.Li@Sun.COM 	tsid = smb_token_user_sid(token);
9557961SNatalie.Li@Sun.COM 	while (tsid) {
9567961SNatalie.Li@Sun.COM 		if (smb_sid_cmp(tsid, sid))
9577961SNatalie.Li@Sun.COM 			return (1);
9587961SNatalie.Li@Sun.COM 
9597961SNatalie.Li@Sun.COM 		tsid = smb_token_group_sid(token, &iterator);
9607961SNatalie.Li@Sun.COM 	}
9617961SNatalie.Li@Sun.COM 
9627961SNatalie.Li@Sun.COM 	return (0);
9637961SNatalie.Li@Sun.COM }
9647961SNatalie.Li@Sun.COM 
9657961SNatalie.Li@Sun.COM /*
9667961SNatalie.Li@Sun.COM  * smb_token_log
9677961SNatalie.Li@Sun.COM  *
9687961SNatalie.Li@Sun.COM  * Diagnostic routine to write the contents of a token to the log.
9697961SNatalie.Li@Sun.COM  */
9707961SNatalie.Li@Sun.COM void
9717961SNatalie.Li@Sun.COM smb_token_log(smb_token_t *token)
9727961SNatalie.Li@Sun.COM {
9737961SNatalie.Li@Sun.COM 	smb_win_grps_t *w_grps;
9747961SNatalie.Li@Sun.COM 	smb_posix_grps_t *x_grps;
9757961SNatalie.Li@Sun.COM 	smb_sid_attrs_t *grp;
9767961SNatalie.Li@Sun.COM 	char sidstr[SMB_SID_STRSZ];
9777961SNatalie.Li@Sun.COM 	int i;
9787961SNatalie.Li@Sun.COM 
9797961SNatalie.Li@Sun.COM 	if (token == NULL)
9807961SNatalie.Li@Sun.COM 		return;
9817961SNatalie.Li@Sun.COM 
9827961SNatalie.Li@Sun.COM 	syslog(LOG_DEBUG, "Token for %s\\%s",
9837961SNatalie.Li@Sun.COM 	    (token->tkn_domain_name) ? token->tkn_domain_name : "-NULL-",
9847961SNatalie.Li@Sun.COM 	    (token->tkn_account_name) ? token->tkn_account_name : "-NULL-");
9857961SNatalie.Li@Sun.COM 
9867961SNatalie.Li@Sun.COM 	syslog(LOG_DEBUG, "   User->Attr: %d",
9877961SNatalie.Li@Sun.COM 	    token->tkn_user->i_sidattr.attrs);
9887961SNatalie.Li@Sun.COM 	smb_sid_tostr((smb_sid_t *)token->tkn_user->i_sidattr.sid, sidstr);
9897961SNatalie.Li@Sun.COM 	syslog(LOG_DEBUG, "   User->Sid: %s (id=%u)",
9907961SNatalie.Li@Sun.COM 	    sidstr, token->tkn_user->i_id);
9917961SNatalie.Li@Sun.COM 
9927961SNatalie.Li@Sun.COM 	smb_sid_tostr((smb_sid_t *)token->tkn_owner->i_sidattr.sid, sidstr);
9937961SNatalie.Li@Sun.COM 	syslog(LOG_DEBUG, "   Ownr->Sid: %s (id=%u)",
9947961SNatalie.Li@Sun.COM 	    sidstr, token->tkn_owner->i_id);
9957961SNatalie.Li@Sun.COM 
9967961SNatalie.Li@Sun.COM 	smb_sid_tostr((smb_sid_t *)token->tkn_primary_grp->i_sidattr.sid,
9977961SNatalie.Li@Sun.COM 	    sidstr);
9987961SNatalie.Li@Sun.COM 	syslog(LOG_DEBUG, "   PGrp->Sid: %s (id=%u)",
9997961SNatalie.Li@Sun.COM 	    sidstr, token->tkn_primary_grp->i_id);
10007961SNatalie.Li@Sun.COM 
10017961SNatalie.Li@Sun.COM 	w_grps = token->tkn_win_grps;
10027961SNatalie.Li@Sun.COM 	if (w_grps) {
10037961SNatalie.Li@Sun.COM 		syslog(LOG_DEBUG, "   Windows groups: %d",
10047961SNatalie.Li@Sun.COM 		    w_grps->wg_count);
10057961SNatalie.Li@Sun.COM 
10067961SNatalie.Li@Sun.COM 		for (i = 0; i < w_grps->wg_count; ++i) {
10077961SNatalie.Li@Sun.COM 			grp = &w_grps->wg_groups[i].i_sidattr;
10087961SNatalie.Li@Sun.COM 			syslog(LOG_DEBUG,
10097961SNatalie.Li@Sun.COM 			    "    Grp[%d].Attr:%d", i, grp->attrs);
10107961SNatalie.Li@Sun.COM 			if (w_grps->wg_groups[i].i_sidattr.sid) {
10117961SNatalie.Li@Sun.COM 				smb_sid_tostr((smb_sid_t *)grp->sid, sidstr);
10127961SNatalie.Li@Sun.COM 				syslog(LOG_DEBUG,
10137961SNatalie.Li@Sun.COM 				    "    Grp[%d].Sid: %s (id=%u)", i, sidstr,
10147961SNatalie.Li@Sun.COM 				    w_grps->wg_groups[i].i_id);
10157961SNatalie.Li@Sun.COM 			}
10167961SNatalie.Li@Sun.COM 		}
10177961SNatalie.Li@Sun.COM 	}
10187961SNatalie.Li@Sun.COM 	else
10197961SNatalie.Li@Sun.COM 		syslog(LOG_DEBUG, "   No Windows groups");
10207961SNatalie.Li@Sun.COM 
10217961SNatalie.Li@Sun.COM 	x_grps = token->tkn_posix_grps;
10227961SNatalie.Li@Sun.COM 	if (x_grps) {
10237961SNatalie.Li@Sun.COM 		syslog(LOG_DEBUG, "   Solaris groups: %d",
10247961SNatalie.Li@Sun.COM 		    x_grps->pg_ngrps);
10257961SNatalie.Li@Sun.COM 		for (i = 0; i < x_grps->pg_ngrps; i++)
10267961SNatalie.Li@Sun.COM 			syslog(LOG_DEBUG, "    %u",
10277961SNatalie.Li@Sun.COM 			    x_grps->pg_grps[i]);
10287961SNatalie.Li@Sun.COM 	}
10297961SNatalie.Li@Sun.COM 	else
10307961SNatalie.Li@Sun.COM 		syslog(LOG_DEBUG, "   No Solaris groups");
10317961SNatalie.Li@Sun.COM 
10327961SNatalie.Li@Sun.COM 	if (token->tkn_privileges)
10337961SNatalie.Li@Sun.COM 		smb_privset_log(token->tkn_privileges);
10347961SNatalie.Li@Sun.COM 	else
10357961SNatalie.Li@Sun.COM 		syslog(LOG_DEBUG, "   No privileges");
10367961SNatalie.Li@Sun.COM }
1037