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