xref: /titanic_52/usr/src/lib/libsecdb/common/chkauthattr.c (revision cb8a054b1ab30d5caa746e6c44f29d4c9d3071c1)
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  */
85*cb8a054bSGlenn Faden static int _auth_match_noun(const char *, const char *, size_t, const char *);
86*cb8a054bSGlenn Faden 
877c478bd9Sstevel@tonic-gate int
88134a1f4eSCasper H.S. Dik _enum_common_p(const char *cprofiles,
89134a1f4eSCasper H.S. Dik     int (*cb)(const char *, kva_t *, void *, void *),
90134a1f4eSCasper H.S. Dik     void *ctxt, void *pres, boolean_t wantattr,
91134a1f4eSCasper H.S. Dik     int *pcnt, char *profs[MAXPROFS])
927c478bd9Sstevel@tonic-gate {
93134a1f4eSCasper H.S. Dik 	char *prof, *last;
947c478bd9Sstevel@tonic-gate 	char *profiles;
957c478bd9Sstevel@tonic-gate 	profattr_t *pa;
967c478bd9Sstevel@tonic-gate 	int i;
97134a1f4eSCasper H.S. Dik 	int res = 0;
987c478bd9Sstevel@tonic-gate 
99134a1f4eSCasper H.S. Dik 	if (cprofiles == NULL)
1007c478bd9Sstevel@tonic-gate 		return (0);
101134a1f4eSCasper H.S. Dik 
102134a1f4eSCasper H.S. Dik 	if (*pcnt > 0 && strcmp(profs[*pcnt - 1], PROFILE_STOP) == NULL)
103134a1f4eSCasper H.S. Dik 		return (0);
104134a1f4eSCasper H.S. Dik 
105134a1f4eSCasper H.S. Dik 	COPYTOSTACK(profiles, cprofiles)
106134a1f4eSCasper H.S. Dik 
107134a1f4eSCasper H.S. Dik 	while (prof = strtok_r(profiles, KV_SEPSTR, &last)) {
108134a1f4eSCasper H.S. Dik 
109134a1f4eSCasper H.S. Dik 		profiles = NULL;	/* For next iterations of strtok_r */
110134a1f4eSCasper H.S. Dik 
111134a1f4eSCasper H.S. Dik 		for (i = 0; i < *pcnt; i++)
112134a1f4eSCasper H.S. Dik 			if (strcmp(profs[i], prof) == 0)
113134a1f4eSCasper H.S. Dik 				goto cont;
114134a1f4eSCasper H.S. Dik 
115134a1f4eSCasper H.S. Dik 		if (*pcnt >= MAXPROFS)		/* oops: too many profs */
116134a1f4eSCasper H.S. Dik 			return (-1);
117134a1f4eSCasper H.S. Dik 
118134a1f4eSCasper H.S. Dik 		/* Add it */
119134a1f4eSCasper H.S. Dik 		profs[(*pcnt)++] = strdup(prof);
120134a1f4eSCasper H.S. Dik 
121134a1f4eSCasper H.S. Dik 		if (strcmp(profs[*pcnt - 1], PROFILE_STOP) == 0)
122134a1f4eSCasper H.S. Dik 			break;
123134a1f4eSCasper H.S. Dik 
124134a1f4eSCasper H.S. Dik 		/* find the profiles for this profile */
125134a1f4eSCasper H.S. Dik 		pa = getprofnam(prof);
126134a1f4eSCasper H.S. Dik 
127134a1f4eSCasper H.S. Dik 		if (cb != NULL && (!wantattr || pa != NULL && pa->attr != NULL))
128134a1f4eSCasper H.S. Dik 			res = cb(prof, pa ? pa->attr : NULL, ctxt, pres);
129134a1f4eSCasper H.S. Dik 
130134a1f4eSCasper H.S. Dik 		if (pa != NULL) {
131134a1f4eSCasper H.S. Dik 			if (res == 0 && pa->attr != NULL) {
132134a1f4eSCasper H.S. Dik 				res = _enum_common_p(GETPROF(pa->attr), cb,
133134a1f4eSCasper H.S. Dik 				    ctxt, pres, wantattr, pcnt, profs);
134134a1f4eSCasper H.S. Dik 			}
135134a1f4eSCasper H.S. Dik 			free_profattr(pa);
136134a1f4eSCasper H.S. Dik 		}
137134a1f4eSCasper H.S. Dik 		if (res != 0)
138134a1f4eSCasper H.S. Dik 			return (res);
139134a1f4eSCasper H.S. Dik cont:
140134a1f4eSCasper H.S. Dik 		continue;
141134a1f4eSCasper H.S. Dik 	}
142134a1f4eSCasper H.S. Dik 	return (res);
143134a1f4eSCasper H.S. Dik }
144134a1f4eSCasper H.S. Dik 
145134a1f4eSCasper H.S. Dik /*
146134a1f4eSCasper H.S. Dik  * Enumerate all attributes associated with a username and the profiles
147134a1f4eSCasper H.S. Dik  * associated with the user.
148134a1f4eSCasper H.S. Dik  */
149134a1f4eSCasper H.S. Dik static int
150134a1f4eSCasper H.S. Dik _enum_common(const char *username,
151134a1f4eSCasper H.S. Dik     int (*cb)(const char *, kva_t *, void *, void *),
152134a1f4eSCasper H.S. Dik     void *ctxt, void *pres, boolean_t wantattr)
153134a1f4eSCasper H.S. Dik {
154134a1f4eSCasper H.S. Dik 	userattr_t *ua;
155134a1f4eSCasper H.S. Dik 	int res = 0;
156134a1f4eSCasper H.S. Dik 	int cnt = 0;
157134a1f4eSCasper H.S. Dik 	char *profs[MAXPROFS];
158134a1f4eSCasper H.S. Dik 	kva_t *kattrs;
159134a1f4eSCasper H.S. Dik 
160134a1f4eSCasper H.S. Dik 	if (cb == NULL)
161134a1f4eSCasper H.S. Dik 		return (-1);
162134a1f4eSCasper H.S. Dik 
163134a1f4eSCasper H.S. Dik 	ua = getusernam(username);
164134a1f4eSCasper H.S. Dik 
165134a1f4eSCasper H.S. Dik 	if (ua != NULL) {
166134a1f4eSCasper H.S. Dik 		if (ua->attr != NULL) {
167134a1f4eSCasper H.S. Dik 			if (wantattr)
168134a1f4eSCasper H.S. Dik 				res = cb(NULL, ua->attr, ctxt, pres);
169134a1f4eSCasper H.S. Dik 			if (res == 0) {
170134a1f4eSCasper H.S. Dik 				res = _enum_common_p(GETPROF(ua->attr),
171134a1f4eSCasper H.S. Dik 				    cb, ctxt, pres, wantattr, &cnt, profs);
172134a1f4eSCasper H.S. Dik 			}
173134a1f4eSCasper H.S. Dik 		}
174134a1f4eSCasper H.S. Dik 		free_userattr(ua);
175bf859931SCasper H.S. Dik 		if (res != 0) {
176bf859931SCasper H.S. Dik 			free_proflist(profs, cnt);
177134a1f4eSCasper H.S. Dik 			return (res);
178134a1f4eSCasper H.S. Dik 		}
179bf859931SCasper H.S. Dik 	}
180134a1f4eSCasper H.S. Dik 
181134a1f4eSCasper H.S. Dik 	if ((cnt == 0 || strcmp(profs[cnt-1], PROFILE_STOP) != 0) &&
182134a1f4eSCasper H.S. Dik 	    (kattrs = get_default_attrs(username)) != NULL) {
183134a1f4eSCasper H.S. Dik 
184134a1f4eSCasper H.S. Dik 		res = _enum_common_p(GETCONSPROF(kattrs), cb, ctxt, pres,
185134a1f4eSCasper H.S. Dik 		    wantattr, &cnt, profs);
186134a1f4eSCasper H.S. Dik 
187134a1f4eSCasper H.S. Dik 		if (res == 0) {
188134a1f4eSCasper H.S. Dik 			res = _enum_common_p(GETPROF(kattrs), cb, ctxt, pres,
189134a1f4eSCasper H.S. Dik 			    wantattr, &cnt, profs);
190134a1f4eSCasper H.S. Dik 		}
191134a1f4eSCasper H.S. Dik 
192134a1f4eSCasper H.S. Dik 		if (res == 0 && wantattr)
193134a1f4eSCasper H.S. Dik 			res = cb(NULL, kattrs, ctxt, pres);
194134a1f4eSCasper H.S. Dik 
195134a1f4eSCasper H.S. Dik 		free_default_attrs(kattrs);
196134a1f4eSCasper H.S. Dik 	}
197134a1f4eSCasper H.S. Dik 
198134a1f4eSCasper H.S. Dik 	free_proflist(profs, cnt);
199134a1f4eSCasper H.S. Dik 
200134a1f4eSCasper H.S. Dik 	return (res);
201134a1f4eSCasper H.S. Dik }
202134a1f4eSCasper H.S. Dik 
203134a1f4eSCasper H.S. Dik /*
204134a1f4eSCasper H.S. Dik  * Enumerate profiles with a username argument.
205134a1f4eSCasper H.S. Dik  */
206134a1f4eSCasper H.S. Dik int
207134a1f4eSCasper H.S. Dik _enum_profs(const char *username,
208134a1f4eSCasper H.S. Dik     int (*cb)(const char *, kva_t *, void *, void *),
209134a1f4eSCasper H.S. Dik     void *ctxt, void *pres)
210134a1f4eSCasper H.S. Dik {
211134a1f4eSCasper H.S. Dik 	return (_enum_common(username, cb, ctxt, pres, B_FALSE));
212134a1f4eSCasper H.S. Dik }
213134a1f4eSCasper H.S. Dik 
214134a1f4eSCasper H.S. Dik /*
215134a1f4eSCasper H.S. Dik  * Enumerate attributes with a username argument.
216134a1f4eSCasper H.S. Dik  */
217134a1f4eSCasper H.S. Dik int
218134a1f4eSCasper H.S. Dik _enum_attrs(const char *username,
219134a1f4eSCasper H.S. Dik     int (*cb)(const char *, kva_t *, void *, void *),
220134a1f4eSCasper H.S. Dik     void *ctxt, void *pres)
221134a1f4eSCasper H.S. Dik {
222134a1f4eSCasper H.S. Dik 	return (_enum_common(username, cb, ctxt, pres, B_TRUE));
223134a1f4eSCasper H.S. Dik }
224134a1f4eSCasper H.S. Dik 
225134a1f4eSCasper H.S. Dik 
226134a1f4eSCasper H.S. Dik /*
227134a1f4eSCasper H.S. Dik  * Enumerate authorizations in the "auths" argument.
228134a1f4eSCasper H.S. Dik  */
229134a1f4eSCasper H.S. Dik static int
230134a1f4eSCasper H.S. Dik _enum_auths_a(const char *cauths, int (*cb)(const char *, void *, void *),
231134a1f4eSCasper H.S. Dik     void *ctxt, void *pres)
232134a1f4eSCasper H.S. Dik {
233134a1f4eSCasper H.S. Dik 	char *auth, *last, *auths;
234134a1f4eSCasper H.S. Dik 	int res = 0;
235134a1f4eSCasper H.S. Dik 
236134a1f4eSCasper H.S. Dik 	if (cauths == NULL || cb == NULL)
237134a1f4eSCasper H.S. Dik 		return (0);
238134a1f4eSCasper H.S. Dik 
239134a1f4eSCasper H.S. Dik 	COPYTOSTACK(auths, cauths)
240134a1f4eSCasper H.S. Dik 
241134a1f4eSCasper H.S. Dik 	while (auth = strtok_r(auths, KV_SEPSTR, &last)) {
242134a1f4eSCasper H.S. Dik 		auths = NULL;		/* For next iterations of strtok_r */
243134a1f4eSCasper H.S. Dik 
244134a1f4eSCasper H.S. Dik 		res = cb(auth, ctxt, pres);
245134a1f4eSCasper H.S. Dik 
246134a1f4eSCasper H.S. Dik 		if (res != 0)
247134a1f4eSCasper H.S. Dik 			return (res);
248134a1f4eSCasper H.S. Dik 	}
249134a1f4eSCasper H.S. Dik 	return (res);
250134a1f4eSCasper H.S. Dik }
251134a1f4eSCasper H.S. Dik 
252134a1f4eSCasper H.S. Dik /*
253134a1f4eSCasper H.S. Dik  * Magic struct and function to allow using the _enum_attrs functions to
254134a1f4eSCasper H.S. Dik  * enumerate the authorizations.
255134a1f4eSCasper H.S. Dik  */
256134a1f4eSCasper H.S. Dik typedef struct ccomm2auth {
257134a1f4eSCasper H.S. Dik 	int (*cb)(const char *, void *, void *);
258134a1f4eSCasper H.S. Dik 	void *ctxt;
259134a1f4eSCasper H.S. Dik } ccomm2auth;
260134a1f4eSCasper H.S. Dik 
261134a1f4eSCasper H.S. Dik /*ARGSUSED*/
262134a1f4eSCasper H.S. Dik static int
263134a1f4eSCasper H.S. Dik comm2auth(const char *name, kva_t *attr, void *ctxt, void *pres)
264134a1f4eSCasper H.S. Dik {
265134a1f4eSCasper H.S. Dik 	ccomm2auth *ca = ctxt;
266134a1f4eSCasper H.S. Dik 	char *auths;
267134a1f4eSCasper H.S. Dik 
268134a1f4eSCasper H.S. Dik 	/* Note: PROFATTR_AUTHS_KW is equal to USERATTR_AUTHS_KW */
269134a1f4eSCasper H.S. Dik 	auths = kva_match(attr, PROFATTR_AUTHS_KW);
270134a1f4eSCasper H.S. Dik 	return (_enum_auths_a(auths, ca->cb, ca->ctxt, pres));
271134a1f4eSCasper H.S. Dik }
272134a1f4eSCasper H.S. Dik 
273134a1f4eSCasper H.S. Dik /*
274134a1f4eSCasper H.S. Dik  * Enumerate authorizations for username.
275134a1f4eSCasper H.S. Dik  */
276134a1f4eSCasper H.S. Dik int
277134a1f4eSCasper H.S. Dik _enum_auths(const char *username,
278134a1f4eSCasper H.S. Dik     int (*cb)(const char *, void *, void *),
279134a1f4eSCasper H.S. Dik     void *ctxt, void *pres)
280134a1f4eSCasper H.S. Dik {
281134a1f4eSCasper H.S. Dik 	ccomm2auth c2a;
282134a1f4eSCasper H.S. Dik 
283134a1f4eSCasper H.S. Dik 	if (cb == NULL)
284134a1f4eSCasper H.S. Dik 		return (-1);
285134a1f4eSCasper H.S. Dik 
286134a1f4eSCasper H.S. Dik 	c2a.cb = cb;
287134a1f4eSCasper H.S. Dik 	c2a.ctxt = ctxt;
288134a1f4eSCasper H.S. Dik 
289134a1f4eSCasper H.S. Dik 	return (_enum_common(username, comm2auth, &c2a, pres, B_TRUE));
2907c478bd9Sstevel@tonic-gate }
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate int
293*cb8a054bSGlenn Faden _auth_match_noun(const char *pattern, const char *auth,
294*cb8a054bSGlenn Faden     size_t auth_len, const char *auth_noun)
2957c478bd9Sstevel@tonic-gate {
296*cb8a054bSGlenn Faden 	size_t pattern_len;
2977c478bd9Sstevel@tonic-gate 	char *grant;
298*cb8a054bSGlenn Faden 	char *pattern_noun;
299*cb8a054bSGlenn Faden 	char *slash;
3007c478bd9Sstevel@tonic-gate 
301*cb8a054bSGlenn Faden 	pattern_len = strlen(pattern);
302*cb8a054bSGlenn Faden 	/*
303*cb8a054bSGlenn Faden 	 * If the specified authorization has a trailing object
304*cb8a054bSGlenn Faden 	 * and the current authorization we're checking also has
305*cb8a054bSGlenn Faden 	 * a trailing object, the object names must match.
306*cb8a054bSGlenn Faden 	 *
307*cb8a054bSGlenn Faden 	 * If there is no object name failure, then we must
308*cb8a054bSGlenn Faden 	 * check for an exact match of the two authorizations
309*cb8a054bSGlenn Faden 	 */
310*cb8a054bSGlenn Faden 	if (auth_noun != NULL) {
311*cb8a054bSGlenn Faden 		if ((slash = strchr(pattern, KV_OBJECTCHAR)) != NULL) {
312*cb8a054bSGlenn Faden 			pattern_noun = slash + 1;
313*cb8a054bSGlenn Faden 			pattern_len -= strlen(slash);
314*cb8a054bSGlenn Faden 			if (strcmp(pattern_noun, auth_noun) != 0)
315*cb8a054bSGlenn Faden 				return (0);
316*cb8a054bSGlenn Faden 		} else if ((auth_len == pattern_len) &&
317*cb8a054bSGlenn Faden 		    (strncmp(pattern, auth, pattern_len) == 0)) {
318*cb8a054bSGlenn Faden 			return (1);
319*cb8a054bSGlenn Faden 		}
320*cb8a054bSGlenn Faden 	}
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 	/*
3237c478bd9Sstevel@tonic-gate 	 * If the wildcard is not in the last position in the string, don't
3247c478bd9Sstevel@tonic-gate 	 * match against it.
3257c478bd9Sstevel@tonic-gate 	 */
326*cb8a054bSGlenn Faden 	if (pattern[pattern_len-1] != KV_WILDCHAR)
3277c478bd9Sstevel@tonic-gate 		return (0);
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 	/*
3307c478bd9Sstevel@tonic-gate 	 * If the strings are identical up to the wildcard and auth does not
3317c478bd9Sstevel@tonic-gate 	 * end in "grant", then we have a match.
3327c478bd9Sstevel@tonic-gate 	 */
333*cb8a054bSGlenn Faden 	if (strncmp(pattern, auth, pattern_len - 1) == 0) {
3347c478bd9Sstevel@tonic-gate 		grant = strrchr(auth, '.');
3357c478bd9Sstevel@tonic-gate 		if (grant != NULL) {
3367c478bd9Sstevel@tonic-gate 			if (strncmp(grant + 1, "grant", 5) != NULL)
3377c478bd9Sstevel@tonic-gate 				return (1);
3387c478bd9Sstevel@tonic-gate 		}
3397c478bd9Sstevel@tonic-gate 	}
3407c478bd9Sstevel@tonic-gate 	return (0);
3417c478bd9Sstevel@tonic-gate }
3427c478bd9Sstevel@tonic-gate 
343*cb8a054bSGlenn Faden int
344*cb8a054bSGlenn Faden _auth_match(const char *pattern, const char *auth)
345*cb8a054bSGlenn Faden {
346*cb8a054bSGlenn Faden 	return (_auth_match_noun(pattern, auth, strlen(auth), NULL));
347*cb8a054bSGlenn Faden }
348*cb8a054bSGlenn Faden 
3497c478bd9Sstevel@tonic-gate static int
350134a1f4eSCasper H.S. Dik _is_authorized(const char *auth, void *authname, void *res)
3517c478bd9Sstevel@tonic-gate {
352134a1f4eSCasper H.S. Dik 	int *resp = res;
353*cb8a054bSGlenn Faden 	char	*authname_noun;
354*cb8a054bSGlenn Faden 	char	*slash;
355*cb8a054bSGlenn Faden 	size_t	auth_len;
356*cb8a054bSGlenn Faden 	size_t	noun_len;
3577c478bd9Sstevel@tonic-gate 
358*cb8a054bSGlenn Faden 	auth_len = strlen(authname);
359*cb8a054bSGlenn Faden 	if ((slash = strchr(authname, KV_OBJECTCHAR)) != NULL) {
360*cb8a054bSGlenn Faden 		authname_noun = slash + 1;
361*cb8a054bSGlenn Faden 		noun_len = strlen(slash);
362*cb8a054bSGlenn Faden 		auth_len -= noun_len;
363*cb8a054bSGlenn Faden 	} else {
364*cb8a054bSGlenn Faden 		authname_noun = NULL;
365*cb8a054bSGlenn Faden 	}
366*cb8a054bSGlenn Faden 
367*cb8a054bSGlenn Faden 	if (strcmp(authname, auth) == 0) {
368*cb8a054bSGlenn Faden 		/* exact match, we're done */
369134a1f4eSCasper H.S. Dik 		*resp = 1;
370134a1f4eSCasper H.S. Dik 		return (1);
371*cb8a054bSGlenn Faden 	} else if (noun_len || strchr(auth, KV_WILDCHAR) != NULL) {
372*cb8a054bSGlenn Faden 		if (_auth_match_noun(auth, authname,
373*cb8a054bSGlenn Faden 		    auth_len, authname_noun)) {
374*cb8a054bSGlenn Faden 			*resp = 1;
375*cb8a054bSGlenn Faden 			return (1);
376*cb8a054bSGlenn Faden 		}
3777c478bd9Sstevel@tonic-gate 	}
3787c478bd9Sstevel@tonic-gate 
379134a1f4eSCasper H.S. Dik 	return (0);
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate 
382134a1f4eSCasper H.S. Dik int
383134a1f4eSCasper H.S. Dik chkauthattr(const char *authname, const char *username)
3847c478bd9Sstevel@tonic-gate {
385134a1f4eSCasper H.S. Dik 	int		auth_granted = 0;
3867c478bd9Sstevel@tonic-gate 
387134a1f4eSCasper H.S. Dik 	if (authname == NULL || username == NULL)
3887c478bd9Sstevel@tonic-gate 		return (0);
3897c478bd9Sstevel@tonic-gate 
390134a1f4eSCasper H.S. Dik 	(void) _enum_auths(username, _is_authorized, (char *)authname,
391134a1f4eSCasper H.S. Dik 	    &auth_granted);
3927c478bd9Sstevel@tonic-gate 
393134a1f4eSCasper H.S. Dik 	return (auth_granted);
3947c478bd9Sstevel@tonic-gate }
395499fd601Sgww 
396ceeba6f9Srui zang - Sun Microsystems - Beijing China #define	CONSOLE_USER_LINK "/dev/vt/console_user"
397499fd601Sgww 
398499fd601Sgww static int
399499fd601Sgww is_cons_user(const char *user)
400499fd601Sgww {
401499fd601Sgww 	struct stat	cons;
402499fd601Sgww 	struct passwd	pw;
403499fd601Sgww 	char		pwbuf[NSS_BUFLEN_PASSWD];
404499fd601Sgww 
405499fd601Sgww 	if (user == NULL) {
406499fd601Sgww 		return (0);
407499fd601Sgww 	}
408ceeba6f9Srui zang - Sun Microsystems - Beijing China 	if (stat(CONSOLE_USER_LINK, &cons) == -1) {
409499fd601Sgww 		return (0);
410499fd601Sgww 	}
411499fd601Sgww 	if (getpwnam_r(user, &pw, pwbuf, sizeof (pwbuf)) == NULL) {
412499fd601Sgww 		return (0);
413499fd601Sgww 	}
414499fd601Sgww 
415499fd601Sgww 	return (pw.pw_uid == cons.st_uid);
416499fd601Sgww }
417499fd601Sgww 
418134a1f4eSCasper H.S. Dik static void
419134a1f4eSCasper H.S. Dik free_default_attrs(kva_t *kva)
420499fd601Sgww {
421134a1f4eSCasper H.S. Dik 	int i;
422134a1f4eSCasper H.S. Dik 
423134a1f4eSCasper H.S. Dik 	for (i = 0; i < kva->length; i++)
424134a1f4eSCasper H.S. Dik 		free(kva->data[i].value);
425134a1f4eSCasper H.S. Dik 
426134a1f4eSCasper H.S. Dik 	free(kva);
427134a1f4eSCasper H.S. Dik }
428134a1f4eSCasper H.S. Dik 
429134a1f4eSCasper H.S. Dik /*
430134a1f4eSCasper H.S. Dik  * Return the default attributes; this are ignored when a STOP profile
431134a1f4eSCasper H.S. Dik  * was found.
432134a1f4eSCasper H.S. Dik  */
433134a1f4eSCasper H.S. Dik static kva_t *
434134a1f4eSCasper H.S. Dik get_default_attrs(const char *user)
435134a1f4eSCasper H.S. Dik {
436b9175c69SKenjiro Tsuji 	void *defp;
437134a1f4eSCasper H.S. Dik 	kva_t *kva;
438134a1f4eSCasper H.S. Dik 	int i;
439499fd601Sgww 
440134a1f4eSCasper H.S. Dik 	kva = malloc(sizeof (kva_t) + sizeof (kv_t) * NDFLTPLY);
441134a1f4eSCasper H.S. Dik 
442134a1f4eSCasper H.S. Dik 	if (kva == NULL)
443134a1f4eSCasper H.S. Dik 		return (NULL);
444134a1f4eSCasper H.S. Dik 
445134a1f4eSCasper H.S. Dik 	kva->data = (kv_t *)(void *)&kva[1];
446134a1f4eSCasper H.S. Dik 	kva->length = 0;
447134a1f4eSCasper H.S. Dik 
448134a1f4eSCasper H.S. Dik 	if ((defp = defopen_r(AUTH_POLICY)) == NULL)
449134a1f4eSCasper H.S. Dik 		goto return_null;
450134a1f4eSCasper H.S. Dik 
451134a1f4eSCasper H.S. Dik 	for (i = is_cons_user(user) ? 0 : 1; i < NDFLTPLY; i++) {
452134a1f4eSCasper H.S. Dik 		char *cp = defread_r(dfltply[i].defkw, defp);
453134a1f4eSCasper H.S. Dik 
454134a1f4eSCasper H.S. Dik 		if (cp == NULL)
455134a1f4eSCasper H.S. Dik 			continue;
456134a1f4eSCasper H.S. Dik 		if ((cp = strdup(cp)) == NULL)
457134a1f4eSCasper H.S. Dik 			goto return_null;
458134a1f4eSCasper H.S. Dik 
459134a1f4eSCasper H.S. Dik 		kva->data[kva->length].key = dfltply[i].attr;
460134a1f4eSCasper H.S. Dik 		kva->data[kva->length++].value = cp;
461499fd601Sgww 	}
462499fd601Sgww 
463134a1f4eSCasper H.S. Dik 	(void) defclose_r(defp);
464134a1f4eSCasper H.S. Dik 	return (kva);
465499fd601Sgww 
466134a1f4eSCasper H.S. Dik return_null:
467134a1f4eSCasper H.S. Dik 	if (defp != NULL)
468134a1f4eSCasper H.S. Dik 		(void) defclose_r(defp);
469499fd601Sgww 
470134a1f4eSCasper H.S. Dik 	free_default_attrs(kva);
471134a1f4eSCasper H.S. Dik 	return (NULL);
472499fd601Sgww }
473