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)
143 		res = GENENT_CBERR;
144 
145 	free(ecol);
146 
147 	return (res);
148 }
149 
150 void
151 dump_user_attr(ns_ldap_result_t *res)
152 {
153 	char	**value = NULL;
154 
155 	value = __ns_ldap_getAttr(res->entry, "uid");
156 	if (value && value[0])
157 		(void) fprintf(stdout, "%s", value[0]);
158 	else
159 		return;
160 
161 	(void) fprintf(stdout, "::::");
162 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
163 	if (value && value[0])
164 		(void) fprintf(stdout, "%s", value[0]);
165 	(void) fprintf(stdout, "\n");
166 }
167 
168 int
169 genent_prof_attr(char *line, int (*cback)())
170 {
171 	entry_col	*ecol;
172 	profstr_t	data;
173 	int		res, retval;
174 
175 	/*
176 	 * parse entry into columns
177 	 */
178 	res = genent_attr(line, PROFATTR_DB_NCOL, &ecol);
179 	if (res != GENENT_OK)
180 		return (res);
181 
182 	data.name = ecol[0].ec_value.ec_value_val;
183 	data.res1 = NULL;
184 	data.res2 = NULL;
185 	data.desc = ecol[3].ec_value.ec_value_val;
186 	data.attr = ecol[4].ec_value.ec_value_val;
187 
188 	if (flags & F_VERBOSE)
189 		(void) fprintf(stdout,
190 		    gettext("Adding entry : %s\n"), data.name);
191 
192 	retval = (*cback)(&data, 0);
193 	if (retval == LDAP_ALREADY_EXISTS) {
194 		if (continue_onerror)
195 			(void) fprintf(stderr,
196 			    gettext("Entry: %s - already Exists,"
197 			    " skipping it.\n"),
198 			    data.name);
199 		else {
200 			res = GENENT_CBERR;
201 			(void) fprintf(stderr,
202 			    gettext("Entry: %s - already Exists\n"),
203 			    data.name);
204 		}
205 	} else if (retval)
206 		res = GENENT_CBERR;
207 
208 	free(ecol);
209 
210 	return (res);
211 }
212 
213 void
214 dump_prof_attr(ns_ldap_result_t *res)
215 {
216 	char	**value = NULL;
217 
218 	value = __ns_ldap_getAttr(res->entry, "cn");
219 	if (value && value[0])
220 		(void) fprintf(stdout, "%s", value[0]);
221 	else
222 		return;
223 
224 	(void) fprintf(stdout, ":::");
225 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrLongDesc");
226 	if (value && value[0])
227 		(void) fprintf(stdout, "%s", value[0]);
228 	(void) fprintf(stdout, ":");
229 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
230 	if (value && value[0])
231 		(void) fprintf(stdout, "%s", value[0]);
232 	(void) fprintf(stdout, "\n");
233 }
234 
235 int
236 genent_exec_attr(char *line, int (*cback)())
237 {
238 	entry_col	*ecol;
239 	execstr_t	data;
240 	int		res, retval;
241 
242 	/*
243 	 * parse entry into columns
244 	 */
245 	res = genent_attr(line, EXECATTR_DB_NCOL, &ecol);
246 	if (res != GENENT_OK)
247 		return (res);
248 
249 	data.name = ecol[0].ec_value.ec_value_val;
250 	data.policy = ecol[1].ec_value.ec_value_val;
251 	data.type = ecol[2].ec_value.ec_value_val;
252 	data.res1 = NULL;
253 	data.res2 = NULL;
254 	data.id = ecol[5].ec_value.ec_value_val;
255 	data.attr = ecol[6].ec_value.ec_value_val;
256 	data.next = NULL;
257 
258 	if (flags & F_VERBOSE)
259 		(void) fprintf(stdout,
260 		    gettext("Adding entry : %s+%s+%s+%s\n"),
261 		    data.name, data.policy, data.type, data.id);
262 
263 	retval = (*cback)(&data, 0);
264 	if (retval == LDAP_ALREADY_EXISTS) {
265 		if (continue_onerror)
266 			(void) fprintf(stderr,
267 			    gettext("Entry: %s+%s+%s+%s - already Exists,"
268 			    " skipping it.\n"),
269 			    data.name, data.policy, data.type, data.id);
270 		else {
271 			res = GENENT_CBERR;
272 			(void) fprintf(stderr,
273 			    gettext("Entry: %s+%s+%s+%s - already Exists\n"),
274 			    data.name, data.policy, data.type, data.id);
275 		}
276 	} else if (retval)
277 		res = GENENT_CBERR;
278 
279 	free(ecol);
280 
281 	return (res);
282 }
283 
284 void
285 dump_exec_attr(ns_ldap_result_t *res)
286 {
287 	char	**profile;
288 	char	**policy;
289 	char	**type;
290 	char	**id;
291 	char	**value;
292 
293 	profile = __ns_ldap_getAttr(res->entry, "cn");
294 	policy = __ns_ldap_getAttr(res->entry, "SolarisKernelSecurityPolicy");
295 	type = __ns_ldap_getAttr(res->entry, "SolarisProfileType");
296 	id = __ns_ldap_getAttr(res->entry, "SolarisProfileId");
297 
298 	if (profile == NULL || profile[0] == NULL ||
299 	    policy == NULL || policy[0] == NULL ||
300 	    type == NULL || type[0] == NULL ||
301 	    id == NULL || id[0] == NULL)
302 		return;
303 
304 	(void) fprintf(stdout, "%s", profile[0]);
305 	(void) fprintf(stdout, ":");
306 	(void) fprintf(stdout, "%s", policy[0]);
307 	(void) fprintf(stdout, ":");
308 	(void) fprintf(stdout, "%s", type[0]);
309 	(void) fprintf(stdout, ":::");
310 	(void) fprintf(stdout, "%s", id[0]);
311 	(void) fprintf(stdout, ":");
312 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
313 	if (value && value[0])
314 		(void) fprintf(stdout, "%s", value[0]);
315 	(void) fprintf(stdout, "\n");
316 }
317 
318 int
319 genent_auth_attr(char *line, int (*cback)())
320 {
321 	entry_col	*ecol;
322 	authstr_t	data;
323 	int		res, retval;
324 
325 	/*
326 	 * parse entry into columns
327 	 */
328 	res = genent_attr(line, AUTHATTR_DB_NCOL, &ecol);
329 	if (res != GENENT_OK)
330 		return (res);
331 
332 	data.name = ecol[0].ec_value.ec_value_val;
333 	data.res1 = NULL;
334 	data.res2 = NULL;
335 	data.short_desc = ecol[3].ec_value.ec_value_val;
336 	data.long_desc = ecol[4].ec_value.ec_value_val;
337 	data.attr = ecol[5].ec_value.ec_value_val;
338 
339 	if (flags & F_VERBOSE)
340 		(void) fprintf(stdout,
341 		    gettext("Adding entry : %s\n"), data.name);
342 
343 	retval = (*cback)(&data, 0);
344 	if (retval == LDAP_ALREADY_EXISTS) {
345 		if (continue_onerror)
346 			(void) fprintf(stderr,
347 			    gettext("Entry: %s - already Exists,"
348 			    " skipping it.\n"), data.name);
349 		else {
350 			res = GENENT_CBERR;
351 			(void) fprintf(stderr,
352 			    gettext("Entry: %s - already Exists\n"),
353 			    data.name);
354 		}
355 	} else if (retval)
356 		res = GENENT_CBERR;
357 
358 	free(ecol);
359 
360 	return (res);
361 }
362 
363 void
364 dump_auth_attr(ns_ldap_result_t *res)
365 {
366 	char	**value = NULL;
367 
368 	value = __ns_ldap_getAttr(res->entry, "cn");
369 	if (value && value[0])
370 		(void) fprintf(stdout, "%s", value[0]);
371 	else
372 		return;
373 
374 	(void) fprintf(stdout, ":::");
375 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrShortDesc");
376 	if (value && value[0])
377 		(void) fprintf(stdout, "%s", value[0]);
378 	(void) fprintf(stdout, ":");
379 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrLongDesc");
380 	if (value && value[0])
381 		(void) fprintf(stdout, "%s", value[0]);
382 	(void) fprintf(stdout, ":");
383 	value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
384 	if (value && value[0])
385 		(void) fprintf(stdout, "%s", value[0]);
386 	(void) fprintf(stdout, "\n");
387 }
388 
389 int
390 genent_audit_user(char *line, int (*cback)())
391 {
392 	entry_col	*ecol;
393 	au_user_str_t	data;
394 	int		res, retval;
395 
396 	/*
397 	 * parse entry into columns
398 	 */
399 	res = genent_attr(line, AUDITUSER_DB_NCOL, &ecol);
400 	if (res != GENENT_OK)
401 		return (res);
402 
403 	data.au_name = strdup(ecol[0].ec_value.ec_value_val);
404 	data.au_always = strdup(ecol[1].ec_value.ec_value_val);
405 	data.au_never = strdup(ecol[2].ec_value.ec_value_val);
406 
407 	if (flags & F_VERBOSE)
408 		(void) fprintf(stdout,
409 		    gettext("Adding entry : %s\n"), data.au_name);
410 
411 	retval = (*cback)(&data, 1);
412 	if (retval)
413 		res = GENENT_CBERR;
414 
415 	free(ecol);
416 
417 	return (res);
418 }
419 
420 void
421 dump_audit_user(ns_ldap_result_t *res)
422 {
423 	char	**value = NULL;
424 
425 	value = __ns_ldap_getAttr(res->entry, "uid");
426 	if (value && value[0])
427 		(void) fprintf(stdout, "%s", value[0]);
428 	else
429 		return;
430 
431 	(void) fprintf(stdout, ":");
432 	value = __ns_ldap_getAttr(res->entry, "SolarisAuditAlways");
433 	if (value && value[0])
434 		(void) fprintf(stdout, "%s", value[0]);
435 	(void) fprintf(stdout, ":");
436 	value = __ns_ldap_getAttr(res->entry, "SolarisAuditNever");
437 	if (value && value[0])
438 		(void) fprintf(stdout, "%s", value[0]);
439 	(void) fprintf(stdout, "\n");
440 }
441