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
50extern	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 */
65int
66genent_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
114int
115genent_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
152void
153dump_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
170int
171genent_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
215void
216dump_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
237int
238genent_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
286void
287dump_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
320int
321genent_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
365void
366dump_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