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
_enum_common_p(const char * cprofiles,int (* cb)(const char *,kva_t *,void *,void *),void * ctxt,void * pres,boolean_t wantattr,int * pcnt,char * profs[MAXPROFS])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
_enum_common(const char * username,int (* cb)(const char *,kva_t *,void *,void *),void * ctxt,void * pres,boolean_t wantattr)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
_enum_profs(const char * username,int (* cb)(const char *,kva_t *,void *,void *),void * ctxt,void * pres)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
_enum_attrs(const char * username,int (* cb)(const char *,kva_t *,void *,void *),void * ctxt,void * pres)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
_enum_auths_a(const char * cauths,int (* cb)(const char *,void *,void *),void * ctxt,void * pres)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
comm2auth(const char * name,kva_t * attr,void * ctxt,void * pres)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
_enum_auths(const char * username,int (* cb)(const char *,void *,void *),void * ctxt,void * pres)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
_auth_match_noun(const char * pattern,const char * auth,size_t auth_len,const char * auth_noun)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
_auth_match(const char * pattern,const char * auth)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
_is_authorized(const char * auth,void * authname,void * res)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
chkauthattr(const char * authname,const char * username)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
is_cons_user(const char * user)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
free_default_attrs(kva_t * kva)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 *
get_default_attrs(const char * user)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