1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 
25 /*
26  * ldapaddrbac.c
27  *
28  * Routines to add RBAC /etc files into LDAP.
29  * Can also be used to dump entries from a ldap container in /etc format.
30  */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <libintl.h>
35 #include <strings.h>
36 #include <sys/param.h>
37 #include <ctype.h>
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
42 #include <locale.h>
43 #include <syslog.h>
44 #include "ldapaddent.h"
45 
46 #undef opaque
47 #undef	GROUP
48 #include <bsm/libbsm.h>
49 
50 extern	char	*_strtok_escape(char *, char *, char **); /* from libnsl */
51 
52 #include <user_attr.h>
53 #include <prof_attr.h>
54 #include <exec_attr.h>
55 #include <auth_attr.h>
56 
57 /*
58  * The parsing routines for RBAC databases
59  */
60 
61 /*
62  * genent_attr:
63  *   Generic function for generating entries for all of the *_attr databases.
64  */
65 int
genent_attr(char * line,int ncol,entry_col ** ecolret)66 genent_attr(
67 	char	*line,		/* entry to parse */
68 	int	ncol,		/* number of columns in the database */
69 	entry_col	**ecolret)	/* return entry array */
70 {
71 	int		i;
72 	char		(*buf)[BUFSIZ + 1];
73 	char		*s;
74 	char		*sep = KV_TOKEN_DELIMIT;
75 	char		*lasts;
76 	entry_col	*ecol;
77 
78 	/*
79 	 * check input length
80 	 */
81 	if (strlen(line) >= sizeof (*buf)) {
82 		(void) strcpy(parse_err_msg, "line too long");
83 		return (GENENT_PARSEERR);
84 	}
85 
86 	/*
87 	 * setup and clear column data
88 	 */
89 	if ((ecol = (entry_col *)malloc(ncol * sizeof (entry_col) +
90 	    sizeof (*buf))) == NULL)
91 		return (GENENT_ERR);
92 	(void) memset((char *)ecol, 0, ncol * sizeof (ecol));
93 
94 	/* don't scribble over input */
95 	buf = (char (*)[sizeof (*buf)]) (ecol + ncol);
96 	(void) strncpy((char *)buf, line, sizeof (*buf));
97 
98 	/* Split up columns */
99 	for (i = 0; i < ncol; i++, buf = NULL) {
100 		s = _strtok_escape((char *)buf, sep, &lasts);
101 		if (s == NULL) {
102 			ecol[i].ec_value.ec_value_val = "";
103 			ecol[i].ec_value.ec_value_len = 0;
104 		} else {
105 			ecol[i].ec_value.ec_value_val = s;
106 			ecol[i].ec_value.ec_value_len = strlen(s)+1;
107 		}
108 	}
109 
110 	*ecolret = ecol;
111 	return (GENENT_OK);
112 }
113 
114 int
genent_user_attr(char * line,int (* cback)())115 genent_user_attr(char *line, int (*cback)())
116 {
117 	entry_col	*ecol;
118 	userstr_t	data;
119 	int		res, retval;
120 
121 	/*
122 	 * parse entry into columns
123 	 */
124 	res = genent_attr(line, USERATTR_DB_NCOL, &ecol);
125 	if (res != GENENT_OK)
126 		return (res);
127 
128 	data.name = ecol[0].ec_value.ec_value_val;
129 	data.qualifier = ecol[1].ec_value.ec_value_val;
130 	data.res1 = NULL;
131 	data.res2 = NULL;
132 	data.attr = ecol[4].ec_value.ec_value_val;
133 
134 	if (flags & F_VERBOSE)
135 		(void) fprintf(stdout,
136 		    gettext("Adding entry : %s\n"), data.name);
137 
138 	retval = (*cback)(&data, 1);
139 	if (retval != NS_LDAP_SUCCESS) {
140 		if (retval == LDAP_NO_SUCH_OBJECT)
141 			(void) fprintf(stdout,
142 			gettext("Cannot add user_attr entry (%s), "
143 			"add passwd entry first\n"), data.name);
144 		if (continue_onerror == 0) res = GENENT_CBERR;
145 	}
146 
147 	free(ecol);
148 
149 	return (res);
150 }
151 
152 void
dump_user_attr(ns_ldap_result_t * res)153 dump_user_attr(ns_ldap_result_t *res)
154 {
155 	char	**value = NULL;
156 
157 	value = __ns_ldap_getAttr(res->entry, "uid");
158 	if (value && value[0])
159 		(void) fprintf(stdout, "%s", value[0]);
160 	else
161 		return;
162 
163 	(void) fprintf(stdout, "::::");
164 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
165 	if (value && value[0])
166 		(void) fprintf(stdout, "%s", value[0]);
167 	(void) fprintf(stdout, "\n");
168 }
169 
170 int
genent_prof_attr(char * line,int (* cback)())171 genent_prof_attr(char *line, int (*cback)())
172 {
173 	entry_col	*ecol;
174 	profstr_t	data;
175 	int		res, retval;
176 
177 	/*
178 	 * parse entry into columns
179 	 */
180 	res = genent_attr(line, PROFATTR_DB_NCOL, &ecol);
181 	if (res != GENENT_OK)
182 		return (res);
183 
184 	data.name = ecol[0].ec_value.ec_value_val;
185 	data.res1 = NULL;
186 	data.res2 = NULL;
187 	data.desc = ecol[3].ec_value.ec_value_val;
188 	data.attr = ecol[4].ec_value.ec_value_val;
189 
190 	if (flags & F_VERBOSE)
191 		(void) fprintf(stdout,
192 		    gettext("Adding entry : %s\n"), data.name);
193 
194 	retval = (*cback)(&data, 0);
195 	if (retval == LDAP_ALREADY_EXISTS) {
196 		if (continue_onerror)
197 			(void) fprintf(stderr,
198 			    gettext("Entry: %s - already Exists,"
199 			    " skipping it.\n"),
200 			    data.name);
201 		else {
202 			res = GENENT_CBERR;
203 			(void) fprintf(stderr,
204 			    gettext("Entry: %s - already Exists\n"),
205 			    data.name);
206 		}
207 	} else if (retval)
208 		res = GENENT_CBERR;
209 
210 	free(ecol);
211 
212 	return (res);
213 }
214 
215 void
dump_prof_attr(ns_ldap_result_t * res)216 dump_prof_attr(ns_ldap_result_t *res)
217 {
218 	char	**value = NULL;
219 
220 	value = __ns_ldap_getAttr(res->entry, "cn");
221 	if (value && value[0])
222 		(void) fprintf(stdout, "%s", value[0]);
223 	else
224 		return;
225 
226 	(void) fprintf(stdout, ":::");
227 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrLongDesc");
228 	if (value && value[0])
229 		(void) fprintf(stdout, "%s", value[0]);
230 	(void) fprintf(stdout, ":");
231 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
232 	if (value && value[0])
233 		(void) fprintf(stdout, "%s", value[0]);
234 	(void) fprintf(stdout, "\n");
235 }
236 
237 int
genent_exec_attr(char * line,int (* cback)())238 genent_exec_attr(char *line, int (*cback)())
239 {
240 	entry_col	*ecol;
241 	execstr_t	data;
242 	int		res, retval;
243 
244 	/*
245 	 * parse entry into columns
246 	 */
247 	res = genent_attr(line, EXECATTR_DB_NCOL, &ecol);
248 	if (res != GENENT_OK)
249 		return (res);
250 
251 	data.name = ecol[0].ec_value.ec_value_val;
252 	data.policy = ecol[1].ec_value.ec_value_val;
253 	data.type = ecol[2].ec_value.ec_value_val;
254 	data.res1 = NULL;
255 	data.res2 = NULL;
256 	data.id = ecol[5].ec_value.ec_value_val;
257 	data.attr = ecol[6].ec_value.ec_value_val;
258 	data.next = NULL;
259 
260 	if (flags & F_VERBOSE)
261 		(void) fprintf(stdout,
262 		    gettext("Adding entry : %s+%s+%s+%s\n"),
263 		    data.name, data.policy, data.type, data.id);
264 
265 	retval = (*cback)(&data, 0);
266 	if (retval == LDAP_ALREADY_EXISTS) {
267 		if (continue_onerror)
268 			(void) fprintf(stderr,
269 			    gettext("Entry: %s+%s+%s+%s - already Exists,"
270 			    " skipping it.\n"),
271 			    data.name, data.policy, data.type, data.id);
272 		else {
273 			res = GENENT_CBERR;
274 			(void) fprintf(stderr,
275 			    gettext("Entry: %s+%s+%s+%s - already Exists\n"),
276 			    data.name, data.policy, data.type, data.id);
277 		}
278 	} else if (retval)
279 		res = GENENT_CBERR;
280 
281 	free(ecol);
282 
283 	return (res);
284 }
285 
286 void
dump_exec_attr(ns_ldap_result_t * res)287 dump_exec_attr(ns_ldap_result_t *res)
288 {
289 	char	**profile;
290 	char	**policy;
291 	char	**type;
292 	char	**id;
293 	char	**value;
294 
295 	profile = __ns_ldap_getAttr(res->entry, "cn");
296 	policy = __ns_ldap_getAttr(res->entry, "SolarisKernelSecurityPolicy");
297 	type = __ns_ldap_getAttr(res->entry, "SolarisProfileType");
298 	id = __ns_ldap_getAttr(res->entry, "SolarisProfileId");
299 
300 	if (profile == NULL || profile[0] == NULL ||
301 	    policy == NULL || policy[0] == NULL ||
302 	    type == NULL || type[0] == NULL ||
303 	    id == NULL || id[0] == NULL)
304 		return;
305 
306 	(void) fprintf(stdout, "%s", profile[0]);
307 	(void) fprintf(stdout, ":");
308 	(void) fprintf(stdout, "%s", policy[0]);
309 	(void) fprintf(stdout, ":");
310 	(void) fprintf(stdout, "%s", type[0]);
311 	(void) fprintf(stdout, ":::");
312 	(void) fprintf(stdout, "%s", id[0]);
313 	(void) fprintf(stdout, ":");
314 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
315 	if (value && value[0])
316 		(void) fprintf(stdout, "%s", value[0]);
317 	(void) fprintf(stdout, "\n");
318 }
319 
320 int
genent_auth_attr(char * line,int (* cback)())321 genent_auth_attr(char *line, int (*cback)())
322 {
323 	entry_col	*ecol;
324 	authstr_t	data;
325 	int		res, retval;
326 
327 	/*
328 	 * parse entry into columns
329 	 */
330 	res = genent_attr(line, AUTHATTR_DB_NCOL, &ecol);
331 	if (res != GENENT_OK)
332 		return (res);
333 
334 	data.name = ecol[0].ec_value.ec_value_val;
335 	data.res1 = NULL;
336 	data.res2 = NULL;
337 	data.short_desc = ecol[3].ec_value.ec_value_val;
338 	data.long_desc = ecol[4].ec_value.ec_value_val;
339 	data.attr = ecol[5].ec_value.ec_value_val;
340 
341 	if (flags & F_VERBOSE)
342 		(void) fprintf(stdout,
343 		    gettext("Adding entry : %s\n"), data.name);
344 
345 	retval = (*cback)(&data, 0);
346 	if (retval == LDAP_ALREADY_EXISTS) {
347 		if (continue_onerror)
348 			(void) fprintf(stderr,
349 			    gettext("Entry: %s - already Exists,"
350 			    " skipping it.\n"), data.name);
351 		else {
352 			res = GENENT_CBERR;
353 			(void) fprintf(stderr,
354 			    gettext("Entry: %s - already Exists\n"),
355 			    data.name);
356 		}
357 	} else if (retval)
358 		res = GENENT_CBERR;
359 
360 	free(ecol);
361 
362 	return (res);
363 }
364 
365 void
dump_auth_attr(ns_ldap_result_t * res)366 dump_auth_attr(ns_ldap_result_t *res)
367 {
368 	char	**value = NULL;
369 
370 	value = __ns_ldap_getAttr(res->entry, "cn");
371 	if (value && value[0])
372 		(void) fprintf(stdout, "%s", value[0]);
373 	else
374 		return;
375 
376 	(void) fprintf(stdout, ":::");
377 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrShortDesc");
378 	if (value && value[0])
379 		(void) fprintf(stdout, "%s", value[0]);
380 	(void) fprintf(stdout, ":");
381 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrLongDesc");
382 	if (value && value[0])
383 		(void) fprintf(stdout, "%s", value[0]);
384 	(void) fprintf(stdout, ":");
385 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
386 	if (value && value[0])
387 		(void) fprintf(stdout, "%s", value[0]);
388 	(void) fprintf(stdout, "\n");
389 }
390