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