10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51676Sjpk * Common Development and Distribution License (the "License").
61676Sjpk * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*12788Sgary.winiger@oracle.com * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate /*
260Sstevel@tonic-gate * ldapaddrbac.c
270Sstevel@tonic-gate *
280Sstevel@tonic-gate * Routines to add RBAC /etc files into LDAP.
290Sstevel@tonic-gate * Can also be used to dump entries from a ldap container in /etc format.
300Sstevel@tonic-gate */
310Sstevel@tonic-gate
320Sstevel@tonic-gate #include <stdio.h>
330Sstevel@tonic-gate #include <stdlib.h>
340Sstevel@tonic-gate #include <libintl.h>
350Sstevel@tonic-gate #include <strings.h>
360Sstevel@tonic-gate #include <sys/param.h>
370Sstevel@tonic-gate #include <ctype.h>
380Sstevel@tonic-gate #include <sys/types.h>
390Sstevel@tonic-gate #include <sys/socket.h>
400Sstevel@tonic-gate #include <netinet/in.h>
410Sstevel@tonic-gate #include <arpa/inet.h>
420Sstevel@tonic-gate #include <locale.h>
430Sstevel@tonic-gate #include <syslog.h>
440Sstevel@tonic-gate #include "ldapaddent.h"
450Sstevel@tonic-gate
460Sstevel@tonic-gate #undef opaque
470Sstevel@tonic-gate #undef GROUP
480Sstevel@tonic-gate #include <bsm/libbsm.h>
490Sstevel@tonic-gate
500Sstevel@tonic-gate extern char *_strtok_escape(char *, char *, char **); /* from libnsl */
510Sstevel@tonic-gate
520Sstevel@tonic-gate #include <user_attr.h>
530Sstevel@tonic-gate #include <prof_attr.h>
540Sstevel@tonic-gate #include <exec_attr.h>
550Sstevel@tonic-gate #include <auth_attr.h>
560Sstevel@tonic-gate
570Sstevel@tonic-gate /*
58*12788Sgary.winiger@oracle.com * The parsing routines for RBAC databases
590Sstevel@tonic-gate */
600Sstevel@tonic-gate
610Sstevel@tonic-gate /*
620Sstevel@tonic-gate * genent_attr:
630Sstevel@tonic-gate * Generic function for generating entries for all of the *_attr databases.
640Sstevel@tonic-gate */
651676Sjpk int
genent_attr(char * line,int ncol,entry_col ** ecolret)660Sstevel@tonic-gate genent_attr(
670Sstevel@tonic-gate char *line, /* entry to parse */
680Sstevel@tonic-gate int ncol, /* number of columns in the database */
690Sstevel@tonic-gate entry_col **ecolret) /* return entry array */
700Sstevel@tonic-gate {
710Sstevel@tonic-gate int i;
720Sstevel@tonic-gate char (*buf)[BUFSIZ + 1];
730Sstevel@tonic-gate char *s;
740Sstevel@tonic-gate char *sep = KV_TOKEN_DELIMIT;
750Sstevel@tonic-gate char *lasts;
760Sstevel@tonic-gate entry_col *ecol;
770Sstevel@tonic-gate
780Sstevel@tonic-gate /*
790Sstevel@tonic-gate * check input length
800Sstevel@tonic-gate */
810Sstevel@tonic-gate if (strlen(line) >= sizeof (*buf)) {
820Sstevel@tonic-gate (void) strcpy(parse_err_msg, "line too long");
830Sstevel@tonic-gate return (GENENT_PARSEERR);
840Sstevel@tonic-gate }
850Sstevel@tonic-gate
860Sstevel@tonic-gate /*
870Sstevel@tonic-gate * setup and clear column data
880Sstevel@tonic-gate */
890Sstevel@tonic-gate if ((ecol = (entry_col *)malloc(ncol * sizeof (entry_col) +
900Sstevel@tonic-gate sizeof (*buf))) == NULL)
910Sstevel@tonic-gate return (GENENT_ERR);
920Sstevel@tonic-gate (void) memset((char *)ecol, 0, ncol * sizeof (ecol));
930Sstevel@tonic-gate
940Sstevel@tonic-gate /* don't scribble over input */
950Sstevel@tonic-gate buf = (char (*)[sizeof (*buf)]) (ecol + ncol);
960Sstevel@tonic-gate (void) strncpy((char *)buf, line, sizeof (*buf));
970Sstevel@tonic-gate
980Sstevel@tonic-gate /* Split up columns */
990Sstevel@tonic-gate for (i = 0; i < ncol; i++, buf = NULL) {
1000Sstevel@tonic-gate s = _strtok_escape((char *)buf, sep, &lasts);
1010Sstevel@tonic-gate if (s == NULL) {
1020Sstevel@tonic-gate ecol[i].ec_value.ec_value_val = "";
1030Sstevel@tonic-gate ecol[i].ec_value.ec_value_len = 0;
1040Sstevel@tonic-gate } else {
1050Sstevel@tonic-gate ecol[i].ec_value.ec_value_val = s;
1060Sstevel@tonic-gate ecol[i].ec_value.ec_value_len = strlen(s)+1;
1070Sstevel@tonic-gate }
1080Sstevel@tonic-gate }
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate *ecolret = ecol;
1110Sstevel@tonic-gate return (GENENT_OK);
1120Sstevel@tonic-gate }
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate int
genent_user_attr(char * line,int (* cback)())1150Sstevel@tonic-gate genent_user_attr(char *line, int (*cback)())
1160Sstevel@tonic-gate {
1170Sstevel@tonic-gate entry_col *ecol;
1180Sstevel@tonic-gate userstr_t data;
1190Sstevel@tonic-gate int res, retval;
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate /*
1220Sstevel@tonic-gate * parse entry into columns
1230Sstevel@tonic-gate */
1240Sstevel@tonic-gate res = genent_attr(line, USERATTR_DB_NCOL, &ecol);
1250Sstevel@tonic-gate if (res != GENENT_OK)
1260Sstevel@tonic-gate return (res);
1270Sstevel@tonic-gate
1280Sstevel@tonic-gate data.name = ecol[0].ec_value.ec_value_val;
1290Sstevel@tonic-gate data.qualifier = ecol[1].ec_value.ec_value_val;
1300Sstevel@tonic-gate data.res1 = NULL;
1310Sstevel@tonic-gate data.res2 = NULL;
1320Sstevel@tonic-gate data.attr = ecol[4].ec_value.ec_value_val;
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate if (flags & F_VERBOSE)
1350Sstevel@tonic-gate (void) fprintf(stdout,
1360Sstevel@tonic-gate gettext("Adding entry : %s\n"), data.name);
1370Sstevel@tonic-gate
1380Sstevel@tonic-gate retval = (*cback)(&data, 1);
1392277Sjs198686 if (retval != NS_LDAP_SUCCESS) {
1402277Sjs198686 if (retval == LDAP_NO_SUCH_OBJECT)
1412277Sjs198686 (void) fprintf(stdout,
1422277Sjs198686 gettext("Cannot add user_attr entry (%s), "
1432277Sjs198686 "add passwd entry first\n"), data.name);
1442277Sjs198686 if (continue_onerror == 0) res = GENENT_CBERR;
1452277Sjs198686 }
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate free(ecol);
1480Sstevel@tonic-gate
1490Sstevel@tonic-gate return (res);
1500Sstevel@tonic-gate }
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate void
dump_user_attr(ns_ldap_result_t * res)1530Sstevel@tonic-gate dump_user_attr(ns_ldap_result_t *res)
1540Sstevel@tonic-gate {
1550Sstevel@tonic-gate char **value = NULL;
1560Sstevel@tonic-gate
1570Sstevel@tonic-gate value = __ns_ldap_getAttr(res->entry, "uid");
1580Sstevel@tonic-gate if (value && value[0])
1590Sstevel@tonic-gate (void) fprintf(stdout, "%s", value[0]);
1600Sstevel@tonic-gate else
1610Sstevel@tonic-gate return;
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate (void) fprintf(stdout, "::::");
1640Sstevel@tonic-gate value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
1650Sstevel@tonic-gate if (value && value[0])
1660Sstevel@tonic-gate (void) fprintf(stdout, "%s", value[0]);
1670Sstevel@tonic-gate (void) fprintf(stdout, "\n");
1680Sstevel@tonic-gate }
1690Sstevel@tonic-gate
1700Sstevel@tonic-gate int
genent_prof_attr(char * line,int (* cback)())1710Sstevel@tonic-gate genent_prof_attr(char *line, int (*cback)())
1720Sstevel@tonic-gate {
1730Sstevel@tonic-gate entry_col *ecol;
1740Sstevel@tonic-gate profstr_t data;
1750Sstevel@tonic-gate int res, retval;
1760Sstevel@tonic-gate
1770Sstevel@tonic-gate /*
1780Sstevel@tonic-gate * parse entry into columns
1790Sstevel@tonic-gate */
1800Sstevel@tonic-gate res = genent_attr(line, PROFATTR_DB_NCOL, &ecol);
1810Sstevel@tonic-gate if (res != GENENT_OK)
1820Sstevel@tonic-gate return (res);
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate data.name = ecol[0].ec_value.ec_value_val;
1850Sstevel@tonic-gate data.res1 = NULL;
1860Sstevel@tonic-gate data.res2 = NULL;
1870Sstevel@tonic-gate data.desc = ecol[3].ec_value.ec_value_val;
1880Sstevel@tonic-gate data.attr = ecol[4].ec_value.ec_value_val;
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate if (flags & F_VERBOSE)
1910Sstevel@tonic-gate (void) fprintf(stdout,
1920Sstevel@tonic-gate gettext("Adding entry : %s\n"), data.name);
1930Sstevel@tonic-gate
1940Sstevel@tonic-gate retval = (*cback)(&data, 0);
1950Sstevel@tonic-gate if (retval == LDAP_ALREADY_EXISTS) {
1960Sstevel@tonic-gate if (continue_onerror)
1970Sstevel@tonic-gate (void) fprintf(stderr,
1980Sstevel@tonic-gate gettext("Entry: %s - already Exists,"
1990Sstevel@tonic-gate " skipping it.\n"),
2000Sstevel@tonic-gate data.name);
2010Sstevel@tonic-gate else {
2020Sstevel@tonic-gate res = GENENT_CBERR;
2030Sstevel@tonic-gate (void) fprintf(stderr,
2040Sstevel@tonic-gate gettext("Entry: %s - already Exists\n"),
2050Sstevel@tonic-gate data.name);
2060Sstevel@tonic-gate }
2070Sstevel@tonic-gate } else if (retval)
2080Sstevel@tonic-gate res = GENENT_CBERR;
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate free(ecol);
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate return (res);
2130Sstevel@tonic-gate }
2140Sstevel@tonic-gate
2150Sstevel@tonic-gate void
dump_prof_attr(ns_ldap_result_t * res)2160Sstevel@tonic-gate dump_prof_attr(ns_ldap_result_t *res)
2170Sstevel@tonic-gate {
2180Sstevel@tonic-gate char **value = NULL;
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate value = __ns_ldap_getAttr(res->entry, "cn");
2210Sstevel@tonic-gate if (value && value[0])
2220Sstevel@tonic-gate (void) fprintf(stdout, "%s", value[0]);
2230Sstevel@tonic-gate else
2240Sstevel@tonic-gate return;
2250Sstevel@tonic-gate
2260Sstevel@tonic-gate (void) fprintf(stdout, ":::");
2270Sstevel@tonic-gate value = __ns_ldap_getAttr(res->entry, "SolarisAttrLongDesc");
2280Sstevel@tonic-gate if (value && value[0])
2290Sstevel@tonic-gate (void) fprintf(stdout, "%s", value[0]);
2300Sstevel@tonic-gate (void) fprintf(stdout, ":");
2310Sstevel@tonic-gate value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
2320Sstevel@tonic-gate if (value && value[0])
2330Sstevel@tonic-gate (void) fprintf(stdout, "%s", value[0]);
2340Sstevel@tonic-gate (void) fprintf(stdout, "\n");
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate int
genent_exec_attr(char * line,int (* cback)())2380Sstevel@tonic-gate genent_exec_attr(char *line, int (*cback)())
2390Sstevel@tonic-gate {
2400Sstevel@tonic-gate entry_col *ecol;
2410Sstevel@tonic-gate execstr_t data;
2420Sstevel@tonic-gate int res, retval;
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate /*
2450Sstevel@tonic-gate * parse entry into columns
2460Sstevel@tonic-gate */
2470Sstevel@tonic-gate res = genent_attr(line, EXECATTR_DB_NCOL, &ecol);
2480Sstevel@tonic-gate if (res != GENENT_OK)
2490Sstevel@tonic-gate return (res);
2500Sstevel@tonic-gate
2510Sstevel@tonic-gate data.name = ecol[0].ec_value.ec_value_val;
2520Sstevel@tonic-gate data.policy = ecol[1].ec_value.ec_value_val;
2530Sstevel@tonic-gate data.type = ecol[2].ec_value.ec_value_val;
2540Sstevel@tonic-gate data.res1 = NULL;
2550Sstevel@tonic-gate data.res2 = NULL;
2560Sstevel@tonic-gate data.id = ecol[5].ec_value.ec_value_val;
2570Sstevel@tonic-gate data.attr = ecol[6].ec_value.ec_value_val;
2580Sstevel@tonic-gate data.next = NULL;
2590Sstevel@tonic-gate
2600Sstevel@tonic-gate if (flags & F_VERBOSE)
2610Sstevel@tonic-gate (void) fprintf(stdout,
2620Sstevel@tonic-gate gettext("Adding entry : %s+%s+%s+%s\n"),
2630Sstevel@tonic-gate data.name, data.policy, data.type, data.id);
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate retval = (*cback)(&data, 0);
2660Sstevel@tonic-gate if (retval == LDAP_ALREADY_EXISTS) {
2670Sstevel@tonic-gate if (continue_onerror)
2680Sstevel@tonic-gate (void) fprintf(stderr,
2690Sstevel@tonic-gate gettext("Entry: %s+%s+%s+%s - already Exists,"
2700Sstevel@tonic-gate " skipping it.\n"),
2710Sstevel@tonic-gate data.name, data.policy, data.type, data.id);
2720Sstevel@tonic-gate else {
2730Sstevel@tonic-gate res = GENENT_CBERR;
2740Sstevel@tonic-gate (void) fprintf(stderr,
2750Sstevel@tonic-gate gettext("Entry: %s+%s+%s+%s - already Exists\n"),
2760Sstevel@tonic-gate data.name, data.policy, data.type, data.id);
2770Sstevel@tonic-gate }
2780Sstevel@tonic-gate } else if (retval)
2790Sstevel@tonic-gate res = GENENT_CBERR;
2800Sstevel@tonic-gate
2810Sstevel@tonic-gate free(ecol);
2820Sstevel@tonic-gate
2830Sstevel@tonic-gate return (res);
2840Sstevel@tonic-gate }
2850Sstevel@tonic-gate
2860Sstevel@tonic-gate void
dump_exec_attr(ns_ldap_result_t * res)2870Sstevel@tonic-gate dump_exec_attr(ns_ldap_result_t *res)
2880Sstevel@tonic-gate {
2890Sstevel@tonic-gate char **profile;
2900Sstevel@tonic-gate char **policy;
2910Sstevel@tonic-gate char **type;
2920Sstevel@tonic-gate char **id;
2930Sstevel@tonic-gate char **value;
2940Sstevel@tonic-gate
2950Sstevel@tonic-gate profile = __ns_ldap_getAttr(res->entry, "cn");
2960Sstevel@tonic-gate policy = __ns_ldap_getAttr(res->entry, "SolarisKernelSecurityPolicy");
2970Sstevel@tonic-gate type = __ns_ldap_getAttr(res->entry, "SolarisProfileType");
2980Sstevel@tonic-gate id = __ns_ldap_getAttr(res->entry, "SolarisProfileId");
2990Sstevel@tonic-gate
3000Sstevel@tonic-gate if (profile == NULL || profile[0] == NULL ||
3010Sstevel@tonic-gate policy == NULL || policy[0] == NULL ||
3020Sstevel@tonic-gate type == NULL || type[0] == NULL ||
3030Sstevel@tonic-gate id == NULL || id[0] == NULL)
3040Sstevel@tonic-gate return;
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate (void) fprintf(stdout, "%s", profile[0]);
3070Sstevel@tonic-gate (void) fprintf(stdout, ":");
3080Sstevel@tonic-gate (void) fprintf(stdout, "%s", policy[0]);
3090Sstevel@tonic-gate (void) fprintf(stdout, ":");
3100Sstevel@tonic-gate (void) fprintf(stdout, "%s", type[0]);
3110Sstevel@tonic-gate (void) fprintf(stdout, ":::");
3120Sstevel@tonic-gate (void) fprintf(stdout, "%s", id[0]);
3130Sstevel@tonic-gate (void) fprintf(stdout, ":");
3140Sstevel@tonic-gate value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
3150Sstevel@tonic-gate if (value && value[0])
3160Sstevel@tonic-gate (void) fprintf(stdout, "%s", value[0]);
3170Sstevel@tonic-gate (void) fprintf(stdout, "\n");
3180Sstevel@tonic-gate }
3190Sstevel@tonic-gate
3200Sstevel@tonic-gate int
genent_auth_attr(char * line,int (* cback)())3210Sstevel@tonic-gate genent_auth_attr(char *line, int (*cback)())
3220Sstevel@tonic-gate {
3230Sstevel@tonic-gate entry_col *ecol;
3240Sstevel@tonic-gate authstr_t data;
3250Sstevel@tonic-gate int res, retval;
3260Sstevel@tonic-gate
3270Sstevel@tonic-gate /*
3280Sstevel@tonic-gate * parse entry into columns
3290Sstevel@tonic-gate */
3300Sstevel@tonic-gate res = genent_attr(line, AUTHATTR_DB_NCOL, &ecol);
3310Sstevel@tonic-gate if (res != GENENT_OK)
3320Sstevel@tonic-gate return (res);
3330Sstevel@tonic-gate
3340Sstevel@tonic-gate data.name = ecol[0].ec_value.ec_value_val;
3350Sstevel@tonic-gate data.res1 = NULL;
3360Sstevel@tonic-gate data.res2 = NULL;
3370Sstevel@tonic-gate data.short_desc = ecol[3].ec_value.ec_value_val;
3380Sstevel@tonic-gate data.long_desc = ecol[4].ec_value.ec_value_val;
3390Sstevel@tonic-gate data.attr = ecol[5].ec_value.ec_value_val;
3400Sstevel@tonic-gate
3410Sstevel@tonic-gate if (flags & F_VERBOSE)
3420Sstevel@tonic-gate (void) fprintf(stdout,
3430Sstevel@tonic-gate gettext("Adding entry : %s\n"), data.name);
3440Sstevel@tonic-gate
3450Sstevel@tonic-gate retval = (*cback)(&data, 0);
3460Sstevel@tonic-gate if (retval == LDAP_ALREADY_EXISTS) {
3470Sstevel@tonic-gate if (continue_onerror)
3480Sstevel@tonic-gate (void) fprintf(stderr,
3490Sstevel@tonic-gate gettext("Entry: %s - already Exists,"
3500Sstevel@tonic-gate " skipping it.\n"), data.name);
3510Sstevel@tonic-gate else {
3520Sstevel@tonic-gate res = GENENT_CBERR;
3530Sstevel@tonic-gate (void) fprintf(stderr,
3540Sstevel@tonic-gate gettext("Entry: %s - already Exists\n"),
3550Sstevel@tonic-gate data.name);
3560Sstevel@tonic-gate }
3570Sstevel@tonic-gate } else if (retval)
3580Sstevel@tonic-gate res = GENENT_CBERR;
3590Sstevel@tonic-gate
3600Sstevel@tonic-gate free(ecol);
3610Sstevel@tonic-gate
3620Sstevel@tonic-gate return (res);
3630Sstevel@tonic-gate }
3640Sstevel@tonic-gate
3650Sstevel@tonic-gate void
dump_auth_attr(ns_ldap_result_t * res)3660Sstevel@tonic-gate dump_auth_attr(ns_ldap_result_t *res)
3670Sstevel@tonic-gate {
3680Sstevel@tonic-gate char **value = NULL;
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate value = __ns_ldap_getAttr(res->entry, "cn");
3710Sstevel@tonic-gate if (value && value[0])
3720Sstevel@tonic-gate (void) fprintf(stdout, "%s", value[0]);
3730Sstevel@tonic-gate else
3740Sstevel@tonic-gate return;
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate (void) fprintf(stdout, ":::");
3770Sstevel@tonic-gate value = __ns_ldap_getAttr(res->entry, "SolarisAttrShortDesc");
3780Sstevel@tonic-gate if (value && value[0])
3790Sstevel@tonic-gate (void) fprintf(stdout, "%s", value[0]);
3800Sstevel@tonic-gate (void) fprintf(stdout, ":");
3810Sstevel@tonic-gate value = __ns_ldap_getAttr(res->entry, "SolarisAttrLongDesc");
3820Sstevel@tonic-gate if (value && value[0])
3830Sstevel@tonic-gate (void) fprintf(stdout, "%s", value[0]);
3840Sstevel@tonic-gate (void) fprintf(stdout, ":");
3850Sstevel@tonic-gate value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
3860Sstevel@tonic-gate if (value && value[0])
3870Sstevel@tonic-gate (void) fprintf(stdout, "%s", value[0]);
3880Sstevel@tonic-gate (void) fprintf(stdout, "\n");
3890Sstevel@tonic-gate }
390