xref: /titanic_51/usr/src/lib/libsecdb/common/chkauthattr.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include <stdio.h>
30*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
31*7c478bd9Sstevel@tonic-gate #include <string.h>
32*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
33*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
34*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/mman.h>
36*7c478bd9Sstevel@tonic-gate #include <limits.h>
37*7c478bd9Sstevel@tonic-gate #include <deflt.h>
38*7c478bd9Sstevel@tonic-gate #include <auth_attr.h>
39*7c478bd9Sstevel@tonic-gate #include <prof_attr.h>
40*7c478bd9Sstevel@tonic-gate #include <user_attr.h>
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate static int _is_authorized(const char *, char *);
44*7c478bd9Sstevel@tonic-gate static int _chk_policy_auth(const char *, char **, int *);
45*7c478bd9Sstevel@tonic-gate static int _chkprof_for_auth(const char *, const char *, char **, int *);
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate int
49*7c478bd9Sstevel@tonic-gate chkauthattr(const char *authname, const char *username)
50*7c478bd9Sstevel@tonic-gate {
51*7c478bd9Sstevel@tonic-gate 	int		auth_granted = 0;
52*7c478bd9Sstevel@tonic-gate 	char		*auths;
53*7c478bd9Sstevel@tonic-gate 	char		*profiles;
54*7c478bd9Sstevel@tonic-gate 	userattr_t	*user;
55*7c478bd9Sstevel@tonic-gate 	char		*chkedprof[MAXPROFS];
56*7c478bd9Sstevel@tonic-gate 	int		chkedprof_cnt = 0;
57*7c478bd9Sstevel@tonic-gate 	int		i;
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate 	if (authname == NULL || username == NULL)
60*7c478bd9Sstevel@tonic-gate 		return (0);
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate 	auth_granted = _chk_policy_auth(authname, chkedprof, &chkedprof_cnt);
63*7c478bd9Sstevel@tonic-gate 	if (auth_granted) {
64*7c478bd9Sstevel@tonic-gate 		return (1);
65*7c478bd9Sstevel@tonic-gate 	}
66*7c478bd9Sstevel@tonic-gate 	if ((user = getusernam(username)) == NULL)
67*7c478bd9Sstevel@tonic-gate 		return (0);
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate 	if ((auths = kva_match(user->attr, USERATTR_AUTHS_KW)) != NULL) {
70*7c478bd9Sstevel@tonic-gate 		if (_is_authorized(authname, auths)) {
71*7c478bd9Sstevel@tonic-gate 			free_userattr(user);
72*7c478bd9Sstevel@tonic-gate 			return (1);
73*7c478bd9Sstevel@tonic-gate 		}
74*7c478bd9Sstevel@tonic-gate 	}
75*7c478bd9Sstevel@tonic-gate 
76*7c478bd9Sstevel@tonic-gate 	if ((profiles = kva_match(user->attr, USERATTR_PROFILES_KW)) == NULL) {
77*7c478bd9Sstevel@tonic-gate 		free_userattr(user);
78*7c478bd9Sstevel@tonic-gate 		return (0);
79*7c478bd9Sstevel@tonic-gate 	}
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate 	auth_granted = _chkprof_for_auth(profiles, authname,
82*7c478bd9Sstevel@tonic-gate 	    chkedprof, &chkedprof_cnt);
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate 	/* free memory allocated for checked array */
85*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < chkedprof_cnt; i++) {
86*7c478bd9Sstevel@tonic-gate 		free(chkedprof[i]);
87*7c478bd9Sstevel@tonic-gate 	}
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 	free_userattr(user);
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate 	return (auth_granted);
92*7c478bd9Sstevel@tonic-gate }
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate static int
95*7c478bd9Sstevel@tonic-gate _chkprof_for_auth(const char *profs, const char *authname,
96*7c478bd9Sstevel@tonic-gate     char **chkedprof, int *chkedprof_cnt)
97*7c478bd9Sstevel@tonic-gate {
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate 	char *prof, *lasts, *auths, *profiles;
100*7c478bd9Sstevel@tonic-gate 	profattr_t	*pa;
101*7c478bd9Sstevel@tonic-gate 	int		i;
102*7c478bd9Sstevel@tonic-gate 	int		checked = 0;
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate 	for (prof = strtok_r((char *)profs, ",", &lasts); prof != NULL;
105*7c478bd9Sstevel@tonic-gate 	    prof = strtok_r(NULL, ",", &lasts)) {
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate 		checked = 0;
108*7c478bd9Sstevel@tonic-gate 		/* check if this profile has been checked */
109*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < *chkedprof_cnt; i++) {
110*7c478bd9Sstevel@tonic-gate 			if (strcmp(chkedprof[i], prof) == 0) {
111*7c478bd9Sstevel@tonic-gate 				checked = 1;
112*7c478bd9Sstevel@tonic-gate 				break;
113*7c478bd9Sstevel@tonic-gate 			}
114*7c478bd9Sstevel@tonic-gate 		}
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate 		if (!checked) {
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate 			chkedprof[*chkedprof_cnt] = strdup(prof);
119*7c478bd9Sstevel@tonic-gate 			*chkedprof_cnt = *chkedprof_cnt + 1;
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate 			if ((pa = getprofnam(prof)) == NULL)
122*7c478bd9Sstevel@tonic-gate 				continue;
123*7c478bd9Sstevel@tonic-gate 
124*7c478bd9Sstevel@tonic-gate 			if ((auths = kva_match(pa->attr,
125*7c478bd9Sstevel@tonic-gate 			    PROFATTR_AUTHS_KW)) != NULL) {
126*7c478bd9Sstevel@tonic-gate 				if (_is_authorized(authname, auths)) {
127*7c478bd9Sstevel@tonic-gate 					free_profattr(pa);
128*7c478bd9Sstevel@tonic-gate 					return (1);
129*7c478bd9Sstevel@tonic-gate 				}
130*7c478bd9Sstevel@tonic-gate 			}
131*7c478bd9Sstevel@tonic-gate 			if ((profiles =
132*7c478bd9Sstevel@tonic-gate 			    kva_match(pa->attr, PROFATTR_PROFS_KW)) != NULL) {
133*7c478bd9Sstevel@tonic-gate 				/* Check for authorization in subprofiles */
134*7c478bd9Sstevel@tonic-gate 				if (_chkprof_for_auth(profiles, authname,
135*7c478bd9Sstevel@tonic-gate 				    chkedprof, chkedprof_cnt)) {
136*7c478bd9Sstevel@tonic-gate 					free_profattr(pa);
137*7c478bd9Sstevel@tonic-gate 					return (1);
138*7c478bd9Sstevel@tonic-gate 				}
139*7c478bd9Sstevel@tonic-gate 			}
140*7c478bd9Sstevel@tonic-gate 			free_profattr(pa);
141*7c478bd9Sstevel@tonic-gate 		}
142*7c478bd9Sstevel@tonic-gate 	}
143*7c478bd9Sstevel@tonic-gate 	/* authorization not found in any profile */
144*7c478bd9Sstevel@tonic-gate 	return (0);
145*7c478bd9Sstevel@tonic-gate }
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate int
148*7c478bd9Sstevel@tonic-gate _auth_match(const char *pattern, const char *auth)
149*7c478bd9Sstevel@tonic-gate {
150*7c478bd9Sstevel@tonic-gate 	size_t len;
151*7c478bd9Sstevel@tonic-gate 	char wildcard = KV_WILDCHAR;
152*7c478bd9Sstevel@tonic-gate 	char *grant;
153*7c478bd9Sstevel@tonic-gate 
154*7c478bd9Sstevel@tonic-gate 	len = strlen(pattern);
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate 	/*
157*7c478bd9Sstevel@tonic-gate 	 * If the wildcard is not in the last position in the string, don't
158*7c478bd9Sstevel@tonic-gate 	 * match against it.
159*7c478bd9Sstevel@tonic-gate 	 */
160*7c478bd9Sstevel@tonic-gate 	if (pattern[len-1] != wildcard)
161*7c478bd9Sstevel@tonic-gate 		return (0);
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate 	/*
164*7c478bd9Sstevel@tonic-gate 	 * If the strings are identical up to the wildcard and auth does not
165*7c478bd9Sstevel@tonic-gate 	 * end in "grant", then we have a match.
166*7c478bd9Sstevel@tonic-gate 	 */
167*7c478bd9Sstevel@tonic-gate 	if (strncmp(pattern, auth, len-1) == 0) {
168*7c478bd9Sstevel@tonic-gate 		grant = strrchr(auth, '.');
169*7c478bd9Sstevel@tonic-gate 		if (grant != NULL) {
170*7c478bd9Sstevel@tonic-gate 			if (strncmp(grant + 1, "grant", 5) != NULL)
171*7c478bd9Sstevel@tonic-gate 				return (1);
172*7c478bd9Sstevel@tonic-gate 		}
173*7c478bd9Sstevel@tonic-gate 	}
174*7c478bd9Sstevel@tonic-gate 
175*7c478bd9Sstevel@tonic-gate 	return (0);
176*7c478bd9Sstevel@tonic-gate }
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate static int
179*7c478bd9Sstevel@tonic-gate _is_authorized(const char *authname, char *auths)
180*7c478bd9Sstevel@tonic-gate {
181*7c478bd9Sstevel@tonic-gate 	int	found = 0;	/* have we got a match, yet */
182*7c478bd9Sstevel@tonic-gate 	char	wildcard = '*';
183*7c478bd9Sstevel@tonic-gate 	char	*auth;		/* current authorization being compared */
184*7c478bd9Sstevel@tonic-gate 	char	*buf;
185*7c478bd9Sstevel@tonic-gate 	char	*lasts;
186*7c478bd9Sstevel@tonic-gate 
187*7c478bd9Sstevel@tonic-gate 	buf = strdup(auths);
188*7c478bd9Sstevel@tonic-gate 	for (auth = strtok_r(auths, ",", &lasts); auth != NULL && !found;
189*7c478bd9Sstevel@tonic-gate 	    auth = strtok_r(NULL, ",", &lasts)) {
190*7c478bd9Sstevel@tonic-gate 		if (strcmp((char *)authname, auth) == 0) {
191*7c478bd9Sstevel@tonic-gate 			/* Exact match.  We're done. */
192*7c478bd9Sstevel@tonic-gate 			found = 1;
193*7c478bd9Sstevel@tonic-gate 		} else if (strchr(auth, wildcard) != NULL) {
194*7c478bd9Sstevel@tonic-gate 			if (_auth_match(auth, authname)) {
195*7c478bd9Sstevel@tonic-gate 				found = 1;
196*7c478bd9Sstevel@tonic-gate 				break;
197*7c478bd9Sstevel@tonic-gate 			}
198*7c478bd9Sstevel@tonic-gate 		}
199*7c478bd9Sstevel@tonic-gate 	}
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate 	free(buf);
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate 	return (found);
204*7c478bd9Sstevel@tonic-gate }
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate int
208*7c478bd9Sstevel@tonic-gate _get_auth_policy(char **def_auth, char **def_prof)
209*7c478bd9Sstevel@tonic-gate {
210*7c478bd9Sstevel@tonic-gate 	char *cp;
211*7c478bd9Sstevel@tonic-gate 
212*7c478bd9Sstevel@tonic-gate 	if (defopen(AUTH_POLICY) != 0)
213*7c478bd9Sstevel@tonic-gate 		return (-1);
214*7c478bd9Sstevel@tonic-gate 
215*7c478bd9Sstevel@tonic-gate 	cp = defread(DEF_AUTH);
216*7c478bd9Sstevel@tonic-gate 	if (cp != NULL) {
217*7c478bd9Sstevel@tonic-gate 		*def_auth = strdup(cp);
218*7c478bd9Sstevel@tonic-gate 		if (*def_auth == NULL)
219*7c478bd9Sstevel@tonic-gate 			return (-1);
220*7c478bd9Sstevel@tonic-gate 	} else {
221*7c478bd9Sstevel@tonic-gate 		*def_auth = NULL;
222*7c478bd9Sstevel@tonic-gate 	}
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate 	cp = defread(DEF_PROF);
225*7c478bd9Sstevel@tonic-gate 	if (cp != NULL) {
226*7c478bd9Sstevel@tonic-gate 		*def_prof = strdup(cp);
227*7c478bd9Sstevel@tonic-gate 		if (*def_prof == NULL) {
228*7c478bd9Sstevel@tonic-gate 			free(*def_auth);
229*7c478bd9Sstevel@tonic-gate 			return (-1);
230*7c478bd9Sstevel@tonic-gate 		}
231*7c478bd9Sstevel@tonic-gate 	} else {
232*7c478bd9Sstevel@tonic-gate 		*def_prof = NULL;
233*7c478bd9Sstevel@tonic-gate 	}
234*7c478bd9Sstevel@tonic-gate 
235*7c478bd9Sstevel@tonic-gate 	(void) defopen(NULL);
236*7c478bd9Sstevel@tonic-gate 	return (0);
237*7c478bd9Sstevel@tonic-gate }
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate /*
240*7c478bd9Sstevel@tonic-gate  * read /etc/security/policy.conf for AUTHS_GRANTED.
241*7c478bd9Sstevel@tonic-gate  * return 1 if found matching authname.
242*7c478bd9Sstevel@tonic-gate  * Otherwise, read PROFS_GRANTED to see if authname exists in any
243*7c478bd9Sstevel@tonic-gate  * default profiles.
244*7c478bd9Sstevel@tonic-gate  */
245*7c478bd9Sstevel@tonic-gate static int
246*7c478bd9Sstevel@tonic-gate _chk_policy_auth(const char *authname, char **chkedprof, int *chkedprof_cnt)
247*7c478bd9Sstevel@tonic-gate {
248*7c478bd9Sstevel@tonic-gate 	char	*auths, *profs;
249*7c478bd9Sstevel@tonic-gate 	int	ret = 1;
250*7c478bd9Sstevel@tonic-gate 
251*7c478bd9Sstevel@tonic-gate 	if (_get_auth_policy(&auths, &profs) != 0)
252*7c478bd9Sstevel@tonic-gate 		return (0);
253*7c478bd9Sstevel@tonic-gate 
254*7c478bd9Sstevel@tonic-gate 	if (auths != NULL) {
255*7c478bd9Sstevel@tonic-gate 		if (_is_authorized(authname, auths))
256*7c478bd9Sstevel@tonic-gate 			goto exit;
257*7c478bd9Sstevel@tonic-gate 	}
258*7c478bd9Sstevel@tonic-gate 
259*7c478bd9Sstevel@tonic-gate 	if (profs != NULL) {
260*7c478bd9Sstevel@tonic-gate 		if (_chkprof_for_auth(profs, authname, chkedprof,
261*7c478bd9Sstevel@tonic-gate 		    chkedprof_cnt))
262*7c478bd9Sstevel@tonic-gate 			goto exit;
263*7c478bd9Sstevel@tonic-gate 	}
264*7c478bd9Sstevel@tonic-gate 	ret = 0;
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate exit:
267*7c478bd9Sstevel@tonic-gate 	free(auths);
268*7c478bd9Sstevel@tonic-gate 	free(profs);
269*7c478bd9Sstevel@tonic-gate 	return (ret);
270*7c478bd9Sstevel@tonic-gate }
271