xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c (revision 7961:4b5e3051f38b)
1*7961SNatalie.Li@Sun.COM /*
2*7961SNatalie.Li@Sun.COM  * CDDL HEADER START
3*7961SNatalie.Li@Sun.COM  *
4*7961SNatalie.Li@Sun.COM  * The contents of this file are subject to the terms of the
5*7961SNatalie.Li@Sun.COM  * Common Development and Distribution License (the "License").
6*7961SNatalie.Li@Sun.COM  * You may not use this file except in compliance with the License.
7*7961SNatalie.Li@Sun.COM  *
8*7961SNatalie.Li@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7961SNatalie.Li@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7961SNatalie.Li@Sun.COM  * See the License for the specific language governing permissions
11*7961SNatalie.Li@Sun.COM  * and limitations under the License.
12*7961SNatalie.Li@Sun.COM  *
13*7961SNatalie.Li@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7961SNatalie.Li@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7961SNatalie.Li@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7961SNatalie.Li@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7961SNatalie.Li@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7961SNatalie.Li@Sun.COM  *
19*7961SNatalie.Li@Sun.COM  * CDDL HEADER END
20*7961SNatalie.Li@Sun.COM  */
21*7961SNatalie.Li@Sun.COM /*
22*7961SNatalie.Li@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*7961SNatalie.Li@Sun.COM  * Use is subject to license terms.
24*7961SNatalie.Li@Sun.COM  */
25*7961SNatalie.Li@Sun.COM 
26*7961SNatalie.Li@Sun.COM /*
27*7961SNatalie.Li@Sun.COM  * Security database interface.
28*7961SNatalie.Li@Sun.COM  */
29*7961SNatalie.Li@Sun.COM #include <unistd.h>
30*7961SNatalie.Li@Sun.COM #include <strings.h>
31*7961SNatalie.Li@Sun.COM #include <pwd.h>
32*7961SNatalie.Li@Sun.COM #include <grp.h>
33*7961SNatalie.Li@Sun.COM #include <time.h>
34*7961SNatalie.Li@Sun.COM #include <syslog.h>
35*7961SNatalie.Li@Sun.COM #include <assert.h>
36*7961SNatalie.Li@Sun.COM 
37*7961SNatalie.Li@Sun.COM #include <smbsrv/libsmb.h>
38*7961SNatalie.Li@Sun.COM #include <smbsrv/libmlsvc.h>
39*7961SNatalie.Li@Sun.COM 
40*7961SNatalie.Li@Sun.COM #include <smbsrv/smbinfo.h>
41*7961SNatalie.Li@Sun.COM #include <smbsrv/smb_token.h>
42*7961SNatalie.Li@Sun.COM #include <smbsrv/lsalib.h>
43*7961SNatalie.Li@Sun.COM 
44*7961SNatalie.Li@Sun.COM extern uint32_t netlogon_logon(netr_client_t *clnt, smb_userinfo_t *uinfo);
45*7961SNatalie.Li@Sun.COM static uint32_t smb_logon_domain(netr_client_t *clnt, smb_userinfo_t *uinfo);
46*7961SNatalie.Li@Sun.COM static uint32_t smb_logon_local(netr_client_t *clnt, smb_userinfo_t *uinfo);
47*7961SNatalie.Li@Sun.COM static uint32_t smb_logon_none(netr_client_t *clnt, smb_userinfo_t *uinfo);
48*7961SNatalie.Li@Sun.COM 
49*7961SNatalie.Li@Sun.COM static uint32_t smb_setup_luinfo(smb_userinfo_t *, netr_client_t *, uid_t);
50*7961SNatalie.Li@Sun.COM 
51*7961SNatalie.Li@Sun.COM static int smb_token_is_member(smb_token_t *token, smb_sid_t *sid);
52*7961SNatalie.Li@Sun.COM static int smb_token_is_valid(smb_token_t *token);
53*7961SNatalie.Li@Sun.COM static smb_win_grps_t *smb_token_create_wingrps(smb_userinfo_t *user_info);
54*7961SNatalie.Li@Sun.COM 
55*7961SNatalie.Li@Sun.COM static smb_posix_grps_t *smb_token_create_pxgrps(uid_t uid);
56*7961SNatalie.Li@Sun.COM 
57*7961SNatalie.Li@Sun.COM /* Consolidation private function from Network Repository */
58*7961SNatalie.Li@Sun.COM extern int _getgroupsbymember(const char *, gid_t[], int, int);
59*7961SNatalie.Li@Sun.COM 
60*7961SNatalie.Li@Sun.COM static idmap_stat
61*7961SNatalie.Li@Sun.COM smb_token_idmap(smb_token_t *token, smb_idmap_batch_t *sib)
62*7961SNatalie.Li@Sun.COM {
63*7961SNatalie.Li@Sun.COM 	idmap_stat stat;
64*7961SNatalie.Li@Sun.COM 	smb_idmap_t *sim;
65*7961SNatalie.Li@Sun.COM 	smb_id_t *id;
66*7961SNatalie.Li@Sun.COM 	int i;
67*7961SNatalie.Li@Sun.COM 
68*7961SNatalie.Li@Sun.COM 	if (!token || !sib)
69*7961SNatalie.Li@Sun.COM 		return (IDMAP_ERR_ARG);
70*7961SNatalie.Li@Sun.COM 
71*7961SNatalie.Li@Sun.COM 	sim = sib->sib_maps;
72*7961SNatalie.Li@Sun.COM 
73*7961SNatalie.Li@Sun.COM 	if (token->tkn_flags & SMB_ATF_ANON) {
74*7961SNatalie.Li@Sun.COM 		token->tkn_user->i_id = UID_NOBODY;
75*7961SNatalie.Li@Sun.COM 		token->tkn_owner->i_id = UID_NOBODY;
76*7961SNatalie.Li@Sun.COM 	} else {
77*7961SNatalie.Li@Sun.COM 		/* User SID */
78*7961SNatalie.Li@Sun.COM 		id = token->tkn_user;
79*7961SNatalie.Li@Sun.COM 		sim->sim_id = &id->i_id;
80*7961SNatalie.Li@Sun.COM 		stat = smb_idmap_batch_getid(sib->sib_idmaph, sim++,
81*7961SNatalie.Li@Sun.COM 		    id->i_sidattr.sid, SMB_IDMAP_USER);
82*7961SNatalie.Li@Sun.COM 
83*7961SNatalie.Li@Sun.COM 		if (stat != IDMAP_SUCCESS)
84*7961SNatalie.Li@Sun.COM 			return (stat);
85*7961SNatalie.Li@Sun.COM 
86*7961SNatalie.Li@Sun.COM 		/* Owner SID */
87*7961SNatalie.Li@Sun.COM 		id = token->tkn_owner;
88*7961SNatalie.Li@Sun.COM 		sim->sim_id = &id->i_id;
89*7961SNatalie.Li@Sun.COM 		stat = smb_idmap_batch_getid(sib->sib_idmaph, sim++,
90*7961SNatalie.Li@Sun.COM 		    id->i_sidattr.sid, SMB_IDMAP_USER);
91*7961SNatalie.Li@Sun.COM 
92*7961SNatalie.Li@Sun.COM 		if (stat != IDMAP_SUCCESS)
93*7961SNatalie.Li@Sun.COM 			return (stat);
94*7961SNatalie.Li@Sun.COM 	}
95*7961SNatalie.Li@Sun.COM 
96*7961SNatalie.Li@Sun.COM 	/* Primary Group SID */
97*7961SNatalie.Li@Sun.COM 	id = token->tkn_primary_grp;
98*7961SNatalie.Li@Sun.COM 	sim->sim_id = &id->i_id;
99*7961SNatalie.Li@Sun.COM 	stat = smb_idmap_batch_getid(sib->sib_idmaph, sim++,
100*7961SNatalie.Li@Sun.COM 	    id->i_sidattr.sid, SMB_IDMAP_GROUP);
101*7961SNatalie.Li@Sun.COM 
102*7961SNatalie.Li@Sun.COM 	if (stat != IDMAP_SUCCESS)
103*7961SNatalie.Li@Sun.COM 		return (stat);
104*7961SNatalie.Li@Sun.COM 
105*7961SNatalie.Li@Sun.COM 	/* Other Windows Group SIDs */
106*7961SNatalie.Li@Sun.COM 	for (i = 0; i < token->tkn_win_grps->wg_count; i++, sim++) {
107*7961SNatalie.Li@Sun.COM 		id = &token->tkn_win_grps->wg_groups[i];
108*7961SNatalie.Li@Sun.COM 		sim->sim_id = &id->i_id;
109*7961SNatalie.Li@Sun.COM 		stat = smb_idmap_batch_getid(sib->sib_idmaph, sim,
110*7961SNatalie.Li@Sun.COM 		    id->i_sidattr.sid, SMB_IDMAP_GROUP);
111*7961SNatalie.Li@Sun.COM 
112*7961SNatalie.Li@Sun.COM 		if (stat != IDMAP_SUCCESS)
113*7961SNatalie.Li@Sun.COM 			break;
114*7961SNatalie.Li@Sun.COM 	}
115*7961SNatalie.Li@Sun.COM 
116*7961SNatalie.Li@Sun.COM 	return (stat);
117*7961SNatalie.Li@Sun.COM }
118*7961SNatalie.Li@Sun.COM 
119*7961SNatalie.Li@Sun.COM /*
120*7961SNatalie.Li@Sun.COM  * smb_token_sids2ids
121*7961SNatalie.Li@Sun.COM  *
122*7961SNatalie.Li@Sun.COM  * This will map all the SIDs of the access token to UIDs/GIDs.
123*7961SNatalie.Li@Sun.COM  *
124*7961SNatalie.Li@Sun.COM  * Returns 0 upon success.  Otherwise, returns -1.
125*7961SNatalie.Li@Sun.COM  */
126*7961SNatalie.Li@Sun.COM static int
127*7961SNatalie.Li@Sun.COM smb_token_sids2ids(smb_token_t *token)
128*7961SNatalie.Li@Sun.COM {
129*7961SNatalie.Li@Sun.COM 	idmap_stat stat;
130*7961SNatalie.Li@Sun.COM 	int nmaps, retries = 0;
131*7961SNatalie.Li@Sun.COM 	smb_idmap_batch_t sib;
132*7961SNatalie.Li@Sun.COM 
133*7961SNatalie.Li@Sun.COM 	/*
134*7961SNatalie.Li@Sun.COM 	 * Number of idmap lookups: user SID, owner SID, primary group SID,
135*7961SNatalie.Li@Sun.COM 	 * and all Windows group SIDs
136*7961SNatalie.Li@Sun.COM 	 */
137*7961SNatalie.Li@Sun.COM 	if (token->tkn_flags & SMB_ATF_ANON)
138*7961SNatalie.Li@Sun.COM 		/*
139*7961SNatalie.Li@Sun.COM 		 * Don't include user and owner SID, they're Anonymous
140*7961SNatalie.Li@Sun.COM 		 */
141*7961SNatalie.Li@Sun.COM 		nmaps = 1;
142*7961SNatalie.Li@Sun.COM 	else
143*7961SNatalie.Li@Sun.COM 		nmaps = 3;
144*7961SNatalie.Li@Sun.COM 
145*7961SNatalie.Li@Sun.COM 	nmaps += token->tkn_win_grps->wg_count;
146*7961SNatalie.Li@Sun.COM 
147*7961SNatalie.Li@Sun.COM 	do {
148*7961SNatalie.Li@Sun.COM 		stat = smb_idmap_batch_create(&sib, nmaps, SMB_IDMAP_SID2ID);
149*7961SNatalie.Li@Sun.COM 		if (stat != IDMAP_SUCCESS)
150*7961SNatalie.Li@Sun.COM 			return (-1);
151*7961SNatalie.Li@Sun.COM 
152*7961SNatalie.Li@Sun.COM 		stat = smb_token_idmap(token, &sib);
153*7961SNatalie.Li@Sun.COM 		if (stat != IDMAP_SUCCESS) {
154*7961SNatalie.Li@Sun.COM 			smb_idmap_batch_destroy(&sib);
155*7961SNatalie.Li@Sun.COM 			return (-1);
156*7961SNatalie.Li@Sun.COM 		}
157*7961SNatalie.Li@Sun.COM 
158*7961SNatalie.Li@Sun.COM 		stat = smb_idmap_batch_getmappings(&sib);
159*7961SNatalie.Li@Sun.COM 		smb_idmap_batch_destroy(&sib);
160*7961SNatalie.Li@Sun.COM 		if (stat == IDMAP_ERR_RPC_HANDLE)
161*7961SNatalie.Li@Sun.COM 			if (smb_idmap_restart() < 0)
162*7961SNatalie.Li@Sun.COM 				break;
163*7961SNatalie.Li@Sun.COM 	} while (stat == IDMAP_ERR_RPC_HANDLE && retries++ < 3);
164*7961SNatalie.Li@Sun.COM 
165*7961SNatalie.Li@Sun.COM 	return (stat == IDMAP_SUCCESS ? 0 : -1);
166*7961SNatalie.Li@Sun.COM }
167*7961SNatalie.Li@Sun.COM 
168*7961SNatalie.Li@Sun.COM /*
169*7961SNatalie.Li@Sun.COM  * smb_token_create_pxgrps
170*7961SNatalie.Li@Sun.COM  *
171*7961SNatalie.Li@Sun.COM  * Setup the POSIX group membership of the access token if the given UID is
172*7961SNatalie.Li@Sun.COM  * a POSIX UID (non-ephemeral). Both the user's primary group and
173*7961SNatalie.Li@Sun.COM  * supplementary groups will be added to the POSIX group array of the access
174*7961SNatalie.Li@Sun.COM  * token.
175*7961SNatalie.Li@Sun.COM  */
176*7961SNatalie.Li@Sun.COM static smb_posix_grps_t *
177*7961SNatalie.Li@Sun.COM smb_token_create_pxgrps(uid_t uid)
178*7961SNatalie.Li@Sun.COM {
179*7961SNatalie.Li@Sun.COM 	struct passwd *pwd;
180*7961SNatalie.Li@Sun.COM 	smb_posix_grps_t *pgrps;
181*7961SNatalie.Li@Sun.COM 	int ngroups_max, num;
182*7961SNatalie.Li@Sun.COM 	gid_t *gids;
183*7961SNatalie.Li@Sun.COM 
184*7961SNatalie.Li@Sun.COM 	if ((ngroups_max = sysconf(_SC_NGROUPS_MAX)) < 0) {
185*7961SNatalie.Li@Sun.COM 		syslog(LOG_ERR, "smb_logon: failed to get _SC_NGROUPS_MAX");
186*7961SNatalie.Li@Sun.COM 		return (NULL);
187*7961SNatalie.Li@Sun.COM 	}
188*7961SNatalie.Li@Sun.COM 
189*7961SNatalie.Li@Sun.COM 	pwd = getpwuid(uid);
190*7961SNatalie.Li@Sun.COM 	if (pwd == NULL) {
191*7961SNatalie.Li@Sun.COM 		pgrps = malloc(sizeof (smb_posix_grps_t));
192*7961SNatalie.Li@Sun.COM 		if (pgrps == NULL)
193*7961SNatalie.Li@Sun.COM 			return (NULL);
194*7961SNatalie.Li@Sun.COM 
195*7961SNatalie.Li@Sun.COM 		pgrps->pg_ngrps = 0;
196*7961SNatalie.Li@Sun.COM 		return (pgrps);
197*7961SNatalie.Li@Sun.COM 	}
198*7961SNatalie.Li@Sun.COM 
199*7961SNatalie.Li@Sun.COM 	if (pwd->pw_name == NULL) {
200*7961SNatalie.Li@Sun.COM 		pgrps = malloc(sizeof (smb_posix_grps_t));
201*7961SNatalie.Li@Sun.COM 		if (pgrps == NULL)
202*7961SNatalie.Li@Sun.COM 			return (NULL);
203*7961SNatalie.Li@Sun.COM 
204*7961SNatalie.Li@Sun.COM 		pgrps->pg_ngrps = 1;
205*7961SNatalie.Li@Sun.COM 		pgrps->pg_grps[0] = pwd->pw_gid;
206*7961SNatalie.Li@Sun.COM 		return (pgrps);
207*7961SNatalie.Li@Sun.COM 	}
208*7961SNatalie.Li@Sun.COM 
209*7961SNatalie.Li@Sun.COM 	gids = (gid_t *)malloc(ngroups_max * sizeof (gid_t));
210*7961SNatalie.Li@Sun.COM 	if (gids == NULL) {
211*7961SNatalie.Li@Sun.COM 		return (NULL);
212*7961SNatalie.Li@Sun.COM 	}
213*7961SNatalie.Li@Sun.COM 	bzero(gids, ngroups_max * sizeof (gid_t));
214*7961SNatalie.Li@Sun.COM 
215*7961SNatalie.Li@Sun.COM 	gids[0] = pwd->pw_gid;
216*7961SNatalie.Li@Sun.COM 
217*7961SNatalie.Li@Sun.COM 	/*
218*7961SNatalie.Li@Sun.COM 	 * Setup the groups starting at index 1 (the last arg)
219*7961SNatalie.Li@Sun.COM 	 * of gids array.
220*7961SNatalie.Li@Sun.COM 	 */
221*7961SNatalie.Li@Sun.COM 	num = _getgroupsbymember(pwd->pw_name, gids, ngroups_max, 1);
222*7961SNatalie.Li@Sun.COM 
223*7961SNatalie.Li@Sun.COM 	if (num == -1) {
224*7961SNatalie.Li@Sun.COM 		syslog(LOG_ERR, "smb_logon: unable "
225*7961SNatalie.Li@Sun.COM 		    "to get user's supplementary groups");
226*7961SNatalie.Li@Sun.COM 		num = 1;
227*7961SNatalie.Li@Sun.COM 	}
228*7961SNatalie.Li@Sun.COM 
229*7961SNatalie.Li@Sun.COM 	pgrps = (smb_posix_grps_t *)malloc(SMB_POSIX_GRPS_SIZE(num));
230*7961SNatalie.Li@Sun.COM 	if (pgrps) {
231*7961SNatalie.Li@Sun.COM 		pgrps->pg_ngrps = num;
232*7961SNatalie.Li@Sun.COM 		bcopy(gids, pgrps->pg_grps, num * sizeof (gid_t));
233*7961SNatalie.Li@Sun.COM 	}
234*7961SNatalie.Li@Sun.COM 
235*7961SNatalie.Li@Sun.COM 	free(gids);
236*7961SNatalie.Li@Sun.COM 	return (pgrps);
237*7961SNatalie.Li@Sun.COM }
238*7961SNatalie.Li@Sun.COM 
239*7961SNatalie.Li@Sun.COM /*
240*7961SNatalie.Li@Sun.COM  * smb_token_destroy
241*7961SNatalie.Li@Sun.COM  *
242*7961SNatalie.Li@Sun.COM  * Release all of the memory associated with a token structure. Ensure
243*7961SNatalie.Li@Sun.COM  * that the token has been unlinked before calling.
244*7961SNatalie.Li@Sun.COM  */
245*7961SNatalie.Li@Sun.COM void
246*7961SNatalie.Li@Sun.COM smb_token_destroy(smb_token_t *token)
247*7961SNatalie.Li@Sun.COM {
248*7961SNatalie.Li@Sun.COM 	smb_win_grps_t *groups;
249*7961SNatalie.Li@Sun.COM 	int i;
250*7961SNatalie.Li@Sun.COM 
251*7961SNatalie.Li@Sun.COM 	if (token == NULL)
252*7961SNatalie.Li@Sun.COM 		return;
253*7961SNatalie.Li@Sun.COM 
254*7961SNatalie.Li@Sun.COM 	if (token->tkn_user) {
255*7961SNatalie.Li@Sun.COM 		free(token->tkn_user->i_sidattr.sid);
256*7961SNatalie.Li@Sun.COM 		free(token->tkn_user);
257*7961SNatalie.Li@Sun.COM 	}
258*7961SNatalie.Li@Sun.COM 
259*7961SNatalie.Li@Sun.COM 	if (token->tkn_owner) {
260*7961SNatalie.Li@Sun.COM 		free(token->tkn_owner->i_sidattr.sid);
261*7961SNatalie.Li@Sun.COM 		free(token->tkn_owner);
262*7961SNatalie.Li@Sun.COM 	}
263*7961SNatalie.Li@Sun.COM 
264*7961SNatalie.Li@Sun.COM 	if (token->tkn_primary_grp) {
265*7961SNatalie.Li@Sun.COM 		free(token->tkn_primary_grp->i_sidattr.sid);
266*7961SNatalie.Li@Sun.COM 		free(token->tkn_primary_grp);
267*7961SNatalie.Li@Sun.COM 	}
268*7961SNatalie.Li@Sun.COM 
269*7961SNatalie.Li@Sun.COM 	if ((groups = token->tkn_win_grps) != NULL) {
270*7961SNatalie.Li@Sun.COM 		for (i = 0; i < groups->wg_count; ++i)
271*7961SNatalie.Li@Sun.COM 			free(groups->wg_groups[i].i_sidattr.sid);
272*7961SNatalie.Li@Sun.COM 		free(groups);
273*7961SNatalie.Li@Sun.COM 	}
274*7961SNatalie.Li@Sun.COM 
275*7961SNatalie.Li@Sun.COM 	smb_privset_free(token->tkn_privileges);
276*7961SNatalie.Li@Sun.COM 
277*7961SNatalie.Li@Sun.COM 	free(token->tkn_posix_grps);
278*7961SNatalie.Li@Sun.COM 	free(token->tkn_account_name);
279*7961SNatalie.Li@Sun.COM 	free(token->tkn_domain_name);
280*7961SNatalie.Li@Sun.COM 	free(token->tkn_session_key);
281*7961SNatalie.Li@Sun.COM 
282*7961SNatalie.Li@Sun.COM 	free(token);
283*7961SNatalie.Li@Sun.COM }
284*7961SNatalie.Li@Sun.COM 
285*7961SNatalie.Li@Sun.COM static smb_id_t *
286*7961SNatalie.Li@Sun.COM smb_token_create_id(smb_sid_t *sid)
287*7961SNatalie.Li@Sun.COM {
288*7961SNatalie.Li@Sun.COM 	smb_id_t *id;
289*7961SNatalie.Li@Sun.COM 
290*7961SNatalie.Li@Sun.COM 	if ((id = malloc(sizeof (smb_id_t))) == NULL)
291*7961SNatalie.Li@Sun.COM 		return (NULL);
292*7961SNatalie.Li@Sun.COM 
293*7961SNatalie.Li@Sun.COM 	id->i_id = (uid_t)-1;
294*7961SNatalie.Li@Sun.COM 	id->i_sidattr.attrs = 7;
295*7961SNatalie.Li@Sun.COM 	id->i_sidattr.sid = smb_sid_dup(sid);
296*7961SNatalie.Li@Sun.COM 
297*7961SNatalie.Li@Sun.COM 	if (id->i_sidattr.sid == NULL) {
298*7961SNatalie.Li@Sun.COM 		free(id);
299*7961SNatalie.Li@Sun.COM 		id = NULL;
300*7961SNatalie.Li@Sun.COM 	}
301*7961SNatalie.Li@Sun.COM 
302*7961SNatalie.Li@Sun.COM 	return (id);
303*7961SNatalie.Li@Sun.COM }
304*7961SNatalie.Li@Sun.COM 
305*7961SNatalie.Li@Sun.COM /*
306*7961SNatalie.Li@Sun.COM  * Token owner should be set to local Administrators group
307*7961SNatalie.Li@Sun.COM  * in two cases:
308*7961SNatalie.Li@Sun.COM  *   1. The logged on user is a member of Domain Admins group
309*7961SNatalie.Li@Sun.COM  *   2. he/she is a member of local Administrators group
310*7961SNatalie.Li@Sun.COM  */
311*7961SNatalie.Li@Sun.COM static smb_id_t *
312*7961SNatalie.Li@Sun.COM smb_token_create_owner(smb_userinfo_t *user_info)
313*7961SNatalie.Li@Sun.COM {
314*7961SNatalie.Li@Sun.COM #ifdef SMB_SUPPORT_GROUP_OWNER
315*7961SNatalie.Li@Sun.COM 	smb_sid_t *owner_sid;
316*7961SNatalie.Li@Sun.COM 	smb_wka_t *wka;
317*7961SNatalie.Li@Sun.COM 
318*7961SNatalie.Li@Sun.COM 	if (user_info->flags & SMB_UINFO_FLAG_ADMIN) {
319*7961SNatalie.Li@Sun.COM 		wka = smb_wka_lookup("Administrators");
320*7961SNatalie.Li@Sun.COM 		assert(wka);
321*7961SNatalie.Li@Sun.COM 		owner_sid = wka->wka_binsid;
322*7961SNatalie.Li@Sun.COM 	} else {
323*7961SNatalie.Li@Sun.COM 		owner_sid = user_info->user_sid;
324*7961SNatalie.Li@Sun.COM 	}
325*7961SNatalie.Li@Sun.COM 
326*7961SNatalie.Li@Sun.COM 	return (smb_token_create_id(owner_sid));
327*7961SNatalie.Li@Sun.COM #endif
328*7961SNatalie.Li@Sun.COM 	return (smb_token_create_id(user_info->user_sid));
329*7961SNatalie.Li@Sun.COM }
330*7961SNatalie.Li@Sun.COM 
331*7961SNatalie.Li@Sun.COM static smb_privset_t *
332*7961SNatalie.Li@Sun.COM smb_token_create_privs(smb_userinfo_t *user_info)
333*7961SNatalie.Li@Sun.COM {
334*7961SNatalie.Li@Sun.COM 	smb_privset_t *privs;
335*7961SNatalie.Li@Sun.COM 	smb_giter_t gi;
336*7961SNatalie.Li@Sun.COM 	smb_group_t grp;
337*7961SNatalie.Li@Sun.COM 	int rc;
338*7961SNatalie.Li@Sun.COM 
339*7961SNatalie.Li@Sun.COM 	privs = smb_privset_new();
340*7961SNatalie.Li@Sun.COM 	if (privs == NULL)
341*7961SNatalie.Li@Sun.COM 		return (NULL);
342*7961SNatalie.Li@Sun.COM 
343*7961SNatalie.Li@Sun.COM 	if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
344*7961SNatalie.Li@Sun.COM 		smb_privset_free(privs);
345*7961SNatalie.Li@Sun.COM 		return (NULL);
346*7961SNatalie.Li@Sun.COM 	}
347*7961SNatalie.Li@Sun.COM 
348*7961SNatalie.Li@Sun.COM 	while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) {
349*7961SNatalie.Li@Sun.COM 		if (smb_lgrp_is_member(&grp, user_info->user_sid)) {
350*7961SNatalie.Li@Sun.COM 			smb_privset_merge(privs, grp.sg_privs);
351*7961SNatalie.Li@Sun.COM 		}
352*7961SNatalie.Li@Sun.COM 		smb_lgrp_free(&grp);
353*7961SNatalie.Li@Sun.COM 	}
354*7961SNatalie.Li@Sun.COM 	smb_lgrp_iterclose(&gi);
355*7961SNatalie.Li@Sun.COM 
356*7961SNatalie.Li@Sun.COM 	if (user_info->flags & SMB_UINFO_FLAG_ADMIN) {
357*7961SNatalie.Li@Sun.COM 		rc = smb_lgrp_getbyname("Administrators", &grp);
358*7961SNatalie.Li@Sun.COM 		if (rc == SMB_LGRP_SUCCESS) {
359*7961SNatalie.Li@Sun.COM 			smb_privset_merge(privs, grp.sg_privs);
360*7961SNatalie.Li@Sun.COM 			smb_lgrp_free(&grp);
361*7961SNatalie.Li@Sun.COM 		}
362*7961SNatalie.Li@Sun.COM 
363*7961SNatalie.Li@Sun.COM 		/*
364*7961SNatalie.Li@Sun.COM 		 * This privilege is required to view/edit SACL
365*7961SNatalie.Li@Sun.COM 		 */
366*7961SNatalie.Li@Sun.COM 		smb_privset_enable(privs, SE_SECURITY_LUID);
367*7961SNatalie.Li@Sun.COM 	}
368*7961SNatalie.Li@Sun.COM 
369*7961SNatalie.Li@Sun.COM 	return (privs);
370*7961SNatalie.Li@Sun.COM }
371*7961SNatalie.Li@Sun.COM 
372*7961SNatalie.Li@Sun.COM static void
373*7961SNatalie.Li@Sun.COM smb_token_set_flags(smb_token_t *token, smb_userinfo_t *user_info)
374*7961SNatalie.Li@Sun.COM {
375*7961SNatalie.Li@Sun.COM 	smb_wka_t *wka;
376*7961SNatalie.Li@Sun.COM 
377*7961SNatalie.Li@Sun.COM 	if (user_info->flags & SMB_UINFO_FLAG_ANON) {
378*7961SNatalie.Li@Sun.COM 		token->tkn_flags |= SMB_ATF_ANON;
379*7961SNatalie.Li@Sun.COM 		return;
380*7961SNatalie.Li@Sun.COM 	}
381*7961SNatalie.Li@Sun.COM 
382*7961SNatalie.Li@Sun.COM 	if (user_info->rid == DOMAIN_USER_RID_GUEST) {
383*7961SNatalie.Li@Sun.COM 		token->tkn_flags |= SMB_ATF_GUEST;
384*7961SNatalie.Li@Sun.COM 		return;
385*7961SNatalie.Li@Sun.COM 	}
386*7961SNatalie.Li@Sun.COM 
387*7961SNatalie.Li@Sun.COM 	wka = smb_wka_lookup("Administrators");
388*7961SNatalie.Li@Sun.COM 	if (wka->wka_binsid && smb_token_is_member(token, wka->wka_binsid))
389*7961SNatalie.Li@Sun.COM 		token->tkn_flags |= SMB_ATF_ADMIN;
390*7961SNatalie.Li@Sun.COM 
391*7961SNatalie.Li@Sun.COM 	wka = smb_wka_lookup("Power Users");
392*7961SNatalie.Li@Sun.COM 	if (wka->wka_binsid && smb_token_is_member(token, wka->wka_binsid))
393*7961SNatalie.Li@Sun.COM 		token->tkn_flags |= SMB_ATF_POWERUSER;
394*7961SNatalie.Li@Sun.COM 
395*7961SNatalie.Li@Sun.COM 	wka = smb_wka_lookup("Backup Operators");
396*7961SNatalie.Li@Sun.COM 	if (wka->wka_binsid && smb_token_is_member(token, wka->wka_binsid))
397*7961SNatalie.Li@Sun.COM 		token->tkn_flags |= SMB_ATF_BACKUPOP;
398*7961SNatalie.Li@Sun.COM 
399*7961SNatalie.Li@Sun.COM }
400*7961SNatalie.Li@Sun.COM 
401*7961SNatalie.Li@Sun.COM /*
402*7961SNatalie.Li@Sun.COM  * smb_token_create
403*7961SNatalie.Li@Sun.COM  *
404*7961SNatalie.Li@Sun.COM  * Build an access token based on the given user information (user_info).
405*7961SNatalie.Li@Sun.COM  *
406*7961SNatalie.Li@Sun.COM  * If everything is successful, a pointer to an access token is
407*7961SNatalie.Li@Sun.COM  * returned. Otherwise a null pointer is returned.
408*7961SNatalie.Li@Sun.COM  */
409*7961SNatalie.Li@Sun.COM static smb_token_t *
410*7961SNatalie.Li@Sun.COM smb_token_create(smb_userinfo_t *user_info)
411*7961SNatalie.Li@Sun.COM {
412*7961SNatalie.Li@Sun.COM 	smb_token_t *token;
413*7961SNatalie.Li@Sun.COM 
414*7961SNatalie.Li@Sun.COM 	if (user_info->sid_name_use != SidTypeUser)
415*7961SNatalie.Li@Sun.COM 		return (NULL);
416*7961SNatalie.Li@Sun.COM 
417*7961SNatalie.Li@Sun.COM 	token = (smb_token_t *)malloc(sizeof (smb_token_t));
418*7961SNatalie.Li@Sun.COM 	if (token == NULL) {
419*7961SNatalie.Li@Sun.COM 		syslog(LOG_ERR, "smb_token_create: resource shortage");
420*7961SNatalie.Li@Sun.COM 		return (NULL);
421*7961SNatalie.Li@Sun.COM 	}
422*7961SNatalie.Li@Sun.COM 	bzero(token, sizeof (smb_token_t));
423*7961SNatalie.Li@Sun.COM 
424*7961SNatalie.Li@Sun.COM 	/* User */
425*7961SNatalie.Li@Sun.COM 	token->tkn_user = smb_token_create_id(user_info->user_sid);
426*7961SNatalie.Li@Sun.COM 	if (token->tkn_user == NULL) {
427*7961SNatalie.Li@Sun.COM 		smb_token_destroy(token);
428*7961SNatalie.Li@Sun.COM 		return (NULL);
429*7961SNatalie.Li@Sun.COM 	}
430*7961SNatalie.Li@Sun.COM 
431*7961SNatalie.Li@Sun.COM 	/* Owner */
432*7961SNatalie.Li@Sun.COM 	token->tkn_owner = smb_token_create_owner(user_info);
433*7961SNatalie.Li@Sun.COM 	if (token->tkn_owner == NULL) {
434*7961SNatalie.Li@Sun.COM 		smb_token_destroy(token);
435*7961SNatalie.Li@Sun.COM 		return (NULL);
436*7961SNatalie.Li@Sun.COM 	}
437*7961SNatalie.Li@Sun.COM 
438*7961SNatalie.Li@Sun.COM 	/* Primary Group */
439*7961SNatalie.Li@Sun.COM 	token->tkn_primary_grp = smb_token_create_id(user_info->pgrp_sid);
440*7961SNatalie.Li@Sun.COM 	if (token->tkn_primary_grp == NULL) {
441*7961SNatalie.Li@Sun.COM 		smb_token_destroy(token);
442*7961SNatalie.Li@Sun.COM 		return (NULL);
443*7961SNatalie.Li@Sun.COM 	}
444*7961SNatalie.Li@Sun.COM 
445*7961SNatalie.Li@Sun.COM 	/* Privileges */
446*7961SNatalie.Li@Sun.COM 	token->tkn_privileges = smb_token_create_privs(user_info);
447*7961SNatalie.Li@Sun.COM 	if (token->tkn_privileges == NULL) {
448*7961SNatalie.Li@Sun.COM 		smb_token_destroy(token);
449*7961SNatalie.Li@Sun.COM 		return (NULL);
450*7961SNatalie.Li@Sun.COM 	}
451*7961SNatalie.Li@Sun.COM 
452*7961SNatalie.Li@Sun.COM 	/* Windows Groups */
453*7961SNatalie.Li@Sun.COM 	token->tkn_win_grps = smb_token_create_wingrps(user_info);
454*7961SNatalie.Li@Sun.COM 
455*7961SNatalie.Li@Sun.COM 	smb_token_set_flags(token, user_info);
456*7961SNatalie.Li@Sun.COM 
457*7961SNatalie.Li@Sun.COM 	/*
458*7961SNatalie.Li@Sun.COM 	 * IMPORTANT
459*7961SNatalie.Li@Sun.COM 	 *
460*7961SNatalie.Li@Sun.COM 	 * This function has to be called after all the SIDs in the
461*7961SNatalie.Li@Sun.COM 	 * token are setup (i.e. user, owner, primary and supplementary
462*7961SNatalie.Li@Sun.COM 	 * groups) and before setting up Solaris groups.
463*7961SNatalie.Li@Sun.COM 	 */
464*7961SNatalie.Li@Sun.COM 	if (smb_token_sids2ids(token) != 0) {
465*7961SNatalie.Li@Sun.COM 		syslog(LOG_ERR, "%s\\%s: idmap failed",
466*7961SNatalie.Li@Sun.COM 		    (user_info->domain_name) ? user_info->domain_name : "",
467*7961SNatalie.Li@Sun.COM 		    (user_info->name) ? user_info->name : "");
468*7961SNatalie.Li@Sun.COM 		smb_token_destroy(token);
469*7961SNatalie.Li@Sun.COM 		return (NULL);
470*7961SNatalie.Li@Sun.COM 	}
471*7961SNatalie.Li@Sun.COM 
472*7961SNatalie.Li@Sun.COM 	/* Solaris Groups */
473*7961SNatalie.Li@Sun.COM 	token->tkn_posix_grps = smb_token_create_pxgrps(token->tkn_user->i_id);
474*7961SNatalie.Li@Sun.COM 
475*7961SNatalie.Li@Sun.COM 	if (user_info->session_key) {
476*7961SNatalie.Li@Sun.COM 		token->tkn_session_key = malloc(sizeof (smb_session_key_t));
477*7961SNatalie.Li@Sun.COM 		if (token->tkn_session_key == NULL) {
478*7961SNatalie.Li@Sun.COM 			smb_token_destroy(token);
479*7961SNatalie.Li@Sun.COM 			return (NULL);
480*7961SNatalie.Li@Sun.COM 		}
481*7961SNatalie.Li@Sun.COM 
482*7961SNatalie.Li@Sun.COM 		(void) memcpy(token->tkn_session_key,
483*7961SNatalie.Li@Sun.COM 		    user_info->session_key, sizeof (smb_session_key_t));
484*7961SNatalie.Li@Sun.COM 	}
485*7961SNatalie.Li@Sun.COM 
486*7961SNatalie.Li@Sun.COM 	token->tkn_account_name = strdup(user_info->name);
487*7961SNatalie.Li@Sun.COM 	token->tkn_domain_name = strdup(user_info->domain_name);
488*7961SNatalie.Li@Sun.COM 
489*7961SNatalie.Li@Sun.COM 	if (!smb_token_is_valid(token)) {
490*7961SNatalie.Li@Sun.COM 		smb_token_destroy(token);
491*7961SNatalie.Li@Sun.COM 		return (NULL);
492*7961SNatalie.Li@Sun.COM 	}
493*7961SNatalie.Li@Sun.COM 
494*7961SNatalie.Li@Sun.COM 	return (token);
495*7961SNatalie.Li@Sun.COM }
496*7961SNatalie.Li@Sun.COM 
497*7961SNatalie.Li@Sun.COM /*
498*7961SNatalie.Li@Sun.COM  * smb_token_create_wingrps
499*7961SNatalie.Li@Sun.COM  *
500*7961SNatalie.Li@Sun.COM  * This private function supports smb_token_create() by mapping the group
501*7961SNatalie.Li@Sun.COM  * information in the user_info structure to the form required in an
502*7961SNatalie.Li@Sun.COM  * access token. The main difference is that the user_info contains
503*7961SNatalie.Li@Sun.COM  * RIDs while and access token contains full SIDs. Memory allocated
504*7961SNatalie.Li@Sun.COM  * here will be deallocated as part of smb_token_destroy().
505*7961SNatalie.Li@Sun.COM  *
506*7961SNatalie.Li@Sun.COM  * If everything is successful, a pointer to a smb_win_grps_t
507*7961SNatalie.Li@Sun.COM  * structure is returned. Otherwise a null pointer is returned.
508*7961SNatalie.Li@Sun.COM  */
509*7961SNatalie.Li@Sun.COM static smb_win_grps_t *
510*7961SNatalie.Li@Sun.COM smb_token_create_wingrps(smb_userinfo_t *user_info)
511*7961SNatalie.Li@Sun.COM {
512*7961SNatalie.Li@Sun.COM 	static char *wk_grps[] =
513*7961SNatalie.Li@Sun.COM 		{"Authenticated Users", "NETWORK", "Administrators"};
514*7961SNatalie.Li@Sun.COM 	smb_win_grps_t *tkn_grps;
515*7961SNatalie.Li@Sun.COM 	smb_sid_attrs_t *dlg_grps;
516*7961SNatalie.Li@Sun.COM 	smb_rid_attrs_t *g_grps;
517*7961SNatalie.Li@Sun.COM 	smb_sid_attrs_t *grp;
518*7961SNatalie.Li@Sun.COM 	smb_sid_t *builtin_sid;
519*7961SNatalie.Li@Sun.COM 	smb_giter_t gi;
520*7961SNatalie.Li@Sun.COM 	smb_group_t lgrp;
521*7961SNatalie.Li@Sun.COM 	uint32_t n_gg, n_lg, n_dlg, n_wg;
522*7961SNatalie.Li@Sun.COM 	uint32_t i, j;
523*7961SNatalie.Li@Sun.COM 	int size, count;
524*7961SNatalie.Li@Sun.COM 
525*7961SNatalie.Li@Sun.COM 	if (user_info == NULL)
526*7961SNatalie.Li@Sun.COM 		return (NULL);
527*7961SNatalie.Li@Sun.COM 
528*7961SNatalie.Li@Sun.COM 	n_gg = user_info->n_groups;		/* Global Groups */
529*7961SNatalie.Li@Sun.COM 	n_dlg = user_info->n_other_grps;	/* Domain Local Groups */
530*7961SNatalie.Li@Sun.COM 
531*7961SNatalie.Li@Sun.COM 	/* Local Groups */
532*7961SNatalie.Li@Sun.COM 	(void) smb_lgrp_numbymember(user_info->user_sid, (int *)&n_lg);
533*7961SNatalie.Li@Sun.COM 
534*7961SNatalie.Li@Sun.COM 	/* Well known Groups */
535*7961SNatalie.Li@Sun.COM 	if ((user_info->flags & SMB_UINFO_FLAG_ADMIN) == SMB_UINFO_FLAG_DADMIN)
536*7961SNatalie.Li@Sun.COM 		/* if user is a domain admin but not a local admin */
537*7961SNatalie.Li@Sun.COM 		n_wg = 3;
538*7961SNatalie.Li@Sun.COM 	else if (user_info->flags & SMB_UINFO_FLAG_ANON)
539*7961SNatalie.Li@Sun.COM 		n_wg = 0;
540*7961SNatalie.Li@Sun.COM 	else
541*7961SNatalie.Li@Sun.COM 		n_wg = 2;
542*7961SNatalie.Li@Sun.COM 
543*7961SNatalie.Li@Sun.COM 	count = n_gg + n_dlg + n_lg + n_wg;
544*7961SNatalie.Li@Sun.COM 	size = sizeof (smb_win_grps_t) + (count * sizeof (smb_id_t));
545*7961SNatalie.Li@Sun.COM 
546*7961SNatalie.Li@Sun.COM 	if ((tkn_grps = malloc(size)) == NULL)
547*7961SNatalie.Li@Sun.COM 		return (NULL);
548*7961SNatalie.Li@Sun.COM 	bzero(tkn_grps, size);
549*7961SNatalie.Li@Sun.COM 
550*7961SNatalie.Li@Sun.COM 	/* Add global groups */
551*7961SNatalie.Li@Sun.COM 	g_grps = user_info->groups;
552*7961SNatalie.Li@Sun.COM 	for (i = 0; i < n_gg; i++) {
553*7961SNatalie.Li@Sun.COM 		grp = &tkn_grps->wg_groups[i].i_sidattr;
554*7961SNatalie.Li@Sun.COM 		grp->sid = smb_sid_splice(user_info->domain_sid, g_grps[i].rid);
555*7961SNatalie.Li@Sun.COM 		if (grp->sid == NULL)
556*7961SNatalie.Li@Sun.COM 			break;
557*7961SNatalie.Li@Sun.COM 		grp->attrs = g_grps[i].attributes;
558*7961SNatalie.Li@Sun.COM 	}
559*7961SNatalie.Li@Sun.COM 
560*7961SNatalie.Li@Sun.COM 	if (n_gg == 0) {
561*7961SNatalie.Li@Sun.COM 		/*
562*7961SNatalie.Li@Sun.COM 		 * if there's no global group should add the
563*7961SNatalie.Li@Sun.COM 		 * primary group.
564*7961SNatalie.Li@Sun.COM 		 */
565*7961SNatalie.Li@Sun.COM 		grp = &tkn_grps->wg_groups[i].i_sidattr;
566*7961SNatalie.Li@Sun.COM 		grp->sid = smb_sid_dup(user_info->pgrp_sid);
567*7961SNatalie.Li@Sun.COM 		if (grp->sid != NULL) {
568*7961SNatalie.Li@Sun.COM 			grp->attrs = 0x7;
569*7961SNatalie.Li@Sun.COM 			i++;
570*7961SNatalie.Li@Sun.COM 		}
571*7961SNatalie.Li@Sun.COM 	}
572*7961SNatalie.Li@Sun.COM 
573*7961SNatalie.Li@Sun.COM 	/* Add domain local groups */
574*7961SNatalie.Li@Sun.COM 	dlg_grps = user_info->other_grps;
575*7961SNatalie.Li@Sun.COM 	for (j = 0; j < n_dlg; j++, i++) {
576*7961SNatalie.Li@Sun.COM 		grp = &tkn_grps->wg_groups[i].i_sidattr;
577*7961SNatalie.Li@Sun.COM 		grp->sid = smb_sid_dup(dlg_grps[j].sid);
578*7961SNatalie.Li@Sun.COM 		if (grp->sid == NULL)
579*7961SNatalie.Li@Sun.COM 			break;
580*7961SNatalie.Li@Sun.COM 		grp->attrs = dlg_grps[j].attrs;
581*7961SNatalie.Li@Sun.COM 	}
582*7961SNatalie.Li@Sun.COM 
583*7961SNatalie.Li@Sun.COM 	/* Add local groups */
584*7961SNatalie.Li@Sun.COM 	if (n_lg && (smb_lgrp_iteropen(&gi) == SMB_LGRP_SUCCESS)) {
585*7961SNatalie.Li@Sun.COM 		j = 0;
586*7961SNatalie.Li@Sun.COM 		while (smb_lgrp_iterate(&gi, &lgrp) == SMB_LGRP_SUCCESS) {
587*7961SNatalie.Li@Sun.COM 			if ((j < n_lg) &&
588*7961SNatalie.Li@Sun.COM 			    smb_lgrp_is_member(&lgrp, user_info->user_sid)) {
589*7961SNatalie.Li@Sun.COM 				grp = &tkn_grps->wg_groups[i].i_sidattr;
590*7961SNatalie.Li@Sun.COM 				grp->sid = smb_sid_dup(lgrp.sg_id.gs_sid);
591*7961SNatalie.Li@Sun.COM 				if (grp->sid == NULL) {
592*7961SNatalie.Li@Sun.COM 					smb_lgrp_free(&lgrp);
593*7961SNatalie.Li@Sun.COM 					break;
594*7961SNatalie.Li@Sun.COM 				}
595*7961SNatalie.Li@Sun.COM 				grp->attrs = lgrp.sg_attr;
596*7961SNatalie.Li@Sun.COM 				i++;
597*7961SNatalie.Li@Sun.COM 				j++;
598*7961SNatalie.Li@Sun.COM 			}
599*7961SNatalie.Li@Sun.COM 			smb_lgrp_free(&lgrp);
600*7961SNatalie.Li@Sun.COM 		}
601*7961SNatalie.Li@Sun.COM 		smb_lgrp_iterclose(&gi);
602*7961SNatalie.Li@Sun.COM 	}
603*7961SNatalie.Li@Sun.COM 
604*7961SNatalie.Li@Sun.COM 	/* Add well known groups */
605*7961SNatalie.Li@Sun.COM 	for (j = 0; j < n_wg; j++, i++) {
606*7961SNatalie.Li@Sun.COM 		builtin_sid = smb_wka_lookup_name(wk_grps[j], NULL);
607*7961SNatalie.Li@Sun.COM 		if (builtin_sid == NULL)
608*7961SNatalie.Li@Sun.COM 			break;
609*7961SNatalie.Li@Sun.COM 		tkn_grps->wg_groups[i].i_sidattr.sid = builtin_sid;
610*7961SNatalie.Li@Sun.COM 		tkn_grps->wg_groups[i].i_sidattr.attrs = 0x7;
611*7961SNatalie.Li@Sun.COM 	}
612*7961SNatalie.Li@Sun.COM 
613*7961SNatalie.Li@Sun.COM 	tkn_grps->wg_count = i;
614*7961SNatalie.Li@Sun.COM 	return (tkn_grps);
615*7961SNatalie.Li@Sun.COM }
616*7961SNatalie.Li@Sun.COM 
617*7961SNatalie.Li@Sun.COM /*
618*7961SNatalie.Li@Sun.COM  * smb_logon
619*7961SNatalie.Li@Sun.COM  *
620*7961SNatalie.Li@Sun.COM  * Performs user authentication and creates a token if the
621*7961SNatalie.Li@Sun.COM  * authentication is successful.
622*7961SNatalie.Li@Sun.COM  *
623*7961SNatalie.Li@Sun.COM  * Returns pointer to the created token.
624*7961SNatalie.Li@Sun.COM  */
625*7961SNatalie.Li@Sun.COM smb_token_t *
626*7961SNatalie.Li@Sun.COM smb_logon(netr_client_t *clnt)
627*7961SNatalie.Li@Sun.COM {
628*7961SNatalie.Li@Sun.COM 	smb_token_t *token = NULL;
629*7961SNatalie.Li@Sun.COM 	smb_userinfo_t *uinfo;
630*7961SNatalie.Li@Sun.COM 	uint32_t status;
631*7961SNatalie.Li@Sun.COM 
632*7961SNatalie.Li@Sun.COM 	if ((uinfo = mlsvc_alloc_user_info()) == 0)
633*7961SNatalie.Li@Sun.COM 		return (NULL);
634*7961SNatalie.Li@Sun.COM 
635*7961SNatalie.Li@Sun.COM 	switch (clnt->flags) {
636*7961SNatalie.Li@Sun.COM 	case NETR_CFLG_DOMAIN:
637*7961SNatalie.Li@Sun.COM 		/* Pass through authentication with DC */
638*7961SNatalie.Li@Sun.COM 		status = smb_logon_domain(clnt, uinfo);
639*7961SNatalie.Li@Sun.COM 		break;
640*7961SNatalie.Li@Sun.COM 
641*7961SNatalie.Li@Sun.COM 	case NETR_CFLG_LOCAL:
642*7961SNatalie.Li@Sun.COM 		/* Local authentication */
643*7961SNatalie.Li@Sun.COM 		status = smb_logon_local(clnt, uinfo);
644*7961SNatalie.Li@Sun.COM 		break;
645*7961SNatalie.Li@Sun.COM 
646*7961SNatalie.Li@Sun.COM 	case NETR_CFLG_ANON:
647*7961SNatalie.Li@Sun.COM 		/* Anonymous user; no authentication */
648*7961SNatalie.Li@Sun.COM 		status = smb_logon_none(clnt, uinfo);
649*7961SNatalie.Li@Sun.COM 		break;
650*7961SNatalie.Li@Sun.COM 
651*7961SNatalie.Li@Sun.COM 	default:
652*7961SNatalie.Li@Sun.COM 		status = NT_STATUS_INVALID_PARAMETER;
653*7961SNatalie.Li@Sun.COM 		break;
654*7961SNatalie.Li@Sun.COM 	}
655*7961SNatalie.Li@Sun.COM 
656*7961SNatalie.Li@Sun.COM 	if (status == NT_STATUS_SUCCESS)
657*7961SNatalie.Li@Sun.COM 		token = smb_token_create(uinfo);
658*7961SNatalie.Li@Sun.COM 
659*7961SNatalie.Li@Sun.COM 	mlsvc_free_user_info(uinfo);
660*7961SNatalie.Li@Sun.COM 	return (token);
661*7961SNatalie.Li@Sun.COM }
662*7961SNatalie.Li@Sun.COM 
663*7961SNatalie.Li@Sun.COM /*
664*7961SNatalie.Li@Sun.COM  * smb_logon_domain
665*7961SNatalie.Li@Sun.COM  *
666*7961SNatalie.Li@Sun.COM  * Performs pass through authentication with PDC.
667*7961SNatalie.Li@Sun.COM  */
668*7961SNatalie.Li@Sun.COM static uint32_t
669*7961SNatalie.Li@Sun.COM smb_logon_domain(netr_client_t *clnt, smb_userinfo_t *uinfo)
670*7961SNatalie.Li@Sun.COM {
671*7961SNatalie.Li@Sun.COM 	uint32_t status;
672*7961SNatalie.Li@Sun.COM 
673*7961SNatalie.Li@Sun.COM 	if ((status = netlogon_logon(clnt, uinfo)) != 0) {
674*7961SNatalie.Li@Sun.COM 		if (status == NT_STATUS_CANT_ACCESS_DOMAIN_INFO) {
675*7961SNatalie.Li@Sun.COM 			if ((status = netlogon_logon(clnt, uinfo)) != 0) {
676*7961SNatalie.Li@Sun.COM 				syslog(LOG_INFO, "SmbLogon[%s\\%s]: %s",
677*7961SNatalie.Li@Sun.COM 				    clnt->domain, clnt->username,
678*7961SNatalie.Li@Sun.COM 				    xlate_nt_status(status));
679*7961SNatalie.Li@Sun.COM 				return (status);
680*7961SNatalie.Li@Sun.COM 			}
681*7961SNatalie.Li@Sun.COM 		}
682*7961SNatalie.Li@Sun.COM 	}
683*7961SNatalie.Li@Sun.COM 
684*7961SNatalie.Li@Sun.COM 	return (status);
685*7961SNatalie.Li@Sun.COM }
686*7961SNatalie.Li@Sun.COM 
687*7961SNatalie.Li@Sun.COM /*
688*7961SNatalie.Li@Sun.COM  * smb_logon_local
689*7961SNatalie.Li@Sun.COM  *
690*7961SNatalie.Li@Sun.COM  * Check to see if connected user has an entry in the local
691*7961SNatalie.Li@Sun.COM  * smbpasswd database. If it has, tries both LM hash and NT
692*7961SNatalie.Li@Sun.COM  * hash with user's password(s) to authenticate the user.
693*7961SNatalie.Li@Sun.COM  */
694*7961SNatalie.Li@Sun.COM static uint32_t
695*7961SNatalie.Li@Sun.COM smb_logon_local(netr_client_t *clnt, smb_userinfo_t *uinfo)
696*7961SNatalie.Li@Sun.COM {
697*7961SNatalie.Li@Sun.COM 	smb_passwd_t smbpw;
698*7961SNatalie.Li@Sun.COM 	boolean_t lm_ok, nt_ok;
699*7961SNatalie.Li@Sun.COM 	uint32_t status;
700*7961SNatalie.Li@Sun.COM 
701*7961SNatalie.Li@Sun.COM 	if (smb_pwd_getpasswd(clnt->username, &smbpw) == NULL) {
702*7961SNatalie.Li@Sun.COM 		/*
703*7961SNatalie.Li@Sun.COM 		 * If user doesn't have entry either in smbpasswd
704*7961SNatalie.Li@Sun.COM 		 * or passwd it's considered as an invalid user.
705*7961SNatalie.Li@Sun.COM 		 */
706*7961SNatalie.Li@Sun.COM 		status = NT_STATUS_NO_SUCH_USER;
707*7961SNatalie.Li@Sun.COM 		syslog(LOG_NOTICE, "SmbLogon[%s\\%s]: %s",
708*7961SNatalie.Li@Sun.COM 		    clnt->domain, clnt->username,
709*7961SNatalie.Li@Sun.COM 		    xlate_nt_status(status));
710*7961SNatalie.Li@Sun.COM 		return (status);
711*7961SNatalie.Li@Sun.COM 	}
712*7961SNatalie.Li@Sun.COM 	if (smbpw.pw_flags & SMB_PWF_DISABLE)
713*7961SNatalie.Li@Sun.COM 		return (NT_STATUS_ACCOUNT_DISABLED);
714*7961SNatalie.Li@Sun.COM 
715*7961SNatalie.Li@Sun.COM 	nt_ok = lm_ok = B_FALSE;
716*7961SNatalie.Li@Sun.COM 	if ((smbpw.pw_flags & SMB_PWF_LM) &&
717*7961SNatalie.Li@Sun.COM 	    (clnt->lm_password.lm_password_len != 0)) {
718*7961SNatalie.Li@Sun.COM 		lm_ok = smb_auth_validate_lm(
719*7961SNatalie.Li@Sun.COM 		    clnt->challenge_key.challenge_key_val,
720*7961SNatalie.Li@Sun.COM 		    clnt->challenge_key.challenge_key_len,
721*7961SNatalie.Li@Sun.COM 		    &smbpw,
722*7961SNatalie.Li@Sun.COM 		    clnt->lm_password.lm_password_val,
723*7961SNatalie.Li@Sun.COM 		    clnt->lm_password.lm_password_len,
724*7961SNatalie.Li@Sun.COM 		    clnt->domain,
725*7961SNatalie.Li@Sun.COM 		    clnt->username);
726*7961SNatalie.Li@Sun.COM 		uinfo->session_key = NULL;
727*7961SNatalie.Li@Sun.COM 	}
728*7961SNatalie.Li@Sun.COM 
729*7961SNatalie.Li@Sun.COM 	if (!lm_ok && (clnt->nt_password.nt_password_len != 0)) {
730*7961SNatalie.Li@Sun.COM 		if ((uinfo->session_key =
731*7961SNatalie.Li@Sun.COM 		    malloc(SMBAUTH_SESSION_KEY_SZ)) == NULL)
732*7961SNatalie.Li@Sun.COM 			return (NT_STATUS_NO_MEMORY);
733*7961SNatalie.Li@Sun.COM 		nt_ok = smb_auth_validate_nt(
734*7961SNatalie.Li@Sun.COM 		    clnt->challenge_key.challenge_key_val,
735*7961SNatalie.Li@Sun.COM 		    clnt->challenge_key.challenge_key_len,
736*7961SNatalie.Li@Sun.COM 		    &smbpw,
737*7961SNatalie.Li@Sun.COM 		    clnt->nt_password.nt_password_val,
738*7961SNatalie.Li@Sun.COM 		    clnt->nt_password.nt_password_len,
739*7961SNatalie.Li@Sun.COM 		    clnt->domain,
740*7961SNatalie.Li@Sun.COM 		    clnt->username,
741*7961SNatalie.Li@Sun.COM 		    (uchar_t *)uinfo->session_key);
742*7961SNatalie.Li@Sun.COM 	}
743*7961SNatalie.Li@Sun.COM 
744*7961SNatalie.Li@Sun.COM 	if (!nt_ok && !lm_ok) {
745*7961SNatalie.Li@Sun.COM 		status = NT_STATUS_WRONG_PASSWORD;
746*7961SNatalie.Li@Sun.COM 		syslog(LOG_NOTICE, "SmbLogon[%s\\%s]: %s",
747*7961SNatalie.Li@Sun.COM 		    clnt->domain, clnt->username,
748*7961SNatalie.Li@Sun.COM 		    xlate_nt_status(status));
749*7961SNatalie.Li@Sun.COM 		return (status);
750*7961SNatalie.Li@Sun.COM 	}
751*7961SNatalie.Li@Sun.COM 
752*7961SNatalie.Li@Sun.COM 	status = smb_setup_luinfo(uinfo, clnt, smbpw.pw_uid);
753*7961SNatalie.Li@Sun.COM 	return (status);
754*7961SNatalie.Li@Sun.COM }
755*7961SNatalie.Li@Sun.COM 
756*7961SNatalie.Li@Sun.COM /*
757*7961SNatalie.Li@Sun.COM  * smb_logon_none
758*7961SNatalie.Li@Sun.COM  *
759*7961SNatalie.Li@Sun.COM  * Setup user information for anonymous user.
760*7961SNatalie.Li@Sun.COM  * No authentication is required.
761*7961SNatalie.Li@Sun.COM  */
762*7961SNatalie.Li@Sun.COM static uint32_t
763*7961SNatalie.Li@Sun.COM smb_logon_none(netr_client_t *clnt, smb_userinfo_t *uinfo)
764*7961SNatalie.Li@Sun.COM {
765*7961SNatalie.Li@Sun.COM 	return (smb_setup_luinfo(uinfo, clnt, (uid_t)-1));
766*7961SNatalie.Li@Sun.COM }
767*7961SNatalie.Li@Sun.COM 
768*7961SNatalie.Li@Sun.COM /*
769*7961SNatalie.Li@Sun.COM  * smb_setup_luinfo
770*7961SNatalie.Li@Sun.COM  *
771*7961SNatalie.Li@Sun.COM  * Setup local user information based on the client information and
772*7961SNatalie.Li@Sun.COM  * user's record in the local password file.
773*7961SNatalie.Li@Sun.COM  */
774*7961SNatalie.Li@Sun.COM static uint32_t
775*7961SNatalie.Li@Sun.COM smb_setup_luinfo(smb_userinfo_t *lui, netr_client_t *clnt, uid_t uid)
776*7961SNatalie.Li@Sun.COM {
777*7961SNatalie.Li@Sun.COM 	idmap_stat stat;
778*7961SNatalie.Li@Sun.COM 	smb_idmap_batch_t sib;
779*7961SNatalie.Li@Sun.COM 	smb_idmap_t *umap, *gmap;
780*7961SNatalie.Li@Sun.COM 	smb_group_t grp;
781*7961SNatalie.Li@Sun.COM 	struct passwd pw;
782*7961SNatalie.Li@Sun.COM 	char pwbuf[1024];
783*7961SNatalie.Li@Sun.COM 	char nbname[NETBIOS_NAME_SZ];
784*7961SNatalie.Li@Sun.COM 
785*7961SNatalie.Li@Sun.COM 	(void) smb_getnetbiosname(nbname, sizeof (nbname));
786*7961SNatalie.Li@Sun.COM 	lui->sid_name_use = SidTypeUser;
787*7961SNatalie.Li@Sun.COM 	lui->domain_sid = smb_sid_dup(nt_domain_local_sid());
788*7961SNatalie.Li@Sun.COM 	lui->name = strdup(clnt->username);
789*7961SNatalie.Li@Sun.COM 	lui->domain_name = strdup(nbname);
790*7961SNatalie.Li@Sun.COM 	lui->n_groups = 0;
791*7961SNatalie.Li@Sun.COM 	lui->groups = NULL;
792*7961SNatalie.Li@Sun.COM 	lui->n_other_grps = 0;
793*7961SNatalie.Li@Sun.COM 	lui->other_grps = NULL;
794*7961SNatalie.Li@Sun.COM 	lui->flags = 0;
795*7961SNatalie.Li@Sun.COM 
796*7961SNatalie.Li@Sun.COM 	if (lui->name == NULL || lui->domain_name == NULL ||
797*7961SNatalie.Li@Sun.COM 	    lui->domain_sid == NULL)
798*7961SNatalie.Li@Sun.COM 		return (NT_STATUS_INVALID_PARAMETER);
799*7961SNatalie.Li@Sun.COM 
800*7961SNatalie.Li@Sun.COM 	if (clnt->flags & NETR_CFLG_ANON) {
801*7961SNatalie.Li@Sun.COM 		lui->user_sid = smb_wka_lookup_name("Anonymous", NULL);
802*7961SNatalie.Li@Sun.COM 		lui->pgrp_sid = smb_wka_lookup_name("Anonymous", NULL);
803*7961SNatalie.Li@Sun.COM 		lui->flags = SMB_UINFO_FLAG_ANON;
804*7961SNatalie.Li@Sun.COM 
805*7961SNatalie.Li@Sun.COM 		if (lui->user_sid == NULL || lui->pgrp_sid == NULL)
806*7961SNatalie.Li@Sun.COM 			return (NT_STATUS_NO_MEMORY);
807*7961SNatalie.Li@Sun.COM 
808*7961SNatalie.Li@Sun.COM 		return (NT_STATUS_SUCCESS);
809*7961SNatalie.Li@Sun.COM 	}
810*7961SNatalie.Li@Sun.COM 
811*7961SNatalie.Li@Sun.COM 	if (getpwuid_r(uid, &pw, pwbuf, sizeof (pwbuf)) == NULL)
812*7961SNatalie.Li@Sun.COM 		return (NT_STATUS_NO_SUCH_USER);
813*7961SNatalie.Li@Sun.COM 
814*7961SNatalie.Li@Sun.COM 	/* Get the SID for user's uid & gid */
815*7961SNatalie.Li@Sun.COM 	stat = smb_idmap_batch_create(&sib, 2, SMB_IDMAP_ID2SID);
816*7961SNatalie.Li@Sun.COM 	if (stat != IDMAP_SUCCESS) {
817*7961SNatalie.Li@Sun.COM 		return (NT_STATUS_INTERNAL_ERROR);
818*7961SNatalie.Li@Sun.COM 	}
819*7961SNatalie.Li@Sun.COM 
820*7961SNatalie.Li@Sun.COM 	umap = &sib.sib_maps[0];
821*7961SNatalie.Li@Sun.COM 	stat = smb_idmap_batch_getsid(sib.sib_idmaph, umap, pw.pw_uid,
822*7961SNatalie.Li@Sun.COM 	    SMB_IDMAP_USER);
823*7961SNatalie.Li@Sun.COM 
824*7961SNatalie.Li@Sun.COM 	if (stat != IDMAP_SUCCESS) {
825*7961SNatalie.Li@Sun.COM 		smb_idmap_batch_destroy(&sib);
826*7961SNatalie.Li@Sun.COM 		return (NT_STATUS_INTERNAL_ERROR);
827*7961SNatalie.Li@Sun.COM 	}
828*7961SNatalie.Li@Sun.COM 
829*7961SNatalie.Li@Sun.COM 	gmap = &sib.sib_maps[1];
830*7961SNatalie.Li@Sun.COM 	stat = smb_idmap_batch_getsid(sib.sib_idmaph, gmap, pw.pw_gid,
831*7961SNatalie.Li@Sun.COM 	    SMB_IDMAP_GROUP);
832*7961SNatalie.Li@Sun.COM 
833*7961SNatalie.Li@Sun.COM 	if (stat != IDMAP_SUCCESS) {
834*7961SNatalie.Li@Sun.COM 		smb_idmap_batch_destroy(&sib);
835*7961SNatalie.Li@Sun.COM 		return (NT_STATUS_INTERNAL_ERROR);
836*7961SNatalie.Li@Sun.COM 	}
837*7961SNatalie.Li@Sun.COM 
838*7961SNatalie.Li@Sun.COM 	stat = smb_idmap_batch_getmappings(&sib);
839*7961SNatalie.Li@Sun.COM 
840*7961SNatalie.Li@Sun.COM 	if (stat != IDMAP_SUCCESS) {
841*7961SNatalie.Li@Sun.COM 		return (NT_STATUS_INTERNAL_ERROR);
842*7961SNatalie.Li@Sun.COM 	}
843*7961SNatalie.Li@Sun.COM 
844*7961SNatalie.Li@Sun.COM 	lui->rid = umap->sim_rid;
845*7961SNatalie.Li@Sun.COM 	lui->user_sid = smb_sid_dup(umap->sim_sid);
846*7961SNatalie.Li@Sun.COM 
847*7961SNatalie.Li@Sun.COM 	lui->primary_group_rid = gmap->sim_rid;
848*7961SNatalie.Li@Sun.COM 	lui->pgrp_sid = smb_sid_dup(gmap->sim_sid);
849*7961SNatalie.Li@Sun.COM 
850*7961SNatalie.Li@Sun.COM 	smb_idmap_batch_destroy(&sib);
851*7961SNatalie.Li@Sun.COM 
852*7961SNatalie.Li@Sun.COM 	if ((lui->user_sid == NULL) || (lui->pgrp_sid == NULL))
853*7961SNatalie.Li@Sun.COM 		return (NT_STATUS_NO_MEMORY);
854*7961SNatalie.Li@Sun.COM 
855*7961SNatalie.Li@Sun.COM 	if (smb_lgrp_getbyname("Administrators", &grp) == SMB_LGRP_SUCCESS) {
856*7961SNatalie.Li@Sun.COM 		if (smb_lgrp_is_member(&grp, lui->user_sid))
857*7961SNatalie.Li@Sun.COM 			lui->flags = SMB_UINFO_FLAG_LADMIN;
858*7961SNatalie.Li@Sun.COM 		smb_lgrp_free(&grp);
859*7961SNatalie.Li@Sun.COM 	}
860*7961SNatalie.Li@Sun.COM 
861*7961SNatalie.Li@Sun.COM 	return (NT_STATUS_SUCCESS);
862*7961SNatalie.Li@Sun.COM }
863*7961SNatalie.Li@Sun.COM 
864*7961SNatalie.Li@Sun.COM /*
865*7961SNatalie.Li@Sun.COM  * smb_token_is_valid
866*7961SNatalie.Li@Sun.COM  *
867*7961SNatalie.Li@Sun.COM  * check to see if specified fields of the given access
868*7961SNatalie.Li@Sun.COM  * token are valid.
869*7961SNatalie.Li@Sun.COM  * Returns 1 if all of them are valid; otherwise 0.
870*7961SNatalie.Li@Sun.COM  */
871*7961SNatalie.Li@Sun.COM static int
872*7961SNatalie.Li@Sun.COM smb_token_is_valid(smb_token_t *token)
873*7961SNatalie.Li@Sun.COM {
874*7961SNatalie.Li@Sun.COM 	int valid;
875*7961SNatalie.Li@Sun.COM 
876*7961SNatalie.Li@Sun.COM 	valid = (token->tkn_user != 0) &&
877*7961SNatalie.Li@Sun.COM 	    (token->tkn_user->i_sidattr.sid != 0) &&
878*7961SNatalie.Li@Sun.COM 	    (token->tkn_privileges != 0) &&
879*7961SNatalie.Li@Sun.COM 	    (token->tkn_win_grps != 0) &&
880*7961SNatalie.Li@Sun.COM 	    (token->tkn_owner != 0) &&
881*7961SNatalie.Li@Sun.COM 	    (token->tkn_owner->i_sidattr.sid != 0) &&
882*7961SNatalie.Li@Sun.COM 	    (token->tkn_primary_grp != 0) &&
883*7961SNatalie.Li@Sun.COM 	    (token->tkn_primary_grp->i_sidattr.sid != 0);
884*7961SNatalie.Li@Sun.COM 
885*7961SNatalie.Li@Sun.COM 	return (valid);
886*7961SNatalie.Li@Sun.COM }
887*7961SNatalie.Li@Sun.COM 
888*7961SNatalie.Li@Sun.COM /*
889*7961SNatalie.Li@Sun.COM  * smb_token_user_sid
890*7961SNatalie.Li@Sun.COM  *
891*7961SNatalie.Li@Sun.COM  * Return a pointer to the user SID in the specified token. A null
892*7961SNatalie.Li@Sun.COM  * pointer indicates an error.
893*7961SNatalie.Li@Sun.COM  */
894*7961SNatalie.Li@Sun.COM static smb_sid_t *
895*7961SNatalie.Li@Sun.COM smb_token_user_sid(smb_token_t *token)
896*7961SNatalie.Li@Sun.COM {
897*7961SNatalie.Li@Sun.COM 	if (token && token->tkn_user)
898*7961SNatalie.Li@Sun.COM 		return ((token)->tkn_user->i_sidattr.sid);
899*7961SNatalie.Li@Sun.COM 
900*7961SNatalie.Li@Sun.COM 	return (NULL);
901*7961SNatalie.Li@Sun.COM }
902*7961SNatalie.Li@Sun.COM 
903*7961SNatalie.Li@Sun.COM /*
904*7961SNatalie.Li@Sun.COM  * smb_token_group_sid
905*7961SNatalie.Li@Sun.COM  *
906*7961SNatalie.Li@Sun.COM  * Return a pointer to the group SID as indicated by the iterator.
907*7961SNatalie.Li@Sun.COM  * Setting the iterator to 0 before calling this function will return
908*7961SNatalie.Li@Sun.COM  * the first group, which will always be the primary group. The
909*7961SNatalie.Li@Sun.COM  * iterator will be incremented before returning the SID so that this
910*7961SNatalie.Li@Sun.COM  * function can be used to cycle through the groups. The caller can
911*7961SNatalie.Li@Sun.COM  * adjust the iterator as required between calls to obtain any specific
912*7961SNatalie.Li@Sun.COM  * group.
913*7961SNatalie.Li@Sun.COM  *
914*7961SNatalie.Li@Sun.COM  * On success a pointer to the appropriate group SID will be returned.
915*7961SNatalie.Li@Sun.COM  * Otherwise a null pointer will be returned.
916*7961SNatalie.Li@Sun.COM  */
917*7961SNatalie.Li@Sun.COM static smb_sid_t *
918*7961SNatalie.Li@Sun.COM smb_token_group_sid(smb_token_t *token, int *iterator)
919*7961SNatalie.Li@Sun.COM {
920*7961SNatalie.Li@Sun.COM 	smb_win_grps_t *groups;
921*7961SNatalie.Li@Sun.COM 	int index;
922*7961SNatalie.Li@Sun.COM 
923*7961SNatalie.Li@Sun.COM 	if (token == NULL || iterator == NULL) {
924*7961SNatalie.Li@Sun.COM 		return (NULL);
925*7961SNatalie.Li@Sun.COM 	}
926*7961SNatalie.Li@Sun.COM 
927*7961SNatalie.Li@Sun.COM 	if ((groups = token->tkn_win_grps) == NULL) {
928*7961SNatalie.Li@Sun.COM 		return (NULL);
929*7961SNatalie.Li@Sun.COM 	}
930*7961SNatalie.Li@Sun.COM 
931*7961SNatalie.Li@Sun.COM 	index = *iterator;
932*7961SNatalie.Li@Sun.COM 
933*7961SNatalie.Li@Sun.COM 	if (index < 0 || index >= groups->wg_count) {
934*7961SNatalie.Li@Sun.COM 		return (NULL);
935*7961SNatalie.Li@Sun.COM 	}
936*7961SNatalie.Li@Sun.COM 
937*7961SNatalie.Li@Sun.COM 	++(*iterator);
938*7961SNatalie.Li@Sun.COM 	return (groups->wg_groups[index].i_sidattr.sid);
939*7961SNatalie.Li@Sun.COM }
940*7961SNatalie.Li@Sun.COM 
941*7961SNatalie.Li@Sun.COM /*
942*7961SNatalie.Li@Sun.COM  * smb_token_is_member
943*7961SNatalie.Li@Sun.COM  *
944*7961SNatalie.Li@Sun.COM  * This function will determine whether or not the specified SID is a
945*7961SNatalie.Li@Sun.COM  * member of a token. The user SID and all group SIDs are tested.
946*7961SNatalie.Li@Sun.COM  * Returns 1 if the SID is a member of the token. Otherwise returns 0.
947*7961SNatalie.Li@Sun.COM  */
948*7961SNatalie.Li@Sun.COM static int
949*7961SNatalie.Li@Sun.COM smb_token_is_member(smb_token_t *token, smb_sid_t *sid)
950*7961SNatalie.Li@Sun.COM {
951*7961SNatalie.Li@Sun.COM 	smb_sid_t *tsid;
952*7961SNatalie.Li@Sun.COM 	int iterator = 0;
953*7961SNatalie.Li@Sun.COM 
954*7961SNatalie.Li@Sun.COM 	tsid = smb_token_user_sid(token);
955*7961SNatalie.Li@Sun.COM 	while (tsid) {
956*7961SNatalie.Li@Sun.COM 		if (smb_sid_cmp(tsid, sid))
957*7961SNatalie.Li@Sun.COM 			return (1);
958*7961SNatalie.Li@Sun.COM 
959*7961SNatalie.Li@Sun.COM 		tsid = smb_token_group_sid(token, &iterator);
960*7961SNatalie.Li@Sun.COM 	}
961*7961SNatalie.Li@Sun.COM 
962*7961SNatalie.Li@Sun.COM 	return (0);
963*7961SNatalie.Li@Sun.COM }
964*7961SNatalie.Li@Sun.COM 
965*7961SNatalie.Li@Sun.COM /*
966*7961SNatalie.Li@Sun.COM  * smb_token_log
967*7961SNatalie.Li@Sun.COM  *
968*7961SNatalie.Li@Sun.COM  * Diagnostic routine to write the contents of a token to the log.
969*7961SNatalie.Li@Sun.COM  */
970*7961SNatalie.Li@Sun.COM void
971*7961SNatalie.Li@Sun.COM smb_token_log(smb_token_t *token)
972*7961SNatalie.Li@Sun.COM {
973*7961SNatalie.Li@Sun.COM 	smb_win_grps_t *w_grps;
974*7961SNatalie.Li@Sun.COM 	smb_posix_grps_t *x_grps;
975*7961SNatalie.Li@Sun.COM 	smb_sid_attrs_t *grp;
976*7961SNatalie.Li@Sun.COM 	char sidstr[SMB_SID_STRSZ];
977*7961SNatalie.Li@Sun.COM 	int i;
978*7961SNatalie.Li@Sun.COM 
979*7961SNatalie.Li@Sun.COM 	if (token == NULL)
980*7961SNatalie.Li@Sun.COM 		return;
981*7961SNatalie.Li@Sun.COM 
982*7961SNatalie.Li@Sun.COM 	syslog(LOG_DEBUG, "Token for %s\\%s",
983*7961SNatalie.Li@Sun.COM 	    (token->tkn_domain_name) ? token->tkn_domain_name : "-NULL-",
984*7961SNatalie.Li@Sun.COM 	    (token->tkn_account_name) ? token->tkn_account_name : "-NULL-");
985*7961SNatalie.Li@Sun.COM 
986*7961SNatalie.Li@Sun.COM 	syslog(LOG_DEBUG, "   User->Attr: %d",
987*7961SNatalie.Li@Sun.COM 	    token->tkn_user->i_sidattr.attrs);
988*7961SNatalie.Li@Sun.COM 	smb_sid_tostr((smb_sid_t *)token->tkn_user->i_sidattr.sid, sidstr);
989*7961SNatalie.Li@Sun.COM 	syslog(LOG_DEBUG, "   User->Sid: %s (id=%u)",
990*7961SNatalie.Li@Sun.COM 	    sidstr, token->tkn_user->i_id);
991*7961SNatalie.Li@Sun.COM 
992*7961SNatalie.Li@Sun.COM 	smb_sid_tostr((smb_sid_t *)token->tkn_owner->i_sidattr.sid, sidstr);
993*7961SNatalie.Li@Sun.COM 	syslog(LOG_DEBUG, "   Ownr->Sid: %s (id=%u)",
994*7961SNatalie.Li@Sun.COM 	    sidstr, token->tkn_owner->i_id);
995*7961SNatalie.Li@Sun.COM 
996*7961SNatalie.Li@Sun.COM 	smb_sid_tostr((smb_sid_t *)token->tkn_primary_grp->i_sidattr.sid,
997*7961SNatalie.Li@Sun.COM 	    sidstr);
998*7961SNatalie.Li@Sun.COM 	syslog(LOG_DEBUG, "   PGrp->Sid: %s (id=%u)",
999*7961SNatalie.Li@Sun.COM 	    sidstr, token->tkn_primary_grp->i_id);
1000*7961SNatalie.Li@Sun.COM 
1001*7961SNatalie.Li@Sun.COM 	w_grps = token->tkn_win_grps;
1002*7961SNatalie.Li@Sun.COM 	if (w_grps) {
1003*7961SNatalie.Li@Sun.COM 		syslog(LOG_DEBUG, "   Windows groups: %d",
1004*7961SNatalie.Li@Sun.COM 		    w_grps->wg_count);
1005*7961SNatalie.Li@Sun.COM 
1006*7961SNatalie.Li@Sun.COM 		for (i = 0; i < w_grps->wg_count; ++i) {
1007*7961SNatalie.Li@Sun.COM 			grp = &w_grps->wg_groups[i].i_sidattr;
1008*7961SNatalie.Li@Sun.COM 			syslog(LOG_DEBUG,
1009*7961SNatalie.Li@Sun.COM 			    "    Grp[%d].Attr:%d", i, grp->attrs);
1010*7961SNatalie.Li@Sun.COM 			if (w_grps->wg_groups[i].i_sidattr.sid) {
1011*7961SNatalie.Li@Sun.COM 				smb_sid_tostr((smb_sid_t *)grp->sid, sidstr);
1012*7961SNatalie.Li@Sun.COM 				syslog(LOG_DEBUG,
1013*7961SNatalie.Li@Sun.COM 				    "    Grp[%d].Sid: %s (id=%u)", i, sidstr,
1014*7961SNatalie.Li@Sun.COM 				    w_grps->wg_groups[i].i_id);
1015*7961SNatalie.Li@Sun.COM 			}
1016*7961SNatalie.Li@Sun.COM 		}
1017*7961SNatalie.Li@Sun.COM 	}
1018*7961SNatalie.Li@Sun.COM 	else
1019*7961SNatalie.Li@Sun.COM 		syslog(LOG_DEBUG, "   No Windows groups");
1020*7961SNatalie.Li@Sun.COM 
1021*7961SNatalie.Li@Sun.COM 	x_grps = token->tkn_posix_grps;
1022*7961SNatalie.Li@Sun.COM 	if (x_grps) {
1023*7961SNatalie.Li@Sun.COM 		syslog(LOG_DEBUG, "   Solaris groups: %d",
1024*7961SNatalie.Li@Sun.COM 		    x_grps->pg_ngrps);
1025*7961SNatalie.Li@Sun.COM 		for (i = 0; i < x_grps->pg_ngrps; i++)
1026*7961SNatalie.Li@Sun.COM 			syslog(LOG_DEBUG, "    %u",
1027*7961SNatalie.Li@Sun.COM 			    x_grps->pg_grps[i]);
1028*7961SNatalie.Li@Sun.COM 	}
1029*7961SNatalie.Li@Sun.COM 	else
1030*7961SNatalie.Li@Sun.COM 		syslog(LOG_DEBUG, "   No Solaris groups");
1031*7961SNatalie.Li@Sun.COM 
1032*7961SNatalie.Li@Sun.COM 	if (token->tkn_privileges)
1033*7961SNatalie.Li@Sun.COM 		smb_privset_log(token->tkn_privileges);
1034*7961SNatalie.Li@Sun.COM 	else
1035*7961SNatalie.Li@Sun.COM 		syslog(LOG_DEBUG, "   No privileges");
1036*7961SNatalie.Li@Sun.COM }
1037