xref: /titanic_51/usr/src/lib/libsecdb/common/chkauthattr.c (revision bf8599311c92f3dbd7e51f465d9da6668b81187d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5d3186a0eSjeanm  * Common Development and Distribution License (the "License").
6d3186a0eSjeanm  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22ceeba6f9Srui zang - Sun Microsystems - Beijing China  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
25134a1f4eSCasper H.S. Dik #include <alloca.h>
267c478bd9Sstevel@tonic-gate #include <stdio.h>
277c478bd9Sstevel@tonic-gate #include <stdlib.h>
287c478bd9Sstevel@tonic-gate #include <string.h>
297c478bd9Sstevel@tonic-gate #include <sys/stat.h>
30499fd601Sgww #include <pwd.h>
31499fd601Sgww #include <nss_dbdefs.h>
327c478bd9Sstevel@tonic-gate #include <deflt.h>
337c478bd9Sstevel@tonic-gate #include <auth_attr.h>
347c478bd9Sstevel@tonic-gate #include <prof_attr.h>
357c478bd9Sstevel@tonic-gate #include <user_attr.h>
367c478bd9Sstevel@tonic-gate 
37134a1f4eSCasper H.S. Dik #define	COPYTOSTACK(dst, csrc)		{	\
38134a1f4eSCasper H.S. Dik 		size_t len = strlen(csrc) + 1;	\
39134a1f4eSCasper H.S. Dik 		dst = alloca(len);		\
40134a1f4eSCasper H.S. Dik 		(void) memcpy(dst, csrc, len);	\
41134a1f4eSCasper H.S. Dik 	}
427c478bd9Sstevel@tonic-gate 
43134a1f4eSCasper H.S. Dik static kva_t *get_default_attrs(const char *);
44134a1f4eSCasper H.S. Dik static void free_default_attrs(kva_t *);
45134a1f4eSCasper H.S. Dik 
46134a1f4eSCasper H.S. Dik /*
47134a1f4eSCasper H.S. Dik  * Enumeration functions for auths and profiles; the enumeration functions
48134a1f4eSCasper H.S. Dik  * take a callback with four arguments:
49134a1f4eSCasper H.S. Dik  *	const char *		profile name (or NULL unless wantattr is false)
50134a1f4eSCasper H.S. Dik  *	kva_t *			attributes (or NULL unless wantattr is true)
51134a1f4eSCasper H.S. Dik  *	void *			context
52134a1f4eSCasper H.S. Dik  *	void *			pointer to the result
53134a1f4eSCasper H.S. Dik  * When the call back returns non-zero, the enumeration ends.
54134a1f4eSCasper H.S. Dik  * The function might be NULL but only for profiles as we are always collecting
55134a1f4eSCasper H.S. Dik  * all the profiles.
56134a1f4eSCasper H.S. Dik  * Both the auths and the profiles arguments may be NULL.
57134a1f4eSCasper H.S. Dik  *
58134a1f4eSCasper H.S. Dik  * These should be the only implementation of the algorithm of "finding me
59134a1f4eSCasper H.S. Dik  * all the profiles/athorizations/keywords/etc.
60134a1f4eSCasper H.S. Dik  */
61134a1f4eSCasper H.S. Dik 
62134a1f4eSCasper H.S. Dik #define	CONSUSER_PROFILE_KW		"consprofile"
63134a1f4eSCasper H.S. Dik #define	DEF_LOCK_AFTER_RETRIES		"LOCK_AFTER_RETRIES="
64134a1f4eSCasper H.S. Dik 
65134a1f4eSCasper H.S. Dik static struct dfltplcy {
66134a1f4eSCasper H.S. Dik 	char *attr;
67134a1f4eSCasper H.S. Dik 	const char *defkw;
68134a1f4eSCasper H.S. Dik } dfltply[] = {
69134a1f4eSCasper H.S. Dik 	/* CONSUSER MUST BE FIRST! */
70134a1f4eSCasper H.S. Dik 	{ CONSUSER_PROFILE_KW,			DEF_CONSUSER},
71134a1f4eSCasper H.S. Dik 	{ PROFATTR_AUTHS_KW,			DEF_AUTH},
72134a1f4eSCasper H.S. Dik 	{ PROFATTR_PROFS_KW,			DEF_PROF},
73134a1f4eSCasper H.S. Dik 	{ USERATTR_LIMPRIV_KW,			DEF_LIMITPRIV},
74134a1f4eSCasper H.S. Dik 	{ USERATTR_DFLTPRIV_KW,			DEF_DFLTPRIV},
75134a1f4eSCasper H.S. Dik 	{ USERATTR_LOCK_AFTER_RETRIES_KW,	DEF_LOCK_AFTER_RETRIES}
76134a1f4eSCasper H.S. Dik };
77134a1f4eSCasper H.S. Dik 
78134a1f4eSCasper H.S. Dik #define	NDFLTPLY	(sizeof (dfltply)/sizeof (struct dfltplcy))
79134a1f4eSCasper H.S. Dik #define	GETCONSPROF(a)	(kva_match((a), CONSUSER_PROFILE_KW))
80134a1f4eSCasper H.S. Dik #define	GETPROF(a)	(kva_match((a), PROFATTR_PROFS_KW))
81134a1f4eSCasper H.S. Dik 
82134a1f4eSCasper H.S. Dik /*
83134a1f4eSCasper H.S. Dik  * Enumerate profiles from listed profiles.
84134a1f4eSCasper H.S. Dik  */
857c478bd9Sstevel@tonic-gate int
86134a1f4eSCasper H.S. Dik _enum_common_p(const char *cprofiles,
87134a1f4eSCasper H.S. Dik     int (*cb)(const char *, kva_t *, void *, void *),
88134a1f4eSCasper H.S. Dik     void *ctxt, void *pres, boolean_t wantattr,
89134a1f4eSCasper H.S. Dik     int *pcnt, char *profs[MAXPROFS])
907c478bd9Sstevel@tonic-gate {
91134a1f4eSCasper H.S. Dik 	char *prof, *last;
927c478bd9Sstevel@tonic-gate 	char *profiles;
937c478bd9Sstevel@tonic-gate 	profattr_t *pa;
947c478bd9Sstevel@tonic-gate 	int i;
95134a1f4eSCasper H.S. Dik 	int res = 0;
967c478bd9Sstevel@tonic-gate 
97134a1f4eSCasper H.S. Dik 	if (cprofiles == NULL)
987c478bd9Sstevel@tonic-gate 		return (0);
99134a1f4eSCasper H.S. Dik 
100134a1f4eSCasper H.S. Dik 	if (*pcnt > 0 && strcmp(profs[*pcnt - 1], PROFILE_STOP) == NULL)
101134a1f4eSCasper H.S. Dik 		return (0);
102134a1f4eSCasper H.S. Dik 
103134a1f4eSCasper H.S. Dik 	COPYTOSTACK(profiles, cprofiles)
104134a1f4eSCasper H.S. Dik 
105134a1f4eSCasper H.S. Dik 	while (prof = strtok_r(profiles, KV_SEPSTR, &last)) {
106134a1f4eSCasper H.S. Dik 
107134a1f4eSCasper H.S. Dik 		profiles = NULL;	/* For next iterations of strtok_r */
108134a1f4eSCasper H.S. Dik 
109134a1f4eSCasper H.S. Dik 		for (i = 0; i < *pcnt; i++)
110134a1f4eSCasper H.S. Dik 			if (strcmp(profs[i], prof) == 0)
111134a1f4eSCasper H.S. Dik 				goto cont;
112134a1f4eSCasper H.S. Dik 
113134a1f4eSCasper H.S. Dik 		if (*pcnt >= MAXPROFS)		/* oops: too many profs */
114134a1f4eSCasper H.S. Dik 			return (-1);
115134a1f4eSCasper H.S. Dik 
116134a1f4eSCasper H.S. Dik 		/* Add it */
117134a1f4eSCasper H.S. Dik 		profs[(*pcnt)++] = strdup(prof);
118134a1f4eSCasper H.S. Dik 
119134a1f4eSCasper H.S. Dik 		if (strcmp(profs[*pcnt - 1], PROFILE_STOP) == 0)
120134a1f4eSCasper H.S. Dik 			break;
121134a1f4eSCasper H.S. Dik 
122134a1f4eSCasper H.S. Dik 		/* find the profiles for this profile */
123134a1f4eSCasper H.S. Dik 		pa = getprofnam(prof);
124134a1f4eSCasper H.S. Dik 
125134a1f4eSCasper H.S. Dik 		if (cb != NULL && (!wantattr || pa != NULL && pa->attr != NULL))
126134a1f4eSCasper H.S. Dik 			res = cb(prof, pa ? pa->attr : NULL, ctxt, pres);
127134a1f4eSCasper H.S. Dik 
128134a1f4eSCasper H.S. Dik 		if (pa != NULL) {
129134a1f4eSCasper H.S. Dik 			if (res == 0 && pa->attr != NULL) {
130134a1f4eSCasper H.S. Dik 				res = _enum_common_p(GETPROF(pa->attr), cb,
131134a1f4eSCasper H.S. Dik 				    ctxt, pres, wantattr, pcnt, profs);
132134a1f4eSCasper H.S. Dik 			}
133134a1f4eSCasper H.S. Dik 			free_profattr(pa);
134134a1f4eSCasper H.S. Dik 		}
135134a1f4eSCasper H.S. Dik 		if (res != 0)
136134a1f4eSCasper H.S. Dik 			return (res);
137134a1f4eSCasper H.S. Dik cont:
138134a1f4eSCasper H.S. Dik 		continue;
139134a1f4eSCasper H.S. Dik 	}
140134a1f4eSCasper H.S. Dik 	return (res);
141134a1f4eSCasper H.S. Dik }
142134a1f4eSCasper H.S. Dik 
143134a1f4eSCasper H.S. Dik /*
144134a1f4eSCasper H.S. Dik  * Enumerate all attributes associated with a username and the profiles
145134a1f4eSCasper H.S. Dik  * associated with the user.
146134a1f4eSCasper H.S. Dik  */
147134a1f4eSCasper H.S. Dik static int
148134a1f4eSCasper H.S. Dik _enum_common(const char *username,
149134a1f4eSCasper H.S. Dik     int (*cb)(const char *, kva_t *, void *, void *),
150134a1f4eSCasper H.S. Dik     void *ctxt, void *pres, boolean_t wantattr)
151134a1f4eSCasper H.S. Dik {
152134a1f4eSCasper H.S. Dik 	userattr_t *ua;
153134a1f4eSCasper H.S. Dik 	int res = 0;
154134a1f4eSCasper H.S. Dik 	int cnt = 0;
155134a1f4eSCasper H.S. Dik 	char *profs[MAXPROFS];
156134a1f4eSCasper H.S. Dik 	kva_t *kattrs;
157134a1f4eSCasper H.S. Dik 
158134a1f4eSCasper H.S. Dik 	if (cb == NULL)
159134a1f4eSCasper H.S. Dik 		return (-1);
160134a1f4eSCasper H.S. Dik 
161134a1f4eSCasper H.S. Dik 	ua = getusernam(username);
162134a1f4eSCasper H.S. Dik 
163134a1f4eSCasper H.S. Dik 	if (ua != NULL) {
164134a1f4eSCasper H.S. Dik 		if (ua->attr != NULL) {
165134a1f4eSCasper H.S. Dik 			if (wantattr)
166134a1f4eSCasper H.S. Dik 				res = cb(NULL, ua->attr, ctxt, pres);
167134a1f4eSCasper H.S. Dik 			if (res == 0) {
168134a1f4eSCasper H.S. Dik 				res = _enum_common_p(GETPROF(ua->attr),
169134a1f4eSCasper H.S. Dik 				    cb, ctxt, pres, wantattr, &cnt, profs);
170134a1f4eSCasper H.S. Dik 			}
171134a1f4eSCasper H.S. Dik 		}
172134a1f4eSCasper H.S. Dik 		free_userattr(ua);
173*bf859931SCasper H.S. Dik 		if (res != 0) {
174*bf859931SCasper H.S. Dik 			free_proflist(profs, cnt);
175134a1f4eSCasper H.S. Dik 			return (res);
176134a1f4eSCasper H.S. Dik 		}
177*bf859931SCasper H.S. Dik 	}
178134a1f4eSCasper H.S. Dik 
179134a1f4eSCasper H.S. Dik 	if ((cnt == 0 || strcmp(profs[cnt-1], PROFILE_STOP) != 0) &&
180134a1f4eSCasper H.S. Dik 	    (kattrs = get_default_attrs(username)) != NULL) {
181134a1f4eSCasper H.S. Dik 
182134a1f4eSCasper H.S. Dik 		res = _enum_common_p(GETCONSPROF(kattrs), cb, ctxt, pres,
183134a1f4eSCasper H.S. Dik 		    wantattr, &cnt, profs);
184134a1f4eSCasper H.S. Dik 
185134a1f4eSCasper H.S. Dik 		if (res == 0) {
186134a1f4eSCasper H.S. Dik 			res = _enum_common_p(GETPROF(kattrs), cb, ctxt, pres,
187134a1f4eSCasper H.S. Dik 			    wantattr, &cnt, profs);
188134a1f4eSCasper H.S. Dik 		}
189134a1f4eSCasper H.S. Dik 
190134a1f4eSCasper H.S. Dik 		if (res == 0 && wantattr)
191134a1f4eSCasper H.S. Dik 			res = cb(NULL, kattrs, ctxt, pres);
192134a1f4eSCasper H.S. Dik 
193134a1f4eSCasper H.S. Dik 		free_default_attrs(kattrs);
194134a1f4eSCasper H.S. Dik 	}
195134a1f4eSCasper H.S. Dik 
196134a1f4eSCasper H.S. Dik 	free_proflist(profs, cnt);
197134a1f4eSCasper H.S. Dik 
198134a1f4eSCasper H.S. Dik 	return (res);
199134a1f4eSCasper H.S. Dik }
200134a1f4eSCasper H.S. Dik 
201134a1f4eSCasper H.S. Dik /*
202134a1f4eSCasper H.S. Dik  * Enumerate profiles with a username argument.
203134a1f4eSCasper H.S. Dik  */
204134a1f4eSCasper H.S. Dik int
205134a1f4eSCasper H.S. Dik _enum_profs(const char *username,
206134a1f4eSCasper H.S. Dik     int (*cb)(const char *, kva_t *, void *, void *),
207134a1f4eSCasper H.S. Dik     void *ctxt, void *pres)
208134a1f4eSCasper H.S. Dik {
209134a1f4eSCasper H.S. Dik 	return (_enum_common(username, cb, ctxt, pres, B_FALSE));
210134a1f4eSCasper H.S. Dik }
211134a1f4eSCasper H.S. Dik 
212134a1f4eSCasper H.S. Dik /*
213134a1f4eSCasper H.S. Dik  * Enumerate attributes with a username argument.
214134a1f4eSCasper H.S. Dik  */
215134a1f4eSCasper H.S. Dik int
216134a1f4eSCasper H.S. Dik _enum_attrs(const char *username,
217134a1f4eSCasper H.S. Dik     int (*cb)(const char *, kva_t *, void *, void *),
218134a1f4eSCasper H.S. Dik     void *ctxt, void *pres)
219134a1f4eSCasper H.S. Dik {
220134a1f4eSCasper H.S. Dik 	return (_enum_common(username, cb, ctxt, pres, B_TRUE));
221134a1f4eSCasper H.S. Dik }
222134a1f4eSCasper H.S. Dik 
223134a1f4eSCasper H.S. Dik 
224134a1f4eSCasper H.S. Dik /*
225134a1f4eSCasper H.S. Dik  * Enumerate authorizations in the "auths" argument.
226134a1f4eSCasper H.S. Dik  */
227134a1f4eSCasper H.S. Dik static int
228134a1f4eSCasper H.S. Dik _enum_auths_a(const char *cauths, int (*cb)(const char *, void *, void *),
229134a1f4eSCasper H.S. Dik     void *ctxt, void *pres)
230134a1f4eSCasper H.S. Dik {
231134a1f4eSCasper H.S. Dik 	char *auth, *last, *auths;
232134a1f4eSCasper H.S. Dik 	int res = 0;
233134a1f4eSCasper H.S. Dik 
234134a1f4eSCasper H.S. Dik 	if (cauths == NULL || cb == NULL)
235134a1f4eSCasper H.S. Dik 		return (0);
236134a1f4eSCasper H.S. Dik 
237134a1f4eSCasper H.S. Dik 	COPYTOSTACK(auths, cauths)
238134a1f4eSCasper H.S. Dik 
239134a1f4eSCasper H.S. Dik 	while (auth = strtok_r(auths, KV_SEPSTR, &last)) {
240134a1f4eSCasper H.S. Dik 		auths = NULL;		/* For next iterations of strtok_r */
241134a1f4eSCasper H.S. Dik 
242134a1f4eSCasper H.S. Dik 		res = cb(auth, ctxt, pres);
243134a1f4eSCasper H.S. Dik 
244134a1f4eSCasper H.S. Dik 		if (res != 0)
245134a1f4eSCasper H.S. Dik 			return (res);
246134a1f4eSCasper H.S. Dik 	}
247134a1f4eSCasper H.S. Dik 	return (res);
248134a1f4eSCasper H.S. Dik }
249134a1f4eSCasper H.S. Dik 
250134a1f4eSCasper H.S. Dik /*
251134a1f4eSCasper H.S. Dik  * Magic struct and function to allow using the _enum_attrs functions to
252134a1f4eSCasper H.S. Dik  * enumerate the authorizations.
253134a1f4eSCasper H.S. Dik  */
254134a1f4eSCasper H.S. Dik typedef struct ccomm2auth {
255134a1f4eSCasper H.S. Dik 	int (*cb)(const char *, void *, void *);
256134a1f4eSCasper H.S. Dik 	void *ctxt;
257134a1f4eSCasper H.S. Dik } ccomm2auth;
258134a1f4eSCasper H.S. Dik 
259134a1f4eSCasper H.S. Dik /*ARGSUSED*/
260134a1f4eSCasper H.S. Dik static int
261134a1f4eSCasper H.S. Dik comm2auth(const char *name, kva_t *attr, void *ctxt, void *pres)
262134a1f4eSCasper H.S. Dik {
263134a1f4eSCasper H.S. Dik 	ccomm2auth *ca = ctxt;
264134a1f4eSCasper H.S. Dik 	char *auths;
265134a1f4eSCasper H.S. Dik 
266134a1f4eSCasper H.S. Dik 	/* Note: PROFATTR_AUTHS_KW is equal to USERATTR_AUTHS_KW */
267134a1f4eSCasper H.S. Dik 	auths = kva_match(attr, PROFATTR_AUTHS_KW);
268134a1f4eSCasper H.S. Dik 	return (_enum_auths_a(auths, ca->cb, ca->ctxt, pres));
269134a1f4eSCasper H.S. Dik }
270134a1f4eSCasper H.S. Dik 
271134a1f4eSCasper H.S. Dik /*
272134a1f4eSCasper H.S. Dik  * Enumerate authorizations for username.
273134a1f4eSCasper H.S. Dik  */
274134a1f4eSCasper H.S. Dik int
275134a1f4eSCasper H.S. Dik _enum_auths(const char *username,
276134a1f4eSCasper H.S. Dik     int (*cb)(const char *, void *, void *),
277134a1f4eSCasper H.S. Dik     void *ctxt, void *pres)
278134a1f4eSCasper H.S. Dik {
279134a1f4eSCasper H.S. Dik 	ccomm2auth c2a;
280134a1f4eSCasper H.S. Dik 
281134a1f4eSCasper H.S. Dik 	if (cb == NULL)
282134a1f4eSCasper H.S. Dik 		return (-1);
283134a1f4eSCasper H.S. Dik 
284134a1f4eSCasper H.S. Dik 	c2a.cb = cb;
285134a1f4eSCasper H.S. Dik 	c2a.ctxt = ctxt;
286134a1f4eSCasper H.S. Dik 
287134a1f4eSCasper H.S. Dik 	return (_enum_common(username, comm2auth, &c2a, pres, B_TRUE));
2887c478bd9Sstevel@tonic-gate }
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate int
2917c478bd9Sstevel@tonic-gate _auth_match(const char *pattern, const char *auth)
2927c478bd9Sstevel@tonic-gate {
2937c478bd9Sstevel@tonic-gate 	size_t len;
2947c478bd9Sstevel@tonic-gate 	char *grant;
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	len = strlen(pattern);
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 	/*
2997c478bd9Sstevel@tonic-gate 	 * If the wildcard is not in the last position in the string, don't
3007c478bd9Sstevel@tonic-gate 	 * match against it.
3017c478bd9Sstevel@tonic-gate 	 */
302134a1f4eSCasper H.S. Dik 	if (pattern[len-1] != KV_WILDCHAR)
3037c478bd9Sstevel@tonic-gate 		return (0);
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate 	/*
3067c478bd9Sstevel@tonic-gate 	 * If the strings are identical up to the wildcard and auth does not
3077c478bd9Sstevel@tonic-gate 	 * end in "grant", then we have a match.
3087c478bd9Sstevel@tonic-gate 	 */
3097c478bd9Sstevel@tonic-gate 	if (strncmp(pattern, auth, len-1) == 0) {
3107c478bd9Sstevel@tonic-gate 		grant = strrchr(auth, '.');
3117c478bd9Sstevel@tonic-gate 		if (grant != NULL) {
3127c478bd9Sstevel@tonic-gate 			if (strncmp(grant + 1, "grant", 5) != NULL)
3137c478bd9Sstevel@tonic-gate 				return (1);
3147c478bd9Sstevel@tonic-gate 		}
3157c478bd9Sstevel@tonic-gate 	}
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 	return (0);
3187c478bd9Sstevel@tonic-gate }
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate static int
321134a1f4eSCasper H.S. Dik _is_authorized(const char *auth, void *authname, void *res)
3227c478bd9Sstevel@tonic-gate {
323134a1f4eSCasper H.S. Dik 	int *resp = res;
3247c478bd9Sstevel@tonic-gate 
325134a1f4eSCasper H.S. Dik 	if (strcmp(authname, auth) == 0 ||
326134a1f4eSCasper H.S. Dik 	    (strchr(auth, KV_WILDCHAR) != NULL &&
327134a1f4eSCasper H.S. Dik 	    _auth_match(auth, authname))) {
328134a1f4eSCasper H.S. Dik 		*resp = 1;
329134a1f4eSCasper H.S. Dik 		return (1);
3307c478bd9Sstevel@tonic-gate 	}
3317c478bd9Sstevel@tonic-gate 
332134a1f4eSCasper H.S. Dik 	return (0);
3337c478bd9Sstevel@tonic-gate }
3347c478bd9Sstevel@tonic-gate 
335134a1f4eSCasper H.S. Dik int
336134a1f4eSCasper H.S. Dik chkauthattr(const char *authname, const char *username)
3377c478bd9Sstevel@tonic-gate {
338134a1f4eSCasper H.S. Dik 	int		auth_granted = 0;
3397c478bd9Sstevel@tonic-gate 
340134a1f4eSCasper H.S. Dik 	if (authname == NULL || username == NULL)
3417c478bd9Sstevel@tonic-gate 		return (0);
3427c478bd9Sstevel@tonic-gate 
343134a1f4eSCasper H.S. Dik 	(void) _enum_auths(username, _is_authorized, (char *)authname,
344134a1f4eSCasper H.S. Dik 	    &auth_granted);
3457c478bd9Sstevel@tonic-gate 
346134a1f4eSCasper H.S. Dik 	return (auth_granted);
3477c478bd9Sstevel@tonic-gate }
348499fd601Sgww 
349ceeba6f9Srui zang - Sun Microsystems - Beijing China #define	CONSOLE_USER_LINK "/dev/vt/console_user"
350499fd601Sgww 
351499fd601Sgww static int
352499fd601Sgww is_cons_user(const char *user)
353499fd601Sgww {
354499fd601Sgww 	struct stat	cons;
355499fd601Sgww 	struct passwd	pw;
356499fd601Sgww 	char		pwbuf[NSS_BUFLEN_PASSWD];
357499fd601Sgww 
358499fd601Sgww 	if (user == NULL) {
359499fd601Sgww 		return (0);
360499fd601Sgww 	}
361ceeba6f9Srui zang - Sun Microsystems - Beijing China 	if (stat(CONSOLE_USER_LINK, &cons) == -1) {
362499fd601Sgww 		return (0);
363499fd601Sgww 	}
364499fd601Sgww 	if (getpwnam_r(user, &pw, pwbuf, sizeof (pwbuf)) == NULL) {
365499fd601Sgww 		return (0);
366499fd601Sgww 	}
367499fd601Sgww 
368499fd601Sgww 	return (pw.pw_uid == cons.st_uid);
369499fd601Sgww }
370499fd601Sgww 
371134a1f4eSCasper H.S. Dik static void
372134a1f4eSCasper H.S. Dik free_default_attrs(kva_t *kva)
373499fd601Sgww {
374134a1f4eSCasper H.S. Dik 	int i;
375134a1f4eSCasper H.S. Dik 
376134a1f4eSCasper H.S. Dik 	for (i = 0; i < kva->length; i++)
377134a1f4eSCasper H.S. Dik 		free(kva->data[i].value);
378134a1f4eSCasper H.S. Dik 
379134a1f4eSCasper H.S. Dik 	free(kva);
380134a1f4eSCasper H.S. Dik }
381134a1f4eSCasper H.S. Dik 
382134a1f4eSCasper H.S. Dik /*
383134a1f4eSCasper H.S. Dik  * Return the default attributes; this are ignored when a STOP profile
384134a1f4eSCasper H.S. Dik  * was found.
385134a1f4eSCasper H.S. Dik  */
386134a1f4eSCasper H.S. Dik static kva_t *
387134a1f4eSCasper H.S. Dik get_default_attrs(const char *user)
388134a1f4eSCasper H.S. Dik {
389b9175c69SKenjiro Tsuji 	void *defp;
390134a1f4eSCasper H.S. Dik 	kva_t *kva;
391134a1f4eSCasper H.S. Dik 	int i;
392499fd601Sgww 
393134a1f4eSCasper H.S. Dik 	kva = malloc(sizeof (kva_t) + sizeof (kv_t) * NDFLTPLY);
394134a1f4eSCasper H.S. Dik 
395134a1f4eSCasper H.S. Dik 	if (kva == NULL)
396134a1f4eSCasper H.S. Dik 		return (NULL);
397134a1f4eSCasper H.S. Dik 
398134a1f4eSCasper H.S. Dik 	kva->data = (kv_t *)(void *)&kva[1];
399134a1f4eSCasper H.S. Dik 	kva->length = 0;
400134a1f4eSCasper H.S. Dik 
401134a1f4eSCasper H.S. Dik 	if ((defp = defopen_r(AUTH_POLICY)) == NULL)
402134a1f4eSCasper H.S. Dik 		goto return_null;
403134a1f4eSCasper H.S. Dik 
404134a1f4eSCasper H.S. Dik 	for (i = is_cons_user(user) ? 0 : 1; i < NDFLTPLY; i++) {
405134a1f4eSCasper H.S. Dik 		char *cp = defread_r(dfltply[i].defkw, defp);
406134a1f4eSCasper H.S. Dik 
407134a1f4eSCasper H.S. Dik 		if (cp == NULL)
408134a1f4eSCasper H.S. Dik 			continue;
409134a1f4eSCasper H.S. Dik 		if ((cp = strdup(cp)) == NULL)
410134a1f4eSCasper H.S. Dik 			goto return_null;
411134a1f4eSCasper H.S. Dik 
412134a1f4eSCasper H.S. Dik 		kva->data[kva->length].key = dfltply[i].attr;
413134a1f4eSCasper H.S. Dik 		kva->data[kva->length++].value = cp;
414499fd601Sgww 	}
415499fd601Sgww 
416134a1f4eSCasper H.S. Dik 	(void) defclose_r(defp);
417134a1f4eSCasper H.S. Dik 	return (kva);
418499fd601Sgww 
419134a1f4eSCasper H.S. Dik return_null:
420134a1f4eSCasper H.S. Dik 	if (defp != NULL)
421134a1f4eSCasper H.S. Dik 		(void) defclose_r(defp);
422499fd601Sgww 
423134a1f4eSCasper H.S. Dik 	free_default_attrs(kva);
424134a1f4eSCasper H.S. Dik 	return (NULL);
425499fd601Sgww }
426