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
51603Svl199446  * Common Development and Distribution License (the "License").
61603Svl199446  * 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 /*
221603Svl199446  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * ldapaddent.c
300Sstevel@tonic-gate  *
310Sstevel@tonic-gate  * Utility to add /etc files into LDAP.
320Sstevel@tonic-gate  * Can also be used to dump entries from a ldap container in /etc format.
330Sstevel@tonic-gate  */
340Sstevel@tonic-gate 
350Sstevel@tonic-gate #include <stdio.h>
360Sstevel@tonic-gate #include <stdlib.h>
370Sstevel@tonic-gate #include <libintl.h>
380Sstevel@tonic-gate #include <strings.h>
390Sstevel@tonic-gate #include <sys/param.h>
400Sstevel@tonic-gate #include <ctype.h>
410Sstevel@tonic-gate #include <sys/types.h>
420Sstevel@tonic-gate #include <sys/socket.h>
430Sstevel@tonic-gate #include <netinet/in.h>
440Sstevel@tonic-gate #include <arpa/inet.h>
450Sstevel@tonic-gate #include <locale.h>
460Sstevel@tonic-gate #include <syslog.h>
470Sstevel@tonic-gate 
480Sstevel@tonic-gate #undef opaque
490Sstevel@tonic-gate 
500Sstevel@tonic-gate #include <nss_dbdefs.h>
510Sstevel@tonic-gate #include <netdb.h>
520Sstevel@tonic-gate #include <rpc/rpcent.h>
530Sstevel@tonic-gate #include <grp.h>
540Sstevel@tonic-gate #include <pwd.h>
550Sstevel@tonic-gate #include <shadow.h>
560Sstevel@tonic-gate #include <sys/systeminfo.h>
570Sstevel@tonic-gate #include "ns_internal.h"
580Sstevel@tonic-gate #include "ldapaddent.h"
590Sstevel@tonic-gate 
600Sstevel@tonic-gate #define	OP_ADD	0
610Sstevel@tonic-gate #define	OP_DUMP	3
620Sstevel@tonic-gate 
630Sstevel@tonic-gate static struct ttypelist_t {
640Sstevel@tonic-gate 	char *ttype;		/* type tag */
650Sstevel@tonic-gate 	int (*genent)(char *, int(*)());
660Sstevel@tonic-gate 				/* routine to turn line into ldap entries */
670Sstevel@tonic-gate 	void (*dump)(ns_ldap_result_t *);
680Sstevel@tonic-gate 				/* routine to print ldap containers */
690Sstevel@tonic-gate 	int (*filedbmline)();	/* routine to turn file line into dbm line */
700Sstevel@tonic-gate 	char *objclass;		/* Objectclass for the servicetype */
710Sstevel@tonic-gate } *tt;
720Sstevel@tonic-gate 
730Sstevel@tonic-gate char	parse_err_msg [PARSE_ERR_MSG_LEN];
740Sstevel@tonic-gate int	continue_onerror = 0;  /* do not exit on error */
750Sstevel@tonic-gate 
760Sstevel@tonic-gate static int get_basedn(char *service, char **basedn);
770Sstevel@tonic-gate static int check_ipaddr(char *addr, char **newaddr);
780Sstevel@tonic-gate 
790Sstevel@tonic-gate extern	int	optind;
800Sstevel@tonic-gate extern	char	*optarg;
810Sstevel@tonic-gate 
820Sstevel@tonic-gate extern	char	*__nis_quote_key(const char *, char *, int);
830Sstevel@tonic-gate 
840Sstevel@tonic-gate static char	*inputbasedn = NULL;
850Sstevel@tonic-gate static char	*databasetype = NULL;
860Sstevel@tonic-gate static int	exit_val = 0;
870Sstevel@tonic-gate static unsigned	nent_add = 0;
880Sstevel@tonic-gate static FILE	*etcf = 0;
890Sstevel@tonic-gate static ns_cred_t	authority;
900Sstevel@tonic-gate unsigned	flags = 0;
910Sstevel@tonic-gate 
920Sstevel@tonic-gate static void
930Sstevel@tonic-gate perr(ns_ldap_error_t *e)
940Sstevel@tonic-gate {
950Sstevel@tonic-gate 	if (e)
960Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("%d: %s\n"),
970Sstevel@tonic-gate 				e->status, e->message);
980Sstevel@tonic-gate }
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate static int
1020Sstevel@tonic-gate ascii_to_int(char *str)
1030Sstevel@tonic-gate {
1040Sstevel@tonic-gate 	int i;
1050Sstevel@tonic-gate 	char *c = str;
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate 	if (c == NULL || *c == '\0')
1080Sstevel@tonic-gate 		return (-1);
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate 	while (c != '\0' && *c == ' ')
1110Sstevel@tonic-gate 		c++;
1120Sstevel@tonic-gate 	if (*c == '\0')
1130Sstevel@tonic-gate 		return (-1);
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 	for (i = 0; i < strlen(c); i++)
1160Sstevel@tonic-gate 		if (!isdigit(c[i]))
1170Sstevel@tonic-gate 			return (-1);
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 	return (atoi(c));
1200Sstevel@tonic-gate }
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate /*
1230Sstevel@tonic-gate  * Internet network address interpretation routine.
1240Sstevel@tonic-gate  * The library routines call this routine to interpret
1250Sstevel@tonic-gate  * network numbers.
1260Sstevel@tonic-gate  */
1270Sstevel@tonic-gate static in_addr_t
1280Sstevel@tonic-gate encode_network(const char *cp)
1290Sstevel@tonic-gate {
1300Sstevel@tonic-gate 	in_addr_t val;
1310Sstevel@tonic-gate 	int base;
1320Sstevel@tonic-gate 	ptrdiff_t n;
1330Sstevel@tonic-gate 	char c;
1340Sstevel@tonic-gate 	in_addr_t parts[4], *pp = parts;
1350Sstevel@tonic-gate 	int i;
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate again:
1380Sstevel@tonic-gate 	val = 0; base = 10;
1390Sstevel@tonic-gate 	if (*cp == '0') {
1400Sstevel@tonic-gate 		if (*++cp == 'x' || *cp == 'X')
1410Sstevel@tonic-gate 			base = 16, cp++;
1420Sstevel@tonic-gate 		else
1430Sstevel@tonic-gate 			base = 8;
1440Sstevel@tonic-gate 	}
1450Sstevel@tonic-gate 	while ((c = *cp) != NULL) {
1460Sstevel@tonic-gate 		if (isdigit(c)) {
1470Sstevel@tonic-gate 			if ((c - '0') >= base)
1480Sstevel@tonic-gate 			    break;
1490Sstevel@tonic-gate 			val = (val * base) + (c - '0');
1500Sstevel@tonic-gate 			cp++;
1510Sstevel@tonic-gate 			continue;
1520Sstevel@tonic-gate 		}
1530Sstevel@tonic-gate 		if (base == 16 && isxdigit(c)) {
1540Sstevel@tonic-gate 			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
1550Sstevel@tonic-gate 			cp++;
1560Sstevel@tonic-gate 			continue;
1570Sstevel@tonic-gate 		}
1580Sstevel@tonic-gate 		break;
1590Sstevel@tonic-gate 	}
1600Sstevel@tonic-gate 	if (*cp == '.') {
1610Sstevel@tonic-gate 		if (pp >= parts + 4)
1620Sstevel@tonic-gate 			return ((in_addr_t)-1);
1630Sstevel@tonic-gate 		*pp++ = val, cp++;
1640Sstevel@tonic-gate 		goto again;
1650Sstevel@tonic-gate 	}
1660Sstevel@tonic-gate 	if (*cp && !isspace(*cp))
1670Sstevel@tonic-gate 		return ((in_addr_t)-1);
1680Sstevel@tonic-gate 	*pp++ = val;
1690Sstevel@tonic-gate 	n = pp - parts;
1700Sstevel@tonic-gate 	if (n > 4)
1710Sstevel@tonic-gate 		return ((in_addr_t)-1);
1720Sstevel@tonic-gate 	for (val = 0, i = 0; i < n; i++) {
1730Sstevel@tonic-gate 		val <<= 8;
1740Sstevel@tonic-gate 		val |= parts[i] & 0xff;
1750Sstevel@tonic-gate 	}
1760Sstevel@tonic-gate 	for (/* no init */; i < 4; i++)
1770Sstevel@tonic-gate 		val <<= 8;
1780Sstevel@tonic-gate 	return (val);
1790Sstevel@tonic-gate }
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate static void
1820Sstevel@tonic-gate replace_tab2space(char *str)
1830Sstevel@tonic-gate {
1840Sstevel@tonic-gate 	int i = 0;
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 	while ((str) && (str[i])) {
1870Sstevel@tonic-gate 		if (str[i] == '\t')
1880Sstevel@tonic-gate 			str[i] = ' ';
1890Sstevel@tonic-gate 		i++;
1900Sstevel@tonic-gate 	}
1910Sstevel@tonic-gate }
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate static int
1940Sstevel@tonic-gate blankline(char *line)
1950Sstevel@tonic-gate {
1960Sstevel@tonic-gate 	char *p;
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 	for (p = line; *p; p++)
1990Sstevel@tonic-gate 		if (*p != ' ' && *p != '\t')
2000Sstevel@tonic-gate 			return (0);
2010Sstevel@tonic-gate 	return (1);
2020Sstevel@tonic-gate }
2030Sstevel@tonic-gate 
2041603Svl199446 /*
2051603Svl199446  * check whether the token <tok> is a triplet,
2061603Svl199446  * i. e. <tok> := (<hostname>,<username>,<domainname>)
2071603Svl199446  * where <hostname>, <username>, <domainname> are IA5String
2081603Svl199446  * <tok> supposes to contain NO spaces and start with '('
2091603Svl199446  */
2101603Svl199446 static int
2111603Svl199446 is_triplet(char *tok)
2121603Svl199446 {
2131603Svl199446 	char *s;
2141603Svl199446 	return (strchr(++tok, '(') == NULL &&		/* no more '(' */
2151603Svl199446 		(s = strchr(tok, ')')) != NULL &&	/* find ')' */
2161603Svl199446 		!*++s &&				/* ')' ends token */
2171603Svl199446 		(tok = strchr(tok, ',')) != NULL &&	/* host up to ',' */
2181603Svl199446 		(tok = strchr(++tok, ',')) != NULL &&	/* user up to ',' */
2191603Svl199446 		strchr(++tok, ',') == NULL);		/* no more ',' */
2201603Svl199446 }
2211603Svl199446 
2220Sstevel@tonic-gate static void
2230Sstevel@tonic-gate line_buf_expand(struct line_buf *line)
2240Sstevel@tonic-gate {
2250Sstevel@tonic-gate 	line->alloc += BUFSIZ;
2260Sstevel@tonic-gate 	line->str = (char *)realloc(line->str, line->alloc);
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate 	if (line->str == NULL) {
2290Sstevel@tonic-gate 		(void) fprintf(stderr,
2300Sstevel@tonic-gate 		    gettext("line_buf_expand: out of memory\n"));
2310Sstevel@tonic-gate 		exit(1);
2320Sstevel@tonic-gate 	}
2330Sstevel@tonic-gate }
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate static void
2360Sstevel@tonic-gate line_buf_init(struct line_buf *line)
2370Sstevel@tonic-gate {
2380Sstevel@tonic-gate 	(void) memset((char *)line, 0, sizeof (*line));
2390Sstevel@tonic-gate 	line_buf_expand(line);
2400Sstevel@tonic-gate }
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate static int
2430Sstevel@tonic-gate __s_add_attr(ns_ldap_entry_t *e, char *attrname, char *value)
2440Sstevel@tonic-gate {
2450Sstevel@tonic-gate 	ns_ldap_attr_t	*a;
2460Sstevel@tonic-gate 	char		*v;
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate 	a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t));
2490Sstevel@tonic-gate 	if (a == NULL)
2500Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2510Sstevel@tonic-gate 	a->attrname = strdup(attrname);
2520Sstevel@tonic-gate 	if (a->attrname == NULL) {
2530Sstevel@tonic-gate 		free(a);
2540Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2550Sstevel@tonic-gate 	}
2560Sstevel@tonic-gate 	a->attrvalue = (char **)calloc(1, sizeof (char **));
2570Sstevel@tonic-gate 	if (a->attrvalue == NULL) {
2580Sstevel@tonic-gate 		free(a->attrname);
2590Sstevel@tonic-gate 		free(a);
2600Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2610Sstevel@tonic-gate 	}
2620Sstevel@tonic-gate 	a->value_count = 1;
2630Sstevel@tonic-gate 	a->attrvalue[0] = NULL;
2640Sstevel@tonic-gate 	v = strdup(value);
2650Sstevel@tonic-gate 	if (v == NULL) {
2660Sstevel@tonic-gate 		free(a->attrname);
2670Sstevel@tonic-gate 		free(a->attrvalue);
2680Sstevel@tonic-gate 		free(a);
2690Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2700Sstevel@tonic-gate 	}
2710Sstevel@tonic-gate 	a->attrvalue[0] = v;
2720Sstevel@tonic-gate 	e->attr_pair[e->attr_count] = a;
2730Sstevel@tonic-gate 	e->attr_count++;
2740Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
2750Sstevel@tonic-gate }
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate static int
2780Sstevel@tonic-gate __s_add_attrlist(ns_ldap_entry_t *e, char *attrname, char **argv)
2790Sstevel@tonic-gate {
2800Sstevel@tonic-gate 	ns_ldap_attr_t	*a;
2810Sstevel@tonic-gate 	char		*v;
2820Sstevel@tonic-gate 	char		**av;
2830Sstevel@tonic-gate 	int		i, j;
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate 	a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t));
2860Sstevel@tonic-gate 	if (a == NULL)
2870Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2880Sstevel@tonic-gate 	a->attrname = strdup(attrname);
2890Sstevel@tonic-gate 	if (a->attrname == NULL) {
2900Sstevel@tonic-gate 		free(a);
2910Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2920Sstevel@tonic-gate 	}
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate 	for (i = 0, av = argv; *av != NULL; av++, i++)
2950Sstevel@tonic-gate 		;
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate 	a->attrvalue = (char **)calloc(i, sizeof (char **));
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate 	if (a->attrvalue == NULL) {
3000Sstevel@tonic-gate 		free(a->attrname);
3010Sstevel@tonic-gate 		free(a);
3020Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
3030Sstevel@tonic-gate 	}
3040Sstevel@tonic-gate 	a->value_count = i;
3050Sstevel@tonic-gate 	for (j = 0; j < i; j++) {
3060Sstevel@tonic-gate 		v = strdup(argv[j]);
3070Sstevel@tonic-gate 		if (v == NULL) {
3080Sstevel@tonic-gate 			free(a->attrname);
3090Sstevel@tonic-gate 			free(a->attrvalue);
3100Sstevel@tonic-gate 			free(a);
3110Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
3120Sstevel@tonic-gate 		}
3130Sstevel@tonic-gate 		a->attrvalue[j] = v;
3140Sstevel@tonic-gate 	}
3150Sstevel@tonic-gate 	e->attr_pair[e->attr_count] = a;
3160Sstevel@tonic-gate 	e->attr_count++;
3170Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
3180Sstevel@tonic-gate }
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate static ns_ldap_entry_t *
3210Sstevel@tonic-gate __s_mk_entry(char **objclass, int max_attr)
3220Sstevel@tonic-gate {
3230Sstevel@tonic-gate 	ns_ldap_entry_t *e;
3240Sstevel@tonic-gate 	e = (ns_ldap_entry_t *)calloc(1, sizeof (ns_ldap_entry_t));
3250Sstevel@tonic-gate 	if (e == NULL)
3260Sstevel@tonic-gate 		return (NULL);
3270Sstevel@tonic-gate 	e->attr_pair = (ns_ldap_attr_t **)calloc(max_attr+1,
3280Sstevel@tonic-gate 						sizeof (ns_ldap_attr_t *));
3290Sstevel@tonic-gate 	if (e->attr_pair == NULL) {
3300Sstevel@tonic-gate 		free(e);
3310Sstevel@tonic-gate 		return (NULL);
3320Sstevel@tonic-gate 	}
3330Sstevel@tonic-gate 	e->attr_count = 0;
3340Sstevel@tonic-gate 	if (__s_add_attrlist(e, "objectClass", objclass) != NS_LDAP_SUCCESS) {
3350Sstevel@tonic-gate 		free(e->attr_pair);
3360Sstevel@tonic-gate 		free(e);
3370Sstevel@tonic-gate 		return (NULL);
3380Sstevel@tonic-gate 	}
3390Sstevel@tonic-gate 	return (e);
3400Sstevel@tonic-gate }
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate static void
3430Sstevel@tonic-gate ldap_freeEntry(ns_ldap_entry_t *ep)
3440Sstevel@tonic-gate {
3450Sstevel@tonic-gate 	int		j, k = 0;
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate 	if (ep == NULL)
3480Sstevel@tonic-gate 		return;
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 	if (ep->attr_pair == NULL) {
3510Sstevel@tonic-gate 		free(ep);
3520Sstevel@tonic-gate 		return;
3530Sstevel@tonic-gate 	}
3540Sstevel@tonic-gate 	for (j = 0; j < ep->attr_count; j++) {
3550Sstevel@tonic-gate 		if (ep->attr_pair[j] == NULL)
3560Sstevel@tonic-gate 			continue;
3570Sstevel@tonic-gate 		if (ep->attr_pair[j]->attrname)
3580Sstevel@tonic-gate 			free(ep->attr_pair[j]->attrname);
3590Sstevel@tonic-gate 		if (ep->attr_pair[j]->attrvalue) {
3600Sstevel@tonic-gate 			for (k = 0; (k < ep->attr_pair[j]->value_count) &&
3610Sstevel@tonic-gate 				    (ep->attr_pair[j]->attrvalue[k]); k++) {
3620Sstevel@tonic-gate 				free(ep->attr_pair[j]->attrvalue[k]);
3630Sstevel@tonic-gate 			}
3640Sstevel@tonic-gate 			free(ep->attr_pair[j]->attrvalue);
3650Sstevel@tonic-gate 		}
3660Sstevel@tonic-gate 		free(ep->attr_pair[j]);
3670Sstevel@tonic-gate 	}
3680Sstevel@tonic-gate 	free(ep->attr_pair);
3690Sstevel@tonic-gate 	free(ep);
3700Sstevel@tonic-gate }
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate static int
3730Sstevel@tonic-gate addentry(void *entry, int mod)
3740Sstevel@tonic-gate {
3750Sstevel@tonic-gate 	int		 result = 0;
3760Sstevel@tonic-gate 	ns_ldap_error_t	 *eres = NULL;
3770Sstevel@tonic-gate 	int		rc = 1;
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate 	/*  adds entry into the LDAP tree */
3810Sstevel@tonic-gate 	if (mod)
3820Sstevel@tonic-gate 		result = __ns_ldap_addTypedEntry(databasetype, inputbasedn,
3830Sstevel@tonic-gate 		    entry, 0, &authority, NS_LDAP_FOLLOWREF, &eres);
3840Sstevel@tonic-gate 	else
3850Sstevel@tonic-gate 		result = __ns_ldap_addTypedEntry(databasetype, inputbasedn,
3860Sstevel@tonic-gate 		    entry, 1, &authority, NS_LDAP_FOLLOWREF, &eres);
3870Sstevel@tonic-gate 	/*
3880Sstevel@tonic-gate 	 *  Return	0 on success
3890Sstevel@tonic-gate 	 *		LDAP_ALREADY_EXISTS if entry exists already
3900Sstevel@tonic-gate 	 *		1 for all other non-fatal errors.
3910Sstevel@tonic-gate 	 *  Exit on fatal errors.
3920Sstevel@tonic-gate 	 */
3930Sstevel@tonic-gate 	switch (result) {
3940Sstevel@tonic-gate 	case NS_LDAP_SUCCESS:
3950Sstevel@tonic-gate 		nent_add++;
3960Sstevel@tonic-gate 		rc = 0;
3970Sstevel@tonic-gate 		break;
3980Sstevel@tonic-gate 
3990Sstevel@tonic-gate 	case NS_LDAP_OP_FAILED:
4000Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("operation failed.\n"));
4010Sstevel@tonic-gate 		rc = 1;
4020Sstevel@tonic-gate 		break;
4030Sstevel@tonic-gate 
4040Sstevel@tonic-gate 	case NS_LDAP_INVALID_PARAM:
4050Sstevel@tonic-gate 		(void) fprintf(stderr,
4060Sstevel@tonic-gate 		    gettext("invalid parameter(s) passed.\n"));
4070Sstevel@tonic-gate 		rc = 1;
4080Sstevel@tonic-gate 		break;
4090Sstevel@tonic-gate 
4100Sstevel@tonic-gate 	case NS_LDAP_NOTFOUND:
4110Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("entry not found.\n"));
4120Sstevel@tonic-gate 		rc = 1;
4130Sstevel@tonic-gate 		break;
4140Sstevel@tonic-gate 
4150Sstevel@tonic-gate 	case NS_LDAP_MEMORY:
4160Sstevel@tonic-gate 		(void) fprintf(stderr,
4170Sstevel@tonic-gate 		    gettext("internal memory allocation error.\n"));
4180Sstevel@tonic-gate 		exit(1);
4190Sstevel@tonic-gate 		break;
4200Sstevel@tonic-gate 
4210Sstevel@tonic-gate 	case NS_LDAP_CONFIG:
4220Sstevel@tonic-gate 		(void) fprintf(stderr,
4230Sstevel@tonic-gate 		    gettext("LDAP Configuration problem.\n"));
4240Sstevel@tonic-gate 		perr(eres);
4250Sstevel@tonic-gate 		exit(1);
4260Sstevel@tonic-gate 		break;
4270Sstevel@tonic-gate 
4280Sstevel@tonic-gate 	case NS_LDAP_PARTIAL:
4290Sstevel@tonic-gate 		(void) fprintf(stderr,
4300Sstevel@tonic-gate 		    gettext("partial result returned\n"));
4310Sstevel@tonic-gate 		perr(eres);
4320Sstevel@tonic-gate 		rc = 1;
4330Sstevel@tonic-gate 		break;
4340Sstevel@tonic-gate 
4350Sstevel@tonic-gate 	case NS_LDAP_INTERNAL:
4362277Sjs198686 		if (eres->status == LDAP_ALREADY_EXISTS ||
4372277Sjs198686 			eres->status == LDAP_NO_SUCH_OBJECT)
4380Sstevel@tonic-gate 			rc = eres->status;
439*2830Sdjl 		else if (eres->status == LDAP_INSUFFICIENT_ACCESS) {
440*2830Sdjl 			(void) fprintf(stderr,
441*2830Sdjl 				gettext("The user does not have permission"
442*2830Sdjl 					" to add/modify entries\n"));
443*2830Sdjl 			perr(eres);
444*2830Sdjl 			exit(1);
445*2830Sdjl 		} else {
4460Sstevel@tonic-gate 			rc = 1;
4470Sstevel@tonic-gate 			perr(eres);
4480Sstevel@tonic-gate 		}
4490Sstevel@tonic-gate 		break;
4500Sstevel@tonic-gate 	}
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate 	if (eres)
4530Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&eres);
4540Sstevel@tonic-gate 	return (rc);
4550Sstevel@tonic-gate }
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate 
4580Sstevel@tonic-gate /*
4590Sstevel@tonic-gate  * usage(char *msg)
4600Sstevel@tonic-gate  * Display usage message to STDERR.
4610Sstevel@tonic-gate  */
4620Sstevel@tonic-gate static void
4630Sstevel@tonic-gate usage(char *msg) {
4640Sstevel@tonic-gate 
4650Sstevel@tonic-gate 	if (msg)
4660Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("%s\n"), msg);
4670Sstevel@tonic-gate 
4680Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
4690Sstevel@tonic-gate 	    "usage: ldapaddent [ -cpv ] [ -a authenticationMethod ]\n"
4700Sstevel@tonic-gate 	    "[ -b baseDN ] -D bindDN -w bind_password [ -f file ] database\n\n"
4710Sstevel@tonic-gate 	    "usage: ldapaddent -d [ -cpv ] [ -a authenticationMethod ]\n"
4720Sstevel@tonic-gate 	    "[ -b baseDN ] [ -D bindDN ] [ -w bind_password ] database\n"));
4730Sstevel@tonic-gate 	exit(1);
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate /*
4770Sstevel@tonic-gate  * Determine if the given string is an IP address (IPv4 or IPv6).
4780Sstevel@tonic-gate  * If so, it's converted to the preferred form (rfc2373) and
4790Sstevel@tonic-gate  * *newaddr will point to the new address.
4800Sstevel@tonic-gate  *
4810Sstevel@tonic-gate  * Returns	-2		: inet_ntop error
4820Sstevel@tonic-gate  *		-1		: not an IP address
4830Sstevel@tonic-gate  *		0		: unsupported IP address (future use)
4840Sstevel@tonic-gate  *		AF_INET		: IPv4
4850Sstevel@tonic-gate  *		AF_INET6	: IPv6
4860Sstevel@tonic-gate  */
4870Sstevel@tonic-gate static int
4880Sstevel@tonic-gate check_ipaddr(char *addr, char **newaddr) {
4890Sstevel@tonic-gate 	ipaddr_t	addr_ipv4 = 0;
4900Sstevel@tonic-gate 	in6_addr_t	addr_ipv6;
4910Sstevel@tonic-gate 
4920Sstevel@tonic-gate 	/* IPv6 */
4930Sstevel@tonic-gate 	if (inet_pton(AF_INET6, addr, &addr_ipv6) == 1) {
4940Sstevel@tonic-gate 		if (newaddr == NULL)
4950Sstevel@tonic-gate 			return (AF_INET6);
4960Sstevel@tonic-gate 
4970Sstevel@tonic-gate 		/* Convert IPv4-mapped IPv6 address to IPv4 */
4980Sstevel@tonic-gate 		if (IN6_IS_ADDR_V4MAPPED(&addr_ipv6) ||
4990Sstevel@tonic-gate 					IN6_IS_ADDR_V4COMPAT(&addr_ipv6)) {
5000Sstevel@tonic-gate 			IN6_V4MAPPED_TO_IPADDR(&addr_ipv6, addr_ipv4);
5010Sstevel@tonic-gate 			if ((*newaddr = calloc(1, INET_ADDRSTRLEN)) == NULL) {
5020Sstevel@tonic-gate 				(void) fprintf(stderr,
5030Sstevel@tonic-gate 				    gettext("out of memory\n"));
5040Sstevel@tonic-gate 				exit(1);
5050Sstevel@tonic-gate 			}
5060Sstevel@tonic-gate 			if (inet_ntop(AF_INET, &addr_ipv4, *newaddr,
5070Sstevel@tonic-gate 			    INET_ADDRSTRLEN))
5080Sstevel@tonic-gate 				return (AF_INET6);
5090Sstevel@tonic-gate 			free(*newaddr);
5100Sstevel@tonic-gate 			return (-2);
5110Sstevel@tonic-gate 		}
5120Sstevel@tonic-gate 
5130Sstevel@tonic-gate 		/* Processing general IPv6 addresses */
5140Sstevel@tonic-gate 		if ((*newaddr = calloc(1, INET6_ADDRSTRLEN)) == NULL) {
5150Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
5160Sstevel@tonic-gate 			exit(1);
5170Sstevel@tonic-gate 		}
5180Sstevel@tonic-gate 		if (inet_ntop(AF_INET6, &addr_ipv6, *newaddr, INET6_ADDRSTRLEN))
5190Sstevel@tonic-gate 			return (AF_INET6);
5200Sstevel@tonic-gate 		free(*newaddr);
5210Sstevel@tonic-gate 		return (-2);
5220Sstevel@tonic-gate 	}
5230Sstevel@tonic-gate 
5240Sstevel@tonic-gate 	/* Processing IPv4 addresses of the type d.d.d.d. */
5250Sstevel@tonic-gate 	if (inet_pton(AF_INET, addr, &addr_ipv4) == 1) {
5260Sstevel@tonic-gate 		if (newaddr == NULL)
5270Sstevel@tonic-gate 			return (AF_INET);
5280Sstevel@tonic-gate 		if ((*newaddr = calloc(1, INET_ADDRSTRLEN)) == NULL) {
5290Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
5300Sstevel@tonic-gate 			exit(1);
5310Sstevel@tonic-gate 		}
5320Sstevel@tonic-gate 		if (inet_ntop(AF_INET, &addr_ipv4, *newaddr, INET_ADDRSTRLEN))
5330Sstevel@tonic-gate 			return (AF_INET);
5340Sstevel@tonic-gate 		free(*newaddr);
5350Sstevel@tonic-gate 		return (-2);
5360Sstevel@tonic-gate 	}
5370Sstevel@tonic-gate 
5380Sstevel@tonic-gate 	/* Processing IPv4 addresses d.d.d , d.d and d */
5390Sstevel@tonic-gate 	if (inet_addr(addr) != (in_addr_t)-1) {
5400Sstevel@tonic-gate 		if (newaddr == NULL)
5410Sstevel@tonic-gate 			return (AF_INET);
5420Sstevel@tonic-gate 		if ((*newaddr = strdup(addr)) == NULL) {
5430Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
5440Sstevel@tonic-gate 			exit(1);
5450Sstevel@tonic-gate 		}
5460Sstevel@tonic-gate 		return (AF_INET);
5470Sstevel@tonic-gate 	}
5480Sstevel@tonic-gate 
5490Sstevel@tonic-gate 	return (-1);
5500Sstevel@tonic-gate }
5510Sstevel@tonic-gate 
5520Sstevel@tonic-gate static int
5530Sstevel@tonic-gate genent_hosts(char *line, int (*cback)())
5540Sstevel@tonic-gate {
5550Sstevel@tonic-gate 	char buf[BUFSIZ+1];
5562689Siz202018 	char *t, *comment;
5570Sstevel@tonic-gate 	entry_col ecol[4];
5580Sstevel@tonic-gate 	char *cname, *pref_addr;
5590Sstevel@tonic-gate 	int ctr = 0, retval = 1;
5600Sstevel@tonic-gate 	int rc = GENENT_OK, af;
5610Sstevel@tonic-gate 
5620Sstevel@tonic-gate 	struct hostent  data;
5630Sstevel@tonic-gate 	char *alias;
5640Sstevel@tonic-gate 
5650Sstevel@tonic-gate 	/*
5660Sstevel@tonic-gate 	 * don't clobber our argument
5670Sstevel@tonic-gate 	 */
5680Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
5690Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
5700Sstevel@tonic-gate 		return (GENENT_PARSEERR);
5710Sstevel@tonic-gate 	}
5720Sstevel@tonic-gate 	(void) strcpy(buf, line);
5730Sstevel@tonic-gate 
5740Sstevel@tonic-gate 	/*
5750Sstevel@tonic-gate 	 * clear column data
5760Sstevel@tonic-gate 	 */
5770Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
5780Sstevel@tonic-gate 
5790Sstevel@tonic-gate 	/*
5800Sstevel@tonic-gate 	 * comment (col 3)
5812689Siz202018 	 * All leading spaces will be deleted from the comment
5820Sstevel@tonic-gate 	 */
5832689Siz202018 	ecol[3].ec_value.ec_value_val = "";
5842689Siz202018 	ecol[3].ec_value.ec_value_len = 0;
5852689Siz202018 	comment = t = strchr(buf, '#');
5862689Siz202018 	if (comment) {
5872689Siz202018 		do {
5882689Siz202018 			++comment;
5892689Siz202018 		} while (*comment != '\0' && isspace(*comment));
5902689Siz202018 		if (*comment != '\0') {
5912689Siz202018 			*--comment = '#';
5922689Siz202018 			ecol[3].ec_value.ec_value_val = strdup(comment);
5932689Siz202018 			ecol[3].ec_value.ec_value_len = strlen(comment)+1;
5942689Siz202018 		}
5952689Siz202018 
5962689Siz202018 		*t = '\0';
5970Sstevel@tonic-gate 	}
5980Sstevel@tonic-gate 
5990Sstevel@tonic-gate 	/*
6000Sstevel@tonic-gate 	 * addr(col 2)
6010Sstevel@tonic-gate 	 */
6020Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
6030Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no host");
6040Sstevel@tonic-gate 		return (GENENT_PARSEERR);
6050Sstevel@tonic-gate 	}
6060Sstevel@tonic-gate 
6070Sstevel@tonic-gate 	af = check_ipaddr(t, &pref_addr);
6080Sstevel@tonic-gate 	if (af == -2) {
6090Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "Internal error");
6100Sstevel@tonic-gate 	} else if (af == -1) {
6110Sstevel@tonic-gate 		(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
6120Sstevel@tonic-gate 		    "Invalid IP address: %s", t);
6130Sstevel@tonic-gate 	} else if (flags & F_VERBOSE) {
6140Sstevel@tonic-gate 		if ((strncasecmp(t, pref_addr, strlen(t))) != 0) {
6150Sstevel@tonic-gate 			(void) fprintf(stdout,
6160Sstevel@tonic-gate 			    gettext("IP address %s converted to %s\n"),
6170Sstevel@tonic-gate 			    t, pref_addr);
6180Sstevel@tonic-gate 		}
6190Sstevel@tonic-gate 	}
6200Sstevel@tonic-gate 
6210Sstevel@tonic-gate 	if (af < 0) {
6220Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("%s\n"), parse_err_msg);
6230Sstevel@tonic-gate 		if (continue_onerror == 0)
6240Sstevel@tonic-gate 			return (GENENT_CBERR);
6250Sstevel@tonic-gate 		else
6260Sstevel@tonic-gate 			return (rc);
6270Sstevel@tonic-gate 	}
6280Sstevel@tonic-gate 
6290Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = pref_addr;
6300Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(pref_addr)+1;
6310Sstevel@tonic-gate 
6320Sstevel@tonic-gate 	/*
6330Sstevel@tonic-gate 	 * cname (col 0)
6340Sstevel@tonic-gate 	 */
6350Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
6360Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no cname");
6370Sstevel@tonic-gate 		return (GENENT_PARSEERR);
6380Sstevel@tonic-gate 	}
6390Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
6400Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
6410Sstevel@tonic-gate 	cname = t;
6420Sstevel@tonic-gate 
6430Sstevel@tonic-gate 
6440Sstevel@tonic-gate 	/* build entry */
6450Sstevel@tonic-gate 	if ((data.h_addr_list = (char **)calloc(2, sizeof (char **))) == NULL) {
6460Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
6470Sstevel@tonic-gate 		exit(1);
6480Sstevel@tonic-gate 	}
6490Sstevel@tonic-gate 	data.h_addr_list[0] = strdup(ecol[2].ec_value.ec_value_val);
6500Sstevel@tonic-gate 	data.h_addr_list[1] = NULL;
6510Sstevel@tonic-gate 
6520Sstevel@tonic-gate 	free(pref_addr);
6530Sstevel@tonic-gate 	data.h_name = strdup(ecol[0].ec_value.ec_value_val);
6540Sstevel@tonic-gate 
6550Sstevel@tonic-gate 	/*
6560Sstevel@tonic-gate 	 * name (col 1)
6570Sstevel@tonic-gate 	 */
6580Sstevel@tonic-gate 
6590Sstevel@tonic-gate 	data.h_aliases = NULL;
6600Sstevel@tonic-gate 
6610Sstevel@tonic-gate 	do {
6620Sstevel@tonic-gate 		/*
6630Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
6640Sstevel@tonic-gate 		 */
6650Sstevel@tonic-gate 
6660Sstevel@tonic-gate 		/* This call to AddEntry may move out of the loop */
6670Sstevel@tonic-gate 		/* This is because we have to call the function just once */
6680Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
6690Sstevel@tonic-gate 			continue;
6700Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
6710Sstevel@tonic-gate 			continue;
6720Sstevel@tonic-gate 
6730Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
6740Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
6750Sstevel@tonic-gate 
6760Sstevel@tonic-gate 		ctr++;
6770Sstevel@tonic-gate 		alias = strdup(ecol[1].ec_value.ec_value_val);
6780Sstevel@tonic-gate 		if ((data.h_aliases = (char **)realloc(data.h_aliases,
6790Sstevel@tonic-gate 			ctr * sizeof (char **))) == NULL) {
6800Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
6810Sstevel@tonic-gate 			exit(1);
6820Sstevel@tonic-gate 		}
6830Sstevel@tonic-gate 		data.h_aliases[ctr-1] = alias;
6840Sstevel@tonic-gate 	} while (t = strtok(NULL, " \t"));
6850Sstevel@tonic-gate 
6862689Siz202018 	/*
6872689Siz202018 	 * End the list of all the aliases by NULL
6882689Siz202018 	 * If there is some comment, it will be stored as the last entry
6892689Siz202018 	 * in the list of the host aliases
6902689Siz202018 	 */
6910Sstevel@tonic-gate 	if ((data.h_aliases = (char **)realloc(data.h_aliases,
6922689Siz202018 		(ecol[3].ec_value.ec_value_len != 0 ?
6932689Siz202018 			ctr + 2 : ctr + 1) * sizeof (char **))) == NULL) {
6940Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
6950Sstevel@tonic-gate 		exit(1);
6960Sstevel@tonic-gate 	}
6972689Siz202018 
6982689Siz202018 	if (ecol[3].ec_value.ec_value_len != 0) {
6992689Siz202018 		data.h_aliases[ctr++] = ecol[3].ec_value.ec_value_val;
7002689Siz202018 	}
7010Sstevel@tonic-gate 	data.h_aliases[ctr] = NULL;
7020Sstevel@tonic-gate 
7030Sstevel@tonic-gate 	if (flags & F_VERBOSE)
7040Sstevel@tonic-gate 		(void) fprintf(stdout,
7050Sstevel@tonic-gate 		    gettext("Adding entry : cn=%s+ipHostNumber=%s\n"),
7060Sstevel@tonic-gate 		    data.h_name, data.h_addr_list[0]);
7070Sstevel@tonic-gate 
7080Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
7090Sstevel@tonic-gate 
7102689Siz202018 	if (ecol[3].ec_value.ec_value_len != 0) {
7112689Siz202018 		free(ecol[3].ec_value.ec_value_val);
7122689Siz202018 	}
7132689Siz202018 
7140Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
7150Sstevel@tonic-gate 		if (continue_onerror)
7160Sstevel@tonic-gate 			(void) fprintf(stderr,
7170Sstevel@tonic-gate 				gettext("Entry: cn=%s+ipHostNumber=%s "
7180Sstevel@tonic-gate 					"already Exists -skipping it\n"),
7190Sstevel@tonic-gate 					data.h_name, data.h_addr_list[0]);
7200Sstevel@tonic-gate 		else {
7210Sstevel@tonic-gate 			rc = GENENT_CBERR;
7220Sstevel@tonic-gate 			(void) fprintf(stderr,
7230Sstevel@tonic-gate 				gettext("Entry: cn=%s+ipHostNumber=%s"
7240Sstevel@tonic-gate 					" already Exists\n"),
7250Sstevel@tonic-gate 					data.h_name, data.h_addr_list[0]);
7260Sstevel@tonic-gate 		}
7270Sstevel@tonic-gate 	} else if (retval)
7280Sstevel@tonic-gate 		rc = GENENT_CBERR;
7290Sstevel@tonic-gate 
7300Sstevel@tonic-gate 	free(data.h_name);
7310Sstevel@tonic-gate 	free(data.h_aliases);
7320Sstevel@tonic-gate 	free(data.h_addr_list);
7330Sstevel@tonic-gate 
7340Sstevel@tonic-gate 	return (rc);
7350Sstevel@tonic-gate }
7360Sstevel@tonic-gate 
7370Sstevel@tonic-gate 
7380Sstevel@tonic-gate 
7390Sstevel@tonic-gate static void
7400Sstevel@tonic-gate dump_hosts(ns_ldap_result_t *res)
7410Sstevel@tonic-gate {
7422689Siz202018 	ns_ldap_attr_t	*attrptr = NULL,
7432689Siz202018 			*cn = NULL,
7442689Siz202018 			*iphostnumber = NULL,
7452689Siz202018 			*desc = NULL;
7460Sstevel@tonic-gate 	int		 i, j;
7470Sstevel@tonic-gate 	char		*name; /* host name */
7480Sstevel@tonic-gate 
7490Sstevel@tonic-gate 	if (res == NULL || res->entry == NULL)
7500Sstevel@tonic-gate 		return;
7510Sstevel@tonic-gate 	for (i = 0; i < res->entry->attr_count; i++) {
7520Sstevel@tonic-gate 		attrptr = res->entry->attr_pair[i];
7530Sstevel@tonic-gate 		if (strcasecmp(attrptr->attrname, "cn") == 0)
7540Sstevel@tonic-gate 			cn = attrptr;
7550Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname, "iphostnumber") == 0)
7560Sstevel@tonic-gate 			iphostnumber = attrptr;
7572689Siz202018 		else if (strcasecmp(attrptr->attrname, "description") == 0) {
7582689Siz202018 			desc = attrptr;
7592689Siz202018 		}
7600Sstevel@tonic-gate 	}
7610Sstevel@tonic-gate 	/* sanity check */
7620Sstevel@tonic-gate 	if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
7630Sstevel@tonic-gate 	    iphostnumber == NULL || iphostnumber->attrvalue == NULL ||
7640Sstevel@tonic-gate 	    iphostnumber->attrvalue[0] == NULL)
7650Sstevel@tonic-gate 		return;
7660Sstevel@tonic-gate 
7670Sstevel@tonic-gate 	if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
7680Sstevel@tonic-gate 		return;
7690Sstevel@tonic-gate 
7700Sstevel@tonic-gate 	/* ip host/ipnode number */
7710Sstevel@tonic-gate 	if (strlen(iphostnumber->attrvalue[0]) <= INET_ADDRSTRLEN)
7720Sstevel@tonic-gate 		/* IPV4 or IPV6 but <= NET_ADDRSTRLEN */
7730Sstevel@tonic-gate 		(void) fprintf(stdout, "%-18s", iphostnumber->attrvalue[0]);
7740Sstevel@tonic-gate 	else
7750Sstevel@tonic-gate 		/* IPV6 */
7760Sstevel@tonic-gate 		(void) fprintf(stdout, "%-48s", iphostnumber->attrvalue[0]);
7770Sstevel@tonic-gate 
7780Sstevel@tonic-gate 	/* host/ipnode name */
7790Sstevel@tonic-gate 	(void) fprintf(stdout, "%s ", name);
7800Sstevel@tonic-gate 
7810Sstevel@tonic-gate 	/* aliases */
7820Sstevel@tonic-gate 	for (j = 0; j < cn->value_count; j++) {
7830Sstevel@tonic-gate 		if (cn->attrvalue[j]) {
7840Sstevel@tonic-gate 			if (strcasecmp(name, cn->attrvalue[j]) == 0)
7850Sstevel@tonic-gate 				/* skip host name */
7860Sstevel@tonic-gate 				continue;
7870Sstevel@tonic-gate 			(void) fprintf(stdout, "%s ", cn->attrvalue[j]);
7880Sstevel@tonic-gate 		}
7890Sstevel@tonic-gate 	}
7900Sstevel@tonic-gate 
7912689Siz202018 	/* description */
7922689Siz202018 	if (desc != NULL && desc->attrvalue != NULL &&
7932689Siz202018 	    desc->attrvalue[0] != NULL) {
7942689Siz202018 		(void) fprintf(stdout, "#%s", desc->attrvalue[0]);
7952689Siz202018 	}
7962689Siz202018 
7970Sstevel@tonic-gate 	/* end of line */
7980Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
7990Sstevel@tonic-gate }
8000Sstevel@tonic-gate 
8010Sstevel@tonic-gate /*
8020Sstevel@tonic-gate  * /etc/rpc
8030Sstevel@tonic-gate  */
8040Sstevel@tonic-gate 
8050Sstevel@tonic-gate static int
8060Sstevel@tonic-gate genent_rpc(char *line, int (*cback)())
8070Sstevel@tonic-gate {
8080Sstevel@tonic-gate 	char buf[BUFSIZ+1];
8090Sstevel@tonic-gate 	char *t;
8100Sstevel@tonic-gate 	entry_col ecol[4];
8110Sstevel@tonic-gate 	char *cname;
8120Sstevel@tonic-gate 
8130Sstevel@tonic-gate 	struct rpcent	data;
8140Sstevel@tonic-gate 	char *alias;
8150Sstevel@tonic-gate 	int ctr = 0;
8160Sstevel@tonic-gate 	int retval = 1;
8170Sstevel@tonic-gate 	int rc = GENENT_OK;
8180Sstevel@tonic-gate 
8190Sstevel@tonic-gate 	/*
8200Sstevel@tonic-gate 	 * don't clobber our argument
8210Sstevel@tonic-gate 	 */
8220Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
8230Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
8240Sstevel@tonic-gate 		return (GENENT_PARSEERR);
8250Sstevel@tonic-gate 	}
8260Sstevel@tonic-gate 	(void) strcpy(buf, line);
8270Sstevel@tonic-gate 
8280Sstevel@tonic-gate 	/*
8290Sstevel@tonic-gate 	 * clear column data
8300Sstevel@tonic-gate 	 */
8310Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
8320Sstevel@tonic-gate 
8330Sstevel@tonic-gate 	/*
8340Sstevel@tonic-gate 	 * comment (col 3)
8350Sstevel@tonic-gate 	 */
8360Sstevel@tonic-gate 	t = strchr(buf, '#');
8370Sstevel@tonic-gate 	if (t) {
8380Sstevel@tonic-gate 		*t++ = 0;
8390Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = t;
8400Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = strlen(t)+1;
8410Sstevel@tonic-gate 	} else {
8420Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
8430Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
8440Sstevel@tonic-gate 	}
8450Sstevel@tonic-gate 
8460Sstevel@tonic-gate 	/*
8470Sstevel@tonic-gate 	 * cname(col 0)
8480Sstevel@tonic-gate 	 */
8490Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
8500Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no number");
8510Sstevel@tonic-gate 		return (GENENT_PARSEERR);
8520Sstevel@tonic-gate 	}
8530Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
8540Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
8550Sstevel@tonic-gate 	cname = t;
8560Sstevel@tonic-gate 
8570Sstevel@tonic-gate 	/*
8580Sstevel@tonic-gate 	 * number (col 2)
8590Sstevel@tonic-gate 	 */
8600Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
8610Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no number");
8620Sstevel@tonic-gate 		return (GENENT_PARSEERR);
8630Sstevel@tonic-gate 	}
8640Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
8650Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
8660Sstevel@tonic-gate 
8670Sstevel@tonic-gate 
8680Sstevel@tonic-gate 	/*
8690Sstevel@tonic-gate 	 * build entry
8700Sstevel@tonic-gate 	 */
8710Sstevel@tonic-gate 
8720Sstevel@tonic-gate 	data.r_name = strdup(ecol[0].ec_value.ec_value_val);
8730Sstevel@tonic-gate 	if (ecol[2].ec_value.ec_value_val != NULL &&
8740Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val[0] != '\0') {
8750Sstevel@tonic-gate 
8760Sstevel@tonic-gate 		data.r_number = ascii_to_int(ecol[2].ec_value.ec_value_val);
8770Sstevel@tonic-gate 		if (data.r_number == -1) {
8780Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
8790Sstevel@tonic-gate 			    "invalid program number: %s",
8800Sstevel@tonic-gate 			    ecol[2].ec_value.ec_value_val);
8810Sstevel@tonic-gate 		return (GENENT_PARSEERR);
8820Sstevel@tonic-gate 		}
8830Sstevel@tonic-gate 	} else
8840Sstevel@tonic-gate 		data.r_number = -1;
8850Sstevel@tonic-gate 
8860Sstevel@tonic-gate 	/*
8870Sstevel@tonic-gate 	 * name (col 1)
8880Sstevel@tonic-gate 	 */
8890Sstevel@tonic-gate 	t = cname;
8900Sstevel@tonic-gate 	data.r_aliases = NULL;
8910Sstevel@tonic-gate 	do {
8920Sstevel@tonic-gate 
8930Sstevel@tonic-gate 		/*
8940Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
8950Sstevel@tonic-gate 		 */
8960Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
8970Sstevel@tonic-gate 			continue;
8980Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
8990Sstevel@tonic-gate 			continue;
9000Sstevel@tonic-gate 
9010Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
9020Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
9030Sstevel@tonic-gate 
9040Sstevel@tonic-gate 		ctr++;
9050Sstevel@tonic-gate 		alias = strdup(ecol[1].ec_value.ec_value_val);
9060Sstevel@tonic-gate 		if ((data.r_aliases = (char **)realloc(data.r_aliases,
9070Sstevel@tonic-gate 			ctr * sizeof (char **))) == NULL) {
9080Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
9090Sstevel@tonic-gate 			exit(1);
9100Sstevel@tonic-gate 		}
9110Sstevel@tonic-gate 		data.r_aliases[ctr-1] = alias;
9120Sstevel@tonic-gate 
9130Sstevel@tonic-gate 
9140Sstevel@tonic-gate 		/*
9150Sstevel@tonic-gate 		 * only put comment in canonical entry
9160Sstevel@tonic-gate 		 */
9170Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
9180Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
9190Sstevel@tonic-gate 
9200Sstevel@tonic-gate 	} while (t = strtok(NULL, " \t"));
9210Sstevel@tonic-gate 
9220Sstevel@tonic-gate 	/* End the list of all the aliases by NULL */
9230Sstevel@tonic-gate 	if ((data.r_aliases = (char **)realloc(data.r_aliases,
9240Sstevel@tonic-gate 		(ctr + 1) * sizeof (char **))) == NULL) {
9250Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
9260Sstevel@tonic-gate 		exit(1);
9270Sstevel@tonic-gate 	}
9280Sstevel@tonic-gate 	data.r_aliases[ctr] = NULL;
9290Sstevel@tonic-gate 
9300Sstevel@tonic-gate 	if (flags & F_VERBOSE)
9310Sstevel@tonic-gate 		(void) fprintf(stdout,
9320Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.r_name);
9330Sstevel@tonic-gate 
9340Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
9350Sstevel@tonic-gate 
9360Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
9370Sstevel@tonic-gate 		if (continue_onerror)
9380Sstevel@tonic-gate 			(void) fprintf(stderr,
9390Sstevel@tonic-gate 			gettext("Entry: %s - already Exists, skipping it.\n"),
9400Sstevel@tonic-gate 			data.r_name);
9410Sstevel@tonic-gate 		else {
9420Sstevel@tonic-gate 			rc = GENENT_CBERR;
9430Sstevel@tonic-gate 			(void) fprintf(stderr,
9440Sstevel@tonic-gate 				gettext("Entry: %s - already Exists\n"),
9450Sstevel@tonic-gate 				data.r_name);
9460Sstevel@tonic-gate 		}
9470Sstevel@tonic-gate 	} else if (retval)
9480Sstevel@tonic-gate 		rc = GENENT_CBERR;
9490Sstevel@tonic-gate 
9500Sstevel@tonic-gate 	free(data.r_name);
9510Sstevel@tonic-gate 	free(data.r_aliases);
9520Sstevel@tonic-gate 
9530Sstevel@tonic-gate 	return (rc);
9540Sstevel@tonic-gate }
9550Sstevel@tonic-gate 
9560Sstevel@tonic-gate 
9570Sstevel@tonic-gate 
9580Sstevel@tonic-gate static void
9590Sstevel@tonic-gate dump_rpc(ns_ldap_result_t *res)
9600Sstevel@tonic-gate {
9610Sstevel@tonic-gate 	ns_ldap_attr_t	*attrptr = NULL, *cn = NULL, *rpcnumber = NULL;
9620Sstevel@tonic-gate 	int		 i, j;
9630Sstevel@tonic-gate 	char		*name; /* rpc name */
9640Sstevel@tonic-gate 
9650Sstevel@tonic-gate 	if (res == NULL || res->entry == NULL)
9660Sstevel@tonic-gate 		return;
9670Sstevel@tonic-gate 	for (i = 0; i < res->entry->attr_count; i++) {
9680Sstevel@tonic-gate 		attrptr = res->entry->attr_pair[i];
9690Sstevel@tonic-gate 		if (strcasecmp(attrptr->attrname, "cn") == 0)
9700Sstevel@tonic-gate 			cn = attrptr;
9710Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname, "oncRpcNumber") == 0)
9720Sstevel@tonic-gate 			rpcnumber = attrptr;
9730Sstevel@tonic-gate 	}
9740Sstevel@tonic-gate 	/* sanity check */
9750Sstevel@tonic-gate 	if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
9760Sstevel@tonic-gate 	    rpcnumber == NULL || rpcnumber->attrvalue == NULL ||
9770Sstevel@tonic-gate 	    rpcnumber->attrvalue[0] == NULL)
9780Sstevel@tonic-gate 		return;
9790Sstevel@tonic-gate 
9800Sstevel@tonic-gate 	if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
9810Sstevel@tonic-gate 		return;
9820Sstevel@tonic-gate 
9830Sstevel@tonic-gate 	/* rpc name */
9840Sstevel@tonic-gate 	if (strlen(name) < 8)
9850Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\t\t", name);
9860Sstevel@tonic-gate 	else
9870Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\t", name);
9880Sstevel@tonic-gate 
9890Sstevel@tonic-gate 	/* rpc number */
9900Sstevel@tonic-gate 	(void) fprintf(stdout, "%-8s", rpcnumber->attrvalue[0]);
9910Sstevel@tonic-gate 
9920Sstevel@tonic-gate 
9930Sstevel@tonic-gate 	/* aliases */
9940Sstevel@tonic-gate 	for (j = 0; j < cn->value_count; j++) {
9950Sstevel@tonic-gate 		if (cn->attrvalue[j]) {
9960Sstevel@tonic-gate 			if (strcasecmp(name, cn->attrvalue[j]) == 0)
9970Sstevel@tonic-gate 				/* skip rpc name */
9980Sstevel@tonic-gate 				continue;
9990Sstevel@tonic-gate 			(void) fprintf(stdout, "%s ", cn->attrvalue[j]);
10000Sstevel@tonic-gate 		}
10010Sstevel@tonic-gate 	}
10020Sstevel@tonic-gate 
10030Sstevel@tonic-gate 	/* end of line */
10040Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
10050Sstevel@tonic-gate 
10060Sstevel@tonic-gate }
10070Sstevel@tonic-gate 
10080Sstevel@tonic-gate /*
10090Sstevel@tonic-gate  * /etc/protocols
10100Sstevel@tonic-gate  *
10110Sstevel@tonic-gate  */
10120Sstevel@tonic-gate 
10130Sstevel@tonic-gate static int
10140Sstevel@tonic-gate genent_protocols(char *line, int (*cback)())
10150Sstevel@tonic-gate {
10160Sstevel@tonic-gate 	char buf[BUFSIZ+1];
10170Sstevel@tonic-gate 	char *t;
10180Sstevel@tonic-gate 	entry_col ecol[4];
10190Sstevel@tonic-gate 	char *cname;
10200Sstevel@tonic-gate 
10210Sstevel@tonic-gate 	struct protoent	data;
10220Sstevel@tonic-gate 	char *alias;
10230Sstevel@tonic-gate 	int ctr = 0;
10240Sstevel@tonic-gate 	int retval = 1;
10250Sstevel@tonic-gate 	int rc = GENENT_OK;
10260Sstevel@tonic-gate 
10270Sstevel@tonic-gate 	/*
10280Sstevel@tonic-gate 	 * don't clobber our argument
10290Sstevel@tonic-gate 	 */
10300Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
10310Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
10320Sstevel@tonic-gate 		return (GENENT_PARSEERR);
10330Sstevel@tonic-gate 	}
10340Sstevel@tonic-gate 	(void) strcpy(buf, line);
10350Sstevel@tonic-gate 
10360Sstevel@tonic-gate 	/*
10370Sstevel@tonic-gate 	 * clear column data
10380Sstevel@tonic-gate 	 */
10390Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
10400Sstevel@tonic-gate 
10410Sstevel@tonic-gate 	/*
10420Sstevel@tonic-gate 	 * comment (col 3)
10430Sstevel@tonic-gate 	 */
10440Sstevel@tonic-gate 	t = strchr(buf, '#');
10450Sstevel@tonic-gate 	if (t) {
10460Sstevel@tonic-gate 		*t++ = 0;
10470Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = t;
10480Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = strlen(t)+1;
10490Sstevel@tonic-gate 	} else {
10500Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
10510Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
10520Sstevel@tonic-gate 	}
10530Sstevel@tonic-gate 
10540Sstevel@tonic-gate 	/*
10550Sstevel@tonic-gate 	 * cname(col 0)
10560Sstevel@tonic-gate 	 */
10570Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
10580Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no number");
10590Sstevel@tonic-gate 		return (GENENT_PARSEERR);
10600Sstevel@tonic-gate 	}
10610Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
10620Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
10630Sstevel@tonic-gate 	cname = t;
10640Sstevel@tonic-gate 
10650Sstevel@tonic-gate 	/*
10660Sstevel@tonic-gate 	 * number (col 2)
10670Sstevel@tonic-gate 	 */
10680Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
10690Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no number");
10700Sstevel@tonic-gate 		return (GENENT_PARSEERR);
10710Sstevel@tonic-gate 	}
10720Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
10730Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
10740Sstevel@tonic-gate 
10750Sstevel@tonic-gate 
10760Sstevel@tonic-gate 	/*
10770Sstevel@tonic-gate 	 * build entry
10780Sstevel@tonic-gate 	 */
10790Sstevel@tonic-gate 	data.p_name = strdup(ecol[0].ec_value.ec_value_val);
10800Sstevel@tonic-gate 
10810Sstevel@tonic-gate 	if (ecol[2].ec_value.ec_value_val != NULL &&
10820Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val[0] != '\0') {
10830Sstevel@tonic-gate 
10840Sstevel@tonic-gate 		data.p_proto = ascii_to_int(ecol[2].ec_value.ec_value_val);
10850Sstevel@tonic-gate 		if (data.p_proto == -1) {
10860Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
10870Sstevel@tonic-gate 			    "invalid protocol number: %s",
10880Sstevel@tonic-gate 			    ecol[2].ec_value.ec_value_val);
10890Sstevel@tonic-gate 		return (GENENT_PARSEERR);
10900Sstevel@tonic-gate 		}
10910Sstevel@tonic-gate 	} else
10920Sstevel@tonic-gate 		data.p_proto = -1;
10930Sstevel@tonic-gate 
10940Sstevel@tonic-gate 	/*
10950Sstevel@tonic-gate 	 * name (col 1)
10960Sstevel@tonic-gate 	 */
10970Sstevel@tonic-gate 	t = cname;
10980Sstevel@tonic-gate 	ctr = 0;
10990Sstevel@tonic-gate 	data.p_aliases = NULL;
11000Sstevel@tonic-gate 
11010Sstevel@tonic-gate 	do {
11020Sstevel@tonic-gate 		/*
11030Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
11040Sstevel@tonic-gate 		 */
11050Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
11060Sstevel@tonic-gate 			continue;
11070Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
11080Sstevel@tonic-gate 			continue;
11090Sstevel@tonic-gate 
11100Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
11110Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
11120Sstevel@tonic-gate 
11130Sstevel@tonic-gate 		ctr++;
11140Sstevel@tonic-gate 		alias = strdup(ecol[1].ec_value.ec_value_val);
11150Sstevel@tonic-gate 		if ((data.p_aliases = (char **)realloc(data.p_aliases,
11160Sstevel@tonic-gate 			ctr * sizeof (char **))) == NULL) {
11170Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
11180Sstevel@tonic-gate 			exit(1);
11190Sstevel@tonic-gate 		}
11200Sstevel@tonic-gate 		data.p_aliases[ctr-1] = alias;
11210Sstevel@tonic-gate 
11220Sstevel@tonic-gate 		/*
11230Sstevel@tonic-gate 		 * only put comment in canonical entry
11240Sstevel@tonic-gate 		 */
11250Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
11260Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
11270Sstevel@tonic-gate 
11280Sstevel@tonic-gate 	} while (t = strtok(NULL, " \t"));
11290Sstevel@tonic-gate 
11300Sstevel@tonic-gate 	/* End the list of all the aliases by NULL */
11310Sstevel@tonic-gate 	if ((data.p_aliases = (char **)realloc(data.p_aliases,
11320Sstevel@tonic-gate 		(ctr + 1) * sizeof (char **))) == NULL) {
11330Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
11340Sstevel@tonic-gate 		exit(1);
11350Sstevel@tonic-gate 	}
11360Sstevel@tonic-gate 	data.p_aliases[ctr] = NULL;
11370Sstevel@tonic-gate 
11380Sstevel@tonic-gate 	if (flags & F_VERBOSE)
11390Sstevel@tonic-gate 		(void) fprintf(stdout,
11400Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.p_name);
11410Sstevel@tonic-gate 
11420Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
11430Sstevel@tonic-gate 
11440Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
11450Sstevel@tonic-gate 		if (continue_onerror)
11460Sstevel@tonic-gate 			(void) fprintf(stderr,
11470Sstevel@tonic-gate 			gettext("Entry: %s - already Exists, skipping it.\n"),
11480Sstevel@tonic-gate 			data.p_name);
11490Sstevel@tonic-gate 		else {
11500Sstevel@tonic-gate 			rc = GENENT_CBERR;
11510Sstevel@tonic-gate 			(void) fprintf(stderr,
11520Sstevel@tonic-gate 				gettext("Entry: %s - already Exists\n"),
11530Sstevel@tonic-gate 				data.p_name);
11540Sstevel@tonic-gate 		}
11550Sstevel@tonic-gate 	} else if (retval)
11560Sstevel@tonic-gate 		rc = GENENT_CBERR;
11570Sstevel@tonic-gate 
11580Sstevel@tonic-gate 	free(data.p_name);
11590Sstevel@tonic-gate 	free(data.p_aliases);
11600Sstevel@tonic-gate 
11610Sstevel@tonic-gate 	return (rc);
11620Sstevel@tonic-gate }
11630Sstevel@tonic-gate 
11640Sstevel@tonic-gate 
11650Sstevel@tonic-gate static void
11660Sstevel@tonic-gate dump_protocols(ns_ldap_result_t *res)
11670Sstevel@tonic-gate {
11680Sstevel@tonic-gate 	ns_ldap_attr_t	*attrptr = NULL, *cn = NULL, *protocolnumber = NULL;
11690Sstevel@tonic-gate 	int		 i, j;
11700Sstevel@tonic-gate 	char		*name, *cp;
11710Sstevel@tonic-gate 
11720Sstevel@tonic-gate 	if (res == NULL || res->entry == NULL)
11730Sstevel@tonic-gate 		return;
11740Sstevel@tonic-gate 	for (i = 0; i < res->entry->attr_count; i++) {
11750Sstevel@tonic-gate 		attrptr = res->entry->attr_pair[i];
11760Sstevel@tonic-gate 		if (strcasecmp(attrptr->attrname, "cn") == 0)
11770Sstevel@tonic-gate 			cn = attrptr;
11780Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname, "ipProtocolNumber")
11790Sstevel@tonic-gate 									== 0)
11800Sstevel@tonic-gate 			protocolnumber = attrptr;
11810Sstevel@tonic-gate 	}
11820Sstevel@tonic-gate 	/* sanity check */
11830Sstevel@tonic-gate 	if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
11840Sstevel@tonic-gate 	    protocolnumber == NULL || protocolnumber->attrvalue == NULL ||
11850Sstevel@tonic-gate 	    protocolnumber->attrvalue[0] == NULL)
11860Sstevel@tonic-gate 		return;
11870Sstevel@tonic-gate 
11880Sstevel@tonic-gate 	if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
11890Sstevel@tonic-gate 		return;
11900Sstevel@tonic-gate 
11910Sstevel@tonic-gate 	/* protocol name */
11920Sstevel@tonic-gate 	if (strlen(name) < 8)
11930Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\t\t", name);
11940Sstevel@tonic-gate 	else
11950Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\t", name);
11960Sstevel@tonic-gate 
11970Sstevel@tonic-gate 	/* protocol number */
11980Sstevel@tonic-gate 	(void) fprintf(stdout, "%-16s", protocolnumber->attrvalue[0]);
11990Sstevel@tonic-gate 
12000Sstevel@tonic-gate 	/* aliases */
12010Sstevel@tonic-gate 	for (j = 0; j < cn->value_count; j++) {
12020Sstevel@tonic-gate 		if (cn->attrvalue[j]) {
12030Sstevel@tonic-gate 			if (strcasecmp(name, cn->attrvalue[j]) == 0) {
12040Sstevel@tonic-gate 				if (cn->value_count > 1)
12050Sstevel@tonic-gate 					/* Do not replicate */
12060Sstevel@tonic-gate 					continue;
12070Sstevel@tonic-gate 				/*
12080Sstevel@tonic-gate 				 * Replicate name in uppercase as an aliase
12090Sstevel@tonic-gate 				 */
12100Sstevel@tonic-gate 				for (cp = cn->attrvalue[j]; *cp; cp++)
12110Sstevel@tonic-gate 					*cp = toupper(*cp);
12120Sstevel@tonic-gate 			}
12130Sstevel@tonic-gate 			(void) fprintf(stdout, "%s ", cn->attrvalue[j]);
12140Sstevel@tonic-gate 		}
12150Sstevel@tonic-gate 	}
12160Sstevel@tonic-gate 
12170Sstevel@tonic-gate 	/* end of line */
12180Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
12190Sstevel@tonic-gate 
12200Sstevel@tonic-gate }
12210Sstevel@tonic-gate 
12220Sstevel@tonic-gate 
12230Sstevel@tonic-gate 
12240Sstevel@tonic-gate 
12250Sstevel@tonic-gate 
12260Sstevel@tonic-gate /*
12270Sstevel@tonic-gate  * /etc/networks
12280Sstevel@tonic-gate  *
12290Sstevel@tonic-gate  */
12300Sstevel@tonic-gate 
12310Sstevel@tonic-gate static int
12320Sstevel@tonic-gate genent_networks(char *line, int (*cback)())
12330Sstevel@tonic-gate {
12340Sstevel@tonic-gate 	char buf[BUFSIZ+1];
12350Sstevel@tonic-gate 	char *t;
12360Sstevel@tonic-gate 	entry_col ecol[4];
12370Sstevel@tonic-gate 	char *cname;
12380Sstevel@tonic-gate 
12390Sstevel@tonic-gate 	struct netent	data;
12400Sstevel@tonic-gate 	char *alias;
12410Sstevel@tonic-gate 	int ctr = 0;
12420Sstevel@tonic-gate 	int retval = 1;
12430Sstevel@tonic-gate 	int enet;
12440Sstevel@tonic-gate 	int rc = GENENT_OK;
12450Sstevel@tonic-gate 
12460Sstevel@tonic-gate 	/*
12470Sstevel@tonic-gate 	 * don't clobber our argument
12480Sstevel@tonic-gate 	 */
12490Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
12500Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
12510Sstevel@tonic-gate 		return (GENENT_PARSEERR);
12520Sstevel@tonic-gate 	}
12530Sstevel@tonic-gate 	(void) strcpy(buf, line);
12540Sstevel@tonic-gate 
12550Sstevel@tonic-gate 	/*
12560Sstevel@tonic-gate 	 * clear column data
12570Sstevel@tonic-gate 	 */
12580Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
12590Sstevel@tonic-gate 
12600Sstevel@tonic-gate 	/*
12610Sstevel@tonic-gate 	 * comment (col 3)
12620Sstevel@tonic-gate 	 */
12630Sstevel@tonic-gate 	t = strchr(buf, '#');
12640Sstevel@tonic-gate 	if (t) {
12650Sstevel@tonic-gate 		*t++ = 0;
12660Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = t;
12670Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = strlen(t)+1;
12680Sstevel@tonic-gate 	} else {
12690Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
12700Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
12710Sstevel@tonic-gate 	}
12720Sstevel@tonic-gate 
12730Sstevel@tonic-gate 	/*
12740Sstevel@tonic-gate 	 * cname(col 0)
12750Sstevel@tonic-gate 	 */
12760Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
12770Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no number");
12780Sstevel@tonic-gate 		return (GENENT_PARSEERR);
12790Sstevel@tonic-gate 	}
12800Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
12810Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
12820Sstevel@tonic-gate 	cname = t;
12830Sstevel@tonic-gate 
12840Sstevel@tonic-gate 	/*
12850Sstevel@tonic-gate 	 * number (col 2)
12860Sstevel@tonic-gate 	 */
12870Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
12880Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no number");
12890Sstevel@tonic-gate 		return (GENENT_PARSEERR);
12900Sstevel@tonic-gate 	}
12910Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
12920Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
12930Sstevel@tonic-gate 
12940Sstevel@tonic-gate 
12950Sstevel@tonic-gate 	/*
12960Sstevel@tonic-gate 	 * build entry
12970Sstevel@tonic-gate 	 */
12980Sstevel@tonic-gate 
12990Sstevel@tonic-gate 	data.n_name = strdup(ecol[0].ec_value.ec_value_val);
13000Sstevel@tonic-gate 	/*
13010Sstevel@tonic-gate 	 * data.n_net is an unsigned field,
13020Sstevel@tonic-gate 	 * assign -1 to it, make no sense.
13030Sstevel@tonic-gate 	 * Use enet here to avoid lint warning.
13040Sstevel@tonic-gate 	 */
13050Sstevel@tonic-gate 	enet = encode_network(ecol[2].ec_value.ec_value_val);
13060Sstevel@tonic-gate 
13070Sstevel@tonic-gate 	if (enet == -1 && continue_onerror == 0) {
13080Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Invalid network number\n"));
13090Sstevel@tonic-gate 		if (continue_onerror == 0)
13100Sstevel@tonic-gate 			return (GENENT_CBERR);
13110Sstevel@tonic-gate 	} else
13120Sstevel@tonic-gate 		data.n_net = enet;
13130Sstevel@tonic-gate 
13140Sstevel@tonic-gate 	/*
13150Sstevel@tonic-gate 	 * name (col 1)
13160Sstevel@tonic-gate 	 */
13170Sstevel@tonic-gate 	t = cname;
13180Sstevel@tonic-gate 	data.n_aliases = NULL;
13190Sstevel@tonic-gate 
13200Sstevel@tonic-gate 	do {
13210Sstevel@tonic-gate 		/*
13220Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
13230Sstevel@tonic-gate 		 */
13240Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
13250Sstevel@tonic-gate 			continue;
13260Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
13270Sstevel@tonic-gate 			continue;
13280Sstevel@tonic-gate 
13290Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
13300Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
13310Sstevel@tonic-gate 
13320Sstevel@tonic-gate 		ctr++;
13330Sstevel@tonic-gate 		alias = strdup(ecol[1].ec_value.ec_value_val);
13340Sstevel@tonic-gate 		if ((data.n_aliases = (char **)realloc(data.n_aliases,
13350Sstevel@tonic-gate 			ctr * sizeof (char **))) == NULL) {
13360Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
13370Sstevel@tonic-gate 			exit(1);
13380Sstevel@tonic-gate 		}
13390Sstevel@tonic-gate 		data.n_aliases[ctr-1] = alias;
13400Sstevel@tonic-gate 
13410Sstevel@tonic-gate 		/*
13420Sstevel@tonic-gate 		 * only put comment in canonical entry
13430Sstevel@tonic-gate 		 */
13440Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
13450Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
13460Sstevel@tonic-gate 
13470Sstevel@tonic-gate 	} while (t = strtok(NULL, " \t"));
13480Sstevel@tonic-gate 
13490Sstevel@tonic-gate 	/* End the list of all the aliases by NULL */
13500Sstevel@tonic-gate 	if ((data.n_aliases = (char **)realloc(data.n_aliases,
13510Sstevel@tonic-gate 		(ctr + 1) * sizeof (char **))) == NULL) {
13520Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
13530Sstevel@tonic-gate 		exit(1);
13540Sstevel@tonic-gate 	}
13550Sstevel@tonic-gate 	data.n_aliases[ctr] = NULL;
13560Sstevel@tonic-gate 
13570Sstevel@tonic-gate 	if (flags & F_VERBOSE)
13580Sstevel@tonic-gate 		(void) fprintf(stdout,
13590Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.n_name);
13600Sstevel@tonic-gate 
13610Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
13620Sstevel@tonic-gate 
13630Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
13640Sstevel@tonic-gate 		if (continue_onerror)
13650Sstevel@tonic-gate 			(void) fprintf(stderr,
13660Sstevel@tonic-gate 			gettext("Entry: %s - already Exists, skipping it.\n"),
13670Sstevel@tonic-gate 			data.n_name);
13680Sstevel@tonic-gate 		else {
13690Sstevel@tonic-gate 			rc = GENENT_CBERR;
13700Sstevel@tonic-gate 			(void) fprintf(stderr,
13710Sstevel@tonic-gate 				gettext("Entry: %s - already Exists\n"),
13720Sstevel@tonic-gate 				data.n_name);
13730Sstevel@tonic-gate 		}
13740Sstevel@tonic-gate 	} else if (retval)
13750Sstevel@tonic-gate 		rc = GENENT_CBERR;
13760Sstevel@tonic-gate 
13770Sstevel@tonic-gate 	free(data.n_name);
13780Sstevel@tonic-gate 	free(data.n_aliases);
13790Sstevel@tonic-gate 
13800Sstevel@tonic-gate 	return (rc);
13810Sstevel@tonic-gate }
13820Sstevel@tonic-gate 
13830Sstevel@tonic-gate 
13840Sstevel@tonic-gate static void
13850Sstevel@tonic-gate dump_networks(ns_ldap_result_t *res)
13860Sstevel@tonic-gate {
13870Sstevel@tonic-gate 	ns_ldap_attr_t	*attrptr = NULL, *cn = NULL, *networknumber = NULL;
13880Sstevel@tonic-gate 	int		 i, j;
13890Sstevel@tonic-gate 	char		*name;
13900Sstevel@tonic-gate 
13910Sstevel@tonic-gate 	if (res == NULL || res->entry == NULL)
13920Sstevel@tonic-gate 		return;
13930Sstevel@tonic-gate 	for (i = 0; i < res->entry->attr_count; i++) {
13940Sstevel@tonic-gate 		attrptr = res->entry->attr_pair[i];
13950Sstevel@tonic-gate 		if (strcasecmp(attrptr->attrname, "cn") == 0)
13960Sstevel@tonic-gate 			cn = attrptr;
13970Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname, "ipNetworkNumber")
13980Sstevel@tonic-gate 									== 0)
13990Sstevel@tonic-gate 			networknumber = attrptr;
14000Sstevel@tonic-gate 	}
14010Sstevel@tonic-gate 	/* sanity check */
14020Sstevel@tonic-gate 	if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
14030Sstevel@tonic-gate 	    networknumber == NULL || networknumber->attrvalue == NULL ||
14040Sstevel@tonic-gate 	    networknumber->attrvalue[0] == NULL)
14050Sstevel@tonic-gate 		return;
14060Sstevel@tonic-gate 
14070Sstevel@tonic-gate 	/*
14080Sstevel@tonic-gate 	 * cn can be a MUST attribute(RFC 2307) or MAY attribute(2307bis).
14090Sstevel@tonic-gate 	 * If the canonical name can not be found (2307bis), use the 1st
14100Sstevel@tonic-gate 	 * value as the official name.
14110Sstevel@tonic-gate 	 */
14120Sstevel@tonic-gate 
14130Sstevel@tonic-gate 	/* network name */
14140Sstevel@tonic-gate 	if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
14150Sstevel@tonic-gate 		name = cn->attrvalue[0];
14160Sstevel@tonic-gate 
14170Sstevel@tonic-gate 	if (strlen(name) < 8)
14180Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\t\t", name);
14190Sstevel@tonic-gate 	else
14200Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\t", name);
14210Sstevel@tonic-gate 
14220Sstevel@tonic-gate 	/* network number */
14230Sstevel@tonic-gate 	(void) fprintf(stdout, "%-16s", networknumber->attrvalue[0]);
14240Sstevel@tonic-gate 
14250Sstevel@tonic-gate 	/* aliases */
14260Sstevel@tonic-gate 	for (j = 0; j < cn->value_count; j++) {
14270Sstevel@tonic-gate 		if (cn->attrvalue[j]) {
14280Sstevel@tonic-gate 			if (strcasecmp(name, cn->attrvalue[j]) == 0)
14290Sstevel@tonic-gate 				/* skip name */
14300Sstevel@tonic-gate 				continue;
14310Sstevel@tonic-gate 			(void) fprintf(stdout, "%s ", cn->attrvalue[j]);
14320Sstevel@tonic-gate 		}
14330Sstevel@tonic-gate 	}
14340Sstevel@tonic-gate 
14350Sstevel@tonic-gate 	/* end of line */
14360Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
14370Sstevel@tonic-gate 
14380Sstevel@tonic-gate }
14390Sstevel@tonic-gate 
14400Sstevel@tonic-gate 
14410Sstevel@tonic-gate 
14420Sstevel@tonic-gate 
14430Sstevel@tonic-gate /*
14440Sstevel@tonic-gate  * /etc/services
14450Sstevel@tonic-gate  *
14460Sstevel@tonic-gate  */
14470Sstevel@tonic-gate 
14480Sstevel@tonic-gate static int
14490Sstevel@tonic-gate genent_services(char *line, int (*cback)())
14500Sstevel@tonic-gate {
14510Sstevel@tonic-gate 	char buf[BUFSIZ+1];
14520Sstevel@tonic-gate 	char *t, *p;
14530Sstevel@tonic-gate 	entry_col ecol[5];
14540Sstevel@tonic-gate 	char *cname;
14550Sstevel@tonic-gate 
14560Sstevel@tonic-gate 	struct servent	data;
14570Sstevel@tonic-gate 	char *alias;
14580Sstevel@tonic-gate 	int ctr = 0;
14590Sstevel@tonic-gate 	int retval = 1;
14600Sstevel@tonic-gate 	int rc = GENENT_OK;
14610Sstevel@tonic-gate 
14620Sstevel@tonic-gate 	/*
14630Sstevel@tonic-gate 	 * don't clobber our argument
14640Sstevel@tonic-gate 	 */
14650Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
14660Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
14670Sstevel@tonic-gate 		return (GENENT_PARSEERR);
14680Sstevel@tonic-gate 	}
14690Sstevel@tonic-gate 	(void) strcpy(buf, line);
14700Sstevel@tonic-gate 
14710Sstevel@tonic-gate 	/*
14720Sstevel@tonic-gate 	 * clear column data
14730Sstevel@tonic-gate 	 */
14740Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
14750Sstevel@tonic-gate 
14760Sstevel@tonic-gate 	/*
14770Sstevel@tonic-gate 	 * comment (col 4)
14780Sstevel@tonic-gate 	 */
14790Sstevel@tonic-gate 	t = strchr(buf, '#');
14800Sstevel@tonic-gate 	if (t) {
14810Sstevel@tonic-gate 		*t++ = 0;
14820Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_val = t;
14830Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_len = strlen(t)+1;
14840Sstevel@tonic-gate 	} else {
14850Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_val = 0;
14860Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_len = 0;
14870Sstevel@tonic-gate 	}
14880Sstevel@tonic-gate 
14890Sstevel@tonic-gate 	/*
14900Sstevel@tonic-gate 	 * cname(col 0)
14910Sstevel@tonic-gate 	 */
14920Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
14930Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no port");
14940Sstevel@tonic-gate 		return (GENENT_PARSEERR);
14950Sstevel@tonic-gate 	}
14960Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
14970Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
14980Sstevel@tonic-gate 	cname = t;
14990Sstevel@tonic-gate 
15000Sstevel@tonic-gate 	/*
15010Sstevel@tonic-gate 	 * port (col 3)
15020Sstevel@tonic-gate 	 */
15030Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
15040Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no protocol");
15050Sstevel@tonic-gate 		return (GENENT_PARSEERR);
15060Sstevel@tonic-gate 	}
15070Sstevel@tonic-gate 	if ((p = strchr(t, '/')) == 0) {
15080Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "bad port/proto");
15090Sstevel@tonic-gate 		return (GENENT_PARSEERR);
15100Sstevel@tonic-gate 	}
15110Sstevel@tonic-gate 	*(p++) = 0;
15120Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_val = t;
15130Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_len = strlen(t)+1;
15140Sstevel@tonic-gate 
15150Sstevel@tonic-gate 	/*
15160Sstevel@tonic-gate 	 * proto (col 2)
15170Sstevel@tonic-gate 	 */
15180Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = p;
15190Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(p)+1;
15200Sstevel@tonic-gate 
15210Sstevel@tonic-gate 
15220Sstevel@tonic-gate 	/*
15230Sstevel@tonic-gate 	 * build entry
15240Sstevel@tonic-gate 	 */
15250Sstevel@tonic-gate 
15260Sstevel@tonic-gate 	data.s_name = strdup(ecol[0].ec_value.ec_value_val);
15270Sstevel@tonic-gate 	data.s_proto = strdup(ecol[2].ec_value.ec_value_val);
15280Sstevel@tonic-gate 
15290Sstevel@tonic-gate 	if (ecol[3].ec_value.ec_value_val != NULL &&
15300Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val[0] != '\0') {
15310Sstevel@tonic-gate 
15320Sstevel@tonic-gate 		data.s_port = ascii_to_int(ecol[3].ec_value.ec_value_val);
15330Sstevel@tonic-gate 		if (data.s_port == -1) {
15340Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
15350Sstevel@tonic-gate 			    "invalid port number: %s",
15360Sstevel@tonic-gate 			    ecol[3].ec_value.ec_value_val);
15370Sstevel@tonic-gate 		return (GENENT_PARSEERR);
15380Sstevel@tonic-gate 		}
15390Sstevel@tonic-gate 	} else
15400Sstevel@tonic-gate 		data.s_port = -1;
15410Sstevel@tonic-gate 
15420Sstevel@tonic-gate 	/*
15430Sstevel@tonic-gate 	 * name (col 1)
15440Sstevel@tonic-gate 	 */
15450Sstevel@tonic-gate 	t = cname;
15460Sstevel@tonic-gate 	data.s_aliases = NULL;
15470Sstevel@tonic-gate 
15480Sstevel@tonic-gate 	do {
15490Sstevel@tonic-gate 		/*
15500Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
15510Sstevel@tonic-gate 		 */
15520Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
15530Sstevel@tonic-gate 			continue;
15540Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
15550Sstevel@tonic-gate 			continue;
15560Sstevel@tonic-gate 
15570Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
15580Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
15590Sstevel@tonic-gate 
15600Sstevel@tonic-gate 		ctr++;
15610Sstevel@tonic-gate 		alias = strdup(ecol[1].ec_value.ec_value_val);
15620Sstevel@tonic-gate 		if ((data.s_aliases = (char **)realloc(data.s_aliases,
15630Sstevel@tonic-gate 			ctr * sizeof (char **))) == NULL) {
15640Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
15650Sstevel@tonic-gate 			exit(1);
15660Sstevel@tonic-gate 		}
15670Sstevel@tonic-gate 		data.s_aliases[ctr-1] = alias;
15680Sstevel@tonic-gate 
15690Sstevel@tonic-gate 		/*
15700Sstevel@tonic-gate 		 * only put comment in canonical entry
15710Sstevel@tonic-gate 		 */
15720Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_val = 0;
15730Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_len = 0;
15740Sstevel@tonic-gate 
15750Sstevel@tonic-gate 	} while (t = strtok(NULL, " \t"));
15760Sstevel@tonic-gate 
15770Sstevel@tonic-gate 	/* End the list of all the aliases by NULL */
15780Sstevel@tonic-gate 	if ((data.s_aliases = (char **)realloc(data.s_aliases,
15790Sstevel@tonic-gate 		(ctr + 1) * sizeof (char **))) == NULL) {
15800Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
15810Sstevel@tonic-gate 		exit(1);
15820Sstevel@tonic-gate 	}
15830Sstevel@tonic-gate 	data.s_aliases[ctr] = NULL;
15840Sstevel@tonic-gate 
15850Sstevel@tonic-gate 	if (flags & F_VERBOSE)
15860Sstevel@tonic-gate 		(void) fprintf(stdout,
15870Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), line);
15880Sstevel@tonic-gate 
15890Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
15900Sstevel@tonic-gate 
15910Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
15920Sstevel@tonic-gate 		if (continue_onerror)
15930Sstevel@tonic-gate 			(void) fprintf(stderr, gettext(
15940Sstevel@tonic-gate 					"Entry: cn=%s+ipServiceProtocol=%s"
15950Sstevel@tonic-gate 					" already Exists, skipping it.\n"),
15960Sstevel@tonic-gate 					data.s_name, data.s_proto);
15970Sstevel@tonic-gate 		else {
15980Sstevel@tonic-gate 			rc = GENENT_CBERR;
15990Sstevel@tonic-gate 			(void) fprintf(stderr,
16000Sstevel@tonic-gate 				gettext("Entry: cn=%s+ipServiceProtocol=%s"
16010Sstevel@tonic-gate 					" - already Exists\n"),
16020Sstevel@tonic-gate 					data.s_name, data.s_proto);
16030Sstevel@tonic-gate 		}
16040Sstevel@tonic-gate 	} else if (retval)
16050Sstevel@tonic-gate 		rc = GENENT_CBERR;
16060Sstevel@tonic-gate 
16070Sstevel@tonic-gate 	free(data.s_name);
16080Sstevel@tonic-gate 	free(data.s_proto);
16090Sstevel@tonic-gate 	free(data.s_aliases);
16100Sstevel@tonic-gate 
16110Sstevel@tonic-gate 	return (rc);
16120Sstevel@tonic-gate }
16130Sstevel@tonic-gate 
16140Sstevel@tonic-gate 
16150Sstevel@tonic-gate 
16160Sstevel@tonic-gate static void
16170Sstevel@tonic-gate dump_services(ns_ldap_result_t *res)
16180Sstevel@tonic-gate {
16190Sstevel@tonic-gate 	ns_ldap_attr_t	*attrptr = NULL, *cn = NULL, *port = NULL;
16200Sstevel@tonic-gate 	ns_ldap_attr_t	*protocol = NULL;
16210Sstevel@tonic-gate 	int		i, j, len;
16220Sstevel@tonic-gate 	char		*name; /* service name */
16230Sstevel@tonic-gate 
16240Sstevel@tonic-gate 	/*
16250Sstevel@tonic-gate 	 * cn can have multiple values.(service name and its aliases)
16260Sstevel@tonic-gate 	 * In order to support RFC 2307, section 5.5, ipserviceprotocol  can
16270Sstevel@tonic-gate 	 * have multiple values too.
16280Sstevel@tonic-gate 	 * The output format should look like
16290Sstevel@tonic-gate 	 *
16300Sstevel@tonic-gate 	 * test		2345/udp mytest
16310Sstevel@tonic-gate 	 * test		2345/tcp mytest
16320Sstevel@tonic-gate 	 */
16330Sstevel@tonic-gate 	if (res == NULL || res->entry == NULL)
16340Sstevel@tonic-gate 		return;
16350Sstevel@tonic-gate 	for (i = 0; i < res->entry->attr_count; i++) {
16360Sstevel@tonic-gate 		attrptr = res->entry->attr_pair[i];
16370Sstevel@tonic-gate 		if (strcasecmp(attrptr->attrname, "cn") == 0)
16380Sstevel@tonic-gate 			cn = attrptr;
16390Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname, "ipServicePort") == 0)
16400Sstevel@tonic-gate 			port = attrptr;
16410Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname,
16420Sstevel@tonic-gate 					"ipServiceProtocol") == 0)
16430Sstevel@tonic-gate 			protocol = attrptr;
16440Sstevel@tonic-gate 	}
16450Sstevel@tonic-gate 	/* sanity check */
16460Sstevel@tonic-gate 	if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
16470Sstevel@tonic-gate 	    port == NULL || port->attrvalue == NULL ||
16480Sstevel@tonic-gate 	    port->attrvalue[0] == NULL || protocol == NULL ||
16490Sstevel@tonic-gate 	    protocol->attrvalue == NULL || protocol->attrvalue[0] == NULL)
16500Sstevel@tonic-gate 		return;
16510Sstevel@tonic-gate 
16520Sstevel@tonic-gate 	if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
16530Sstevel@tonic-gate 		return;
16540Sstevel@tonic-gate 	for (i = 0; i < protocol->value_count; i++) {
16550Sstevel@tonic-gate 		if (protocol->attrvalue[i] == NULL)
16560Sstevel@tonic-gate 			return;
16570Sstevel@tonic-gate 		/* service name */
16580Sstevel@tonic-gate 		(void) fprintf(stdout, "%-16s", name);
16590Sstevel@tonic-gate 
16600Sstevel@tonic-gate 		/* port & protocol */
16610Sstevel@tonic-gate 		(void) fprintf(stdout, "%s/%s%n", port->attrvalue[0],
16620Sstevel@tonic-gate 				protocol->attrvalue[i], &len);
16630Sstevel@tonic-gate 
16640Sstevel@tonic-gate 		if (len < 8)
16650Sstevel@tonic-gate 			(void) fprintf(stdout, "\t\t");
16660Sstevel@tonic-gate 		else
16670Sstevel@tonic-gate 			(void) fprintf(stdout, "\t");
16680Sstevel@tonic-gate 
16690Sstevel@tonic-gate 		/* aliases */
16700Sstevel@tonic-gate 		for (j = 0; j < cn->value_count; j++) {
16710Sstevel@tonic-gate 			if (cn->attrvalue[j]) {
16720Sstevel@tonic-gate 				if (strcasecmp(name, cn->attrvalue[j]) == 0)
16730Sstevel@tonic-gate 					/* skip service name */
16740Sstevel@tonic-gate 					continue;
16750Sstevel@tonic-gate 				(void) fprintf(stdout, "%s ", cn->attrvalue[j]);
16760Sstevel@tonic-gate 			}
16770Sstevel@tonic-gate 		}
16780Sstevel@tonic-gate 
16790Sstevel@tonic-gate 		/* end of line */
16800Sstevel@tonic-gate 		(void) fprintf(stdout, "\n");
16810Sstevel@tonic-gate 	}
16820Sstevel@tonic-gate }
16830Sstevel@tonic-gate 
16840Sstevel@tonic-gate 
16850Sstevel@tonic-gate /*
16860Sstevel@tonic-gate  * /etc/group
16870Sstevel@tonic-gate  */
16880Sstevel@tonic-gate 
16890Sstevel@tonic-gate static int
16900Sstevel@tonic-gate genent_group(char *line, int (*cback)())
16910Sstevel@tonic-gate {
16920Sstevel@tonic-gate 	char buf[BIGBUF+1];
16930Sstevel@tonic-gate 	char *s, *t;
16940Sstevel@tonic-gate 	entry_col ecol[5];
16950Sstevel@tonic-gate 
16960Sstevel@tonic-gate 	struct group	data;
16970Sstevel@tonic-gate 	int ctr = 0;
16980Sstevel@tonic-gate 	int retval = 1;
16990Sstevel@tonic-gate 	int rc = GENENT_OK;
17000Sstevel@tonic-gate 
17010Sstevel@tonic-gate 	/*
17020Sstevel@tonic-gate 	 * don't clobber our argument
17030Sstevel@tonic-gate 	 */
17040Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
17050Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
17060Sstevel@tonic-gate 		return (GENENT_PARSEERR);
17070Sstevel@tonic-gate 	}
17080Sstevel@tonic-gate 	(void) strcpy(buf, line);
17090Sstevel@tonic-gate 	t = buf;
17100Sstevel@tonic-gate 
17110Sstevel@tonic-gate 	/* ignore empty entries */
17120Sstevel@tonic-gate 	if (*t == '\0')
17130Sstevel@tonic-gate 		return (GENENT_OK);
17140Sstevel@tonic-gate 
17150Sstevel@tonic-gate 	/*
17160Sstevel@tonic-gate 	 * clear column data
17170Sstevel@tonic-gate 	 */
17180Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
17190Sstevel@tonic-gate 
17200Sstevel@tonic-gate 	/*
17210Sstevel@tonic-gate 	 * name (col 0)
17220Sstevel@tonic-gate 	 */
17230Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
17240Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no passwd");
17250Sstevel@tonic-gate 		return (GENENT_PARSEERR);
17260Sstevel@tonic-gate 	}
17270Sstevel@tonic-gate 	*s++ = 0;
17280Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
17290Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
17300Sstevel@tonic-gate 	t = s;
17310Sstevel@tonic-gate 
17320Sstevel@tonic-gate 	/*
17330Sstevel@tonic-gate 	 * passwd (col 1)
17340Sstevel@tonic-gate 	 */
17350Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
17360Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no gid");
17370Sstevel@tonic-gate 		return (GENENT_PARSEERR);
17380Sstevel@tonic-gate 	}
17390Sstevel@tonic-gate 	*s++ = 0;
17400Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = t;
17410Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_len = strlen(t)+1;
17420Sstevel@tonic-gate 	t = s;
17430Sstevel@tonic-gate 
17440Sstevel@tonic-gate 
17450Sstevel@tonic-gate 	/*
17460Sstevel@tonic-gate 	 * gid (col 2)
17470Sstevel@tonic-gate 	 */
17480Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0 || s == t) {
17490Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no members");
17500Sstevel@tonic-gate 		return (GENENT_PARSEERR);
17510Sstevel@tonic-gate 	}
17520Sstevel@tonic-gate 	*s++ = 0;
17530Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
17540Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
17550Sstevel@tonic-gate 	t = s;
17560Sstevel@tonic-gate 
17570Sstevel@tonic-gate 	/*
17580Sstevel@tonic-gate 	 * members (col 3)
17590Sstevel@tonic-gate 	 */
17600Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_val = t;
17610Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_len = strlen(t)+1;
17620Sstevel@tonic-gate 
17630Sstevel@tonic-gate 
17640Sstevel@tonic-gate 	/*
17650Sstevel@tonic-gate 	 * build entry
17660Sstevel@tonic-gate 	 */
17670Sstevel@tonic-gate 	data.gr_name = strdup(ecol[0].ec_value.ec_value_val);
17680Sstevel@tonic-gate 	data.gr_passwd = strdup(ecol[1].ec_value.ec_value_val);
17690Sstevel@tonic-gate 	if (ecol[2].ec_value.ec_value_val != NULL &&
17700Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val[0] != '\0') {
17710Sstevel@tonic-gate 
17720Sstevel@tonic-gate 		data.gr_gid = ascii_to_int(ecol[2].ec_value.ec_value_val);
17730Sstevel@tonic-gate 		if (data.gr_gid == -1) {
17740Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
17750Sstevel@tonic-gate 			    "invalid group id: %s",
17760Sstevel@tonic-gate 			    ecol[2].ec_value.ec_value_val);
17770Sstevel@tonic-gate 		return (GENENT_PARSEERR);
17780Sstevel@tonic-gate 		}
17790Sstevel@tonic-gate 	} else
17800Sstevel@tonic-gate 		data.gr_gid = -1;
17810Sstevel@tonic-gate 
17820Sstevel@tonic-gate 	data.gr_mem = NULL;
17830Sstevel@tonic-gate 
1784839Smj162486 	/* Compute maximum amount of members */
1785839Smj162486 	s = t;
1786839Smj162486 	while (s = strchr(s, ',')) {
1787839Smj162486 		s++;
1788839Smj162486 		ctr++;
1789839Smj162486 	}
1790839Smj162486 
1791839Smj162486 	/* Allocate memory for all members */
1792839Smj162486 	data.gr_mem = calloc(ctr + 2, sizeof (char **));
1793839Smj162486 	if (data.gr_mem == NULL) {
1794839Smj162486 		(void) fprintf(stderr, gettext("out of memory\n"));
1795839Smj162486 		exit(1);
1796839Smj162486 	}
1797839Smj162486 
1798839Smj162486 	ctr = 0;
17990Sstevel@tonic-gate 	while (s = strchr(t, ',')) {
18000Sstevel@tonic-gate 
18010Sstevel@tonic-gate 		*s++ = 0;
18020Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = t;
18030Sstevel@tonic-gate 		t = s;
1804839Smj162486 		/* Send to server only non empty member names */
1805839Smj162486 		if (strlen(ecol[3].ec_value.ec_value_val) != 0)
1806839Smj162486 			data.gr_mem[ctr++] = ecol[3].ec_value.ec_value_val;
18070Sstevel@tonic-gate 	}
18080Sstevel@tonic-gate 
1809839Smj162486 	/* Send to server only non empty member names */
1810839Smj162486 	if (strlen(t) != 0)
1811839Smj162486 		data.gr_mem[ctr++] = t;
1812839Smj162486 
1813839Smj162486 	/* Array of members completed, finished by NULL, see calloc() */
18140Sstevel@tonic-gate 
18150Sstevel@tonic-gate 	if (flags & F_VERBOSE)
18160Sstevel@tonic-gate 		(void) fprintf(stdout,
18170Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.gr_name);
18180Sstevel@tonic-gate 
18190Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
18200Sstevel@tonic-gate 
18210Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
18220Sstevel@tonic-gate 		if (continue_onerror)
18230Sstevel@tonic-gate 			(void) fprintf(stderr,
18240Sstevel@tonic-gate 			gettext("Entry: %s - already Exists, skipping it.\n"),
18250Sstevel@tonic-gate 			data.gr_name);
18260Sstevel@tonic-gate 		else {
18270Sstevel@tonic-gate 			rc = GENENT_CBERR;
18280Sstevel@tonic-gate 			(void) fprintf(stderr,
18290Sstevel@tonic-gate 				gettext("Entry: %s - already Exists\n"),
18300Sstevel@tonic-gate 				data.gr_name);
18310Sstevel@tonic-gate 		}
18320Sstevel@tonic-gate 	} else if (retval)
18330Sstevel@tonic-gate 		rc = GENENT_CBERR;
18340Sstevel@tonic-gate 
18350Sstevel@tonic-gate 	free(data.gr_name);
18360Sstevel@tonic-gate 	free(data.gr_passwd);
18370Sstevel@tonic-gate 	free(data.gr_mem);
18380Sstevel@tonic-gate 
18390Sstevel@tonic-gate 	return (rc);
18400Sstevel@tonic-gate }
18410Sstevel@tonic-gate 
18420Sstevel@tonic-gate static void
18430Sstevel@tonic-gate dump_group(ns_ldap_result_t *res)
18440Sstevel@tonic-gate {
18450Sstevel@tonic-gate 	char    **value = NULL;
18460Sstevel@tonic-gate 	char	pnam[256];
18470Sstevel@tonic-gate 	int	attr_count = 0;
18480Sstevel@tonic-gate 
18490Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "cn");
18500Sstevel@tonic-gate 	if (value && value[0])
18510Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
18520Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "userPassword");
18530Sstevel@tonic-gate 	if (value == NULL || value[0] == NULL)
18540Sstevel@tonic-gate 		(void) fprintf(stdout, "*:");
18550Sstevel@tonic-gate 	else {
18560Sstevel@tonic-gate 		(void) strcpy(pnam, value[0]);
18570Sstevel@tonic-gate 		if (strncasecmp(value[0], "{crypt}", 7) == 0)
18580Sstevel@tonic-gate 			(void) fprintf(stdout, "%s:", (pnam+7));
18590Sstevel@tonic-gate 		else
18600Sstevel@tonic-gate 			(void) fprintf(stdout, "*:");
18610Sstevel@tonic-gate 	}
18620Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "gidNumber");
18630Sstevel@tonic-gate 	if (value && value[0])
18640Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
18650Sstevel@tonic-gate 
18660Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "memberUid");
18670Sstevel@tonic-gate 	if (value != NULL && value[0] != NULL) {
18680Sstevel@tonic-gate 		while (value[attr_count] != NULL) {
18690Sstevel@tonic-gate 			if (value[attr_count+1] == NULL)
18700Sstevel@tonic-gate 				(void) fprintf(stdout, "%s", value[attr_count]);
18710Sstevel@tonic-gate 			else
18720Sstevel@tonic-gate 				(void) fprintf(stdout, "%s,",
18730Sstevel@tonic-gate 					value[attr_count]);
18740Sstevel@tonic-gate 			attr_count++;
18750Sstevel@tonic-gate 		}
18760Sstevel@tonic-gate 		(void) fprintf(stdout, "\n");
18770Sstevel@tonic-gate 	}
18780Sstevel@tonic-gate 	else
18790Sstevel@tonic-gate 		(void) fprintf(stdout, "\n");
18800Sstevel@tonic-gate }
18810Sstevel@tonic-gate 
18820Sstevel@tonic-gate 
18830Sstevel@tonic-gate 
18840Sstevel@tonic-gate 
18850Sstevel@tonic-gate 
18860Sstevel@tonic-gate /*
18870Sstevel@tonic-gate  * /etc/ethers
18880Sstevel@tonic-gate  */
18890Sstevel@tonic-gate 
18900Sstevel@tonic-gate static int
18910Sstevel@tonic-gate genent_ethers(char *line, int (*cback)())
18920Sstevel@tonic-gate {
18930Sstevel@tonic-gate 	char buf[BUFSIZ+1];
18940Sstevel@tonic-gate 	char *t;
18950Sstevel@tonic-gate 	entry_col ecol[3];
18960Sstevel@tonic-gate 	int retval = 1;
18970Sstevel@tonic-gate 	struct _ns_ethers	data;
18980Sstevel@tonic-gate 	int rc = GENENT_OK;
18990Sstevel@tonic-gate 
19000Sstevel@tonic-gate 	/*
19010Sstevel@tonic-gate 	 * don't clobber our argument
19020Sstevel@tonic-gate 	 */
19030Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
19040Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
19050Sstevel@tonic-gate 		return (GENENT_PARSEERR);
19060Sstevel@tonic-gate 	}
19070Sstevel@tonic-gate 	(void) strcpy(buf, line);
19080Sstevel@tonic-gate 
19090Sstevel@tonic-gate 	/*
19100Sstevel@tonic-gate 	 * clear column data
19110Sstevel@tonic-gate 	 */
19120Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
19130Sstevel@tonic-gate 
19140Sstevel@tonic-gate 	/*
19150Sstevel@tonic-gate 	 * comment (col 2)
19160Sstevel@tonic-gate 	 */
19170Sstevel@tonic-gate 	t = strchr(buf, '#');
19180Sstevel@tonic-gate 	if (t) {
19190Sstevel@tonic-gate 		*t++ = 0;
19200Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val = t;
19210Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_len = strlen(t)+1;
19220Sstevel@tonic-gate 	} else {
19230Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val = 0;
19240Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_len = 0;
19250Sstevel@tonic-gate 	}
19260Sstevel@tonic-gate 
19270Sstevel@tonic-gate 	/*
19280Sstevel@tonic-gate 	 * addr(col 0)
19290Sstevel@tonic-gate 	 */
19300Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
19310Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no name");
19320Sstevel@tonic-gate 		return (GENENT_PARSEERR);
19330Sstevel@tonic-gate 	}
19340Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
19350Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
19360Sstevel@tonic-gate 
19370Sstevel@tonic-gate 	/*
19380Sstevel@tonic-gate 	 * name(col 1)
19390Sstevel@tonic-gate 	 */
19400Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
19410Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no white space allowed in name");
19420Sstevel@tonic-gate 		return (GENENT_PARSEERR);
19430Sstevel@tonic-gate 	}
19440Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = t;
19450Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_len = strlen(t)+1;
19460Sstevel@tonic-gate 
19470Sstevel@tonic-gate 
19480Sstevel@tonic-gate 	/*
19490Sstevel@tonic-gate 	 * build entry
19500Sstevel@tonic-gate 	 */
19510Sstevel@tonic-gate 
19520Sstevel@tonic-gate 	data.ether = strdup(ecol[0].ec_value.ec_value_val);
19530Sstevel@tonic-gate 	data.name  = strdup(ecol[1].ec_value.ec_value_val);
19540Sstevel@tonic-gate 
19550Sstevel@tonic-gate 
19560Sstevel@tonic-gate 	if (flags & F_VERBOSE)
19570Sstevel@tonic-gate 		(void) fprintf(stdout,
19580Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.name);
19590Sstevel@tonic-gate 
19600Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
19610Sstevel@tonic-gate 
19620Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
19630Sstevel@tonic-gate 		if (continue_onerror)
19640Sstevel@tonic-gate 			(void) fprintf(stderr,
19650Sstevel@tonic-gate 			gettext("Entry: %s - already Exists, skipping it.\n"),
19660Sstevel@tonic-gate 			data.name);
19670Sstevel@tonic-gate 		else {
19680Sstevel@tonic-gate 			rc = GENENT_CBERR;
19690Sstevel@tonic-gate 			(void) fprintf(stderr,
19700Sstevel@tonic-gate 				gettext("Entry: %s - already Exists\n"),
19710Sstevel@tonic-gate 				data.name);
19720Sstevel@tonic-gate 		}
19730Sstevel@tonic-gate 	} else if (retval)
19740Sstevel@tonic-gate 		rc = GENENT_CBERR;
19750Sstevel@tonic-gate 
19760Sstevel@tonic-gate 	free(data.ether);
19770Sstevel@tonic-gate 	free(data.name);
19780Sstevel@tonic-gate 
19790Sstevel@tonic-gate 	return (rc);
19800Sstevel@tonic-gate }
19810Sstevel@tonic-gate 
19820Sstevel@tonic-gate 
19830Sstevel@tonic-gate static void
19840Sstevel@tonic-gate dump_ethers(ns_ldap_result_t *res)
19850Sstevel@tonic-gate {
19860Sstevel@tonic-gate 	char	**value = NULL;
19870Sstevel@tonic-gate 
19880Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "macAddress");
19890Sstevel@tonic-gate 	if (value && value[0])
19900Sstevel@tonic-gate 		(void) fprintf(stdout, "%s", value[0]);
19910Sstevel@tonic-gate 	else
19920Sstevel@tonic-gate 		return;
19930Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "cn");
19940Sstevel@tonic-gate 	if (value && value[0])
19950Sstevel@tonic-gate 		(void) fprintf(stdout, "	%s\n", value[0]);
19960Sstevel@tonic-gate }
19970Sstevel@tonic-gate 
19980Sstevel@tonic-gate static int
19990Sstevel@tonic-gate genent_aliases(char *line, int (*cback)())
20000Sstevel@tonic-gate {
20010Sstevel@tonic-gate 	char buf[BUFSIZ+1];
20020Sstevel@tonic-gate 	char *t, *aliases;
20030Sstevel@tonic-gate 	char *cname;
20040Sstevel@tonic-gate 	int ctr = 0;
20050Sstevel@tonic-gate 	int retval = 1;
20060Sstevel@tonic-gate 	int i;
20070Sstevel@tonic-gate 
20080Sstevel@tonic-gate 	struct _ns_alias data;
20090Sstevel@tonic-gate 	char *alias;
20100Sstevel@tonic-gate 	int rc = GENENT_OK;
20110Sstevel@tonic-gate 
20120Sstevel@tonic-gate 	/*
20130Sstevel@tonic-gate 	 * don't clobber our argument
20140Sstevel@tonic-gate 	 */
20150Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
20160Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
20170Sstevel@tonic-gate 		return (GENENT_PARSEERR);
20180Sstevel@tonic-gate 	}
20190Sstevel@tonic-gate 
20200Sstevel@tonic-gate 	(void) strcpy(buf, line);
20210Sstevel@tonic-gate 
20220Sstevel@tonic-gate 	if ((t = strchr(buf, ':')) == 0) {
20230Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no alias name");
20240Sstevel@tonic-gate 		return (GENENT_PARSEERR);
20250Sstevel@tonic-gate 	}
20260Sstevel@tonic-gate 
20270Sstevel@tonic-gate 	t[0] = '\0';
20280Sstevel@tonic-gate 	if (++t == '\0') {
20290Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no alias value");
20300Sstevel@tonic-gate 		return (GENENT_PARSEERR);
20310Sstevel@tonic-gate 	}
20320Sstevel@tonic-gate 
20330Sstevel@tonic-gate 	cname = buf;
20340Sstevel@tonic-gate 	aliases = t;
20350Sstevel@tonic-gate 
20360Sstevel@tonic-gate 	/* build entry */
20370Sstevel@tonic-gate 	data.alias = strdup(cname);
20380Sstevel@tonic-gate 	if (!data.alias) {
20390Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
20400Sstevel@tonic-gate 		exit(1);
20410Sstevel@tonic-gate 	}
20420Sstevel@tonic-gate 
20430Sstevel@tonic-gate 	data.member = NULL;
20440Sstevel@tonic-gate 	t = strtok(aliases, ",");
20450Sstevel@tonic-gate 	do {
20460Sstevel@tonic-gate 		ctr++;
20470Sstevel@tonic-gate 		while (t[0] == ' ')
20480Sstevel@tonic-gate 			t++;
20490Sstevel@tonic-gate 		alias = strdup(t);
20500Sstevel@tonic-gate 		if ((alias == NULL) ||
20510Sstevel@tonic-gate 			((data.member = (char **)realloc(data.member,
20520Sstevel@tonic-gate 			(ctr + 1) * sizeof (char **))) == NULL)) {
20530Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
20540Sstevel@tonic-gate 			exit(1);
20550Sstevel@tonic-gate 		}
20560Sstevel@tonic-gate 		data.member[ctr-1] = alias;
20570Sstevel@tonic-gate 
20580Sstevel@tonic-gate 	} while (t = strtok(NULL, ","));
20590Sstevel@tonic-gate 
20600Sstevel@tonic-gate 	data.member[ctr] = NULL;
20610Sstevel@tonic-gate 
20620Sstevel@tonic-gate 	if (flags & F_VERBOSE)
20630Sstevel@tonic-gate 		(void) fprintf(stdout,
20640Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.alias);
20650Sstevel@tonic-gate 
20660Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
20670Sstevel@tonic-gate 
20680Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
20690Sstevel@tonic-gate 		if (continue_onerror)
20700Sstevel@tonic-gate 			(void) fprintf(stderr,
20710Sstevel@tonic-gate 			gettext("Entry: %s - already Exists, skipping it.\n"),
20720Sstevel@tonic-gate 			data.alias);
20730Sstevel@tonic-gate 		else {
20740Sstevel@tonic-gate 			rc = GENENT_CBERR;
20750Sstevel@tonic-gate 			(void) fprintf(stderr,
20760Sstevel@tonic-gate 				gettext("Entry: %s - already Exists\n"),
20770Sstevel@tonic-gate 				data.alias);
20780Sstevel@tonic-gate 		}
20790Sstevel@tonic-gate 	} else if (retval)
20800Sstevel@tonic-gate 		rc = GENENT_CBERR;
20810Sstevel@tonic-gate 
20820Sstevel@tonic-gate 	free(data.alias);
20830Sstevel@tonic-gate 	i = 0;
20840Sstevel@tonic-gate 	while (data.member[i])
20850Sstevel@tonic-gate 		free(data.member[i++]);
20860Sstevel@tonic-gate 	free(data.member);
20870Sstevel@tonic-gate 
20880Sstevel@tonic-gate 	return (rc);
20890Sstevel@tonic-gate }
20900Sstevel@tonic-gate 
20910Sstevel@tonic-gate 
20920Sstevel@tonic-gate static void
20930Sstevel@tonic-gate dump_aliases(ns_ldap_result_t *res)
20940Sstevel@tonic-gate {
20950Sstevel@tonic-gate 
20960Sstevel@tonic-gate 	char	**value = NULL;
20970Sstevel@tonic-gate 	int 		attr_count = 0;
20980Sstevel@tonic-gate 
20990Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "mail");
21000Sstevel@tonic-gate 	if (value && value[0])
21010Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
21020Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "mgrpRFC822MailMember");
21030Sstevel@tonic-gate 	if (value != NULL)
21040Sstevel@tonic-gate 		while (value[attr_count] != NULL) {
21050Sstevel@tonic-gate 			(void) fprintf(stdout, "%s,", value[attr_count]);
21060Sstevel@tonic-gate 			attr_count++;
21070Sstevel@tonic-gate 		}
21080Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
21090Sstevel@tonic-gate 
21100Sstevel@tonic-gate }
21110Sstevel@tonic-gate 
21120Sstevel@tonic-gate /*
21130Sstevel@tonic-gate  * /etc/publickey
21140Sstevel@tonic-gate  */
21150Sstevel@tonic-gate 
2116*2830Sdjl static char *h_errno2str(int h_errno);
2117*2830Sdjl 
21180Sstevel@tonic-gate static int
21190Sstevel@tonic-gate genent_publickey(char *line, int (*cback)())
21200Sstevel@tonic-gate {
21210Sstevel@tonic-gate 	char buf[BUFSIZ+1], tmpbuf[BUFSIZ+1], cname[BUFSIZ+1];
21220Sstevel@tonic-gate 	char *t, *p, *tmppubkey, *tmpprivkey;
21230Sstevel@tonic-gate 	entry_col ecol[3];
2124*2830Sdjl 	int buflen, uid, retval = 1, errnum = 0;
21250Sstevel@tonic-gate 	struct passwd *pwd;
2126*2830Sdjl 	char auth_type[BUFSIZ+1], *dot;
21270Sstevel@tonic-gate 	keylen_t keylen;
21280Sstevel@tonic-gate 	algtype_t algtype;
21290Sstevel@tonic-gate 	struct _ns_pubkey data;
21300Sstevel@tonic-gate 	struct hostent *hp;
21310Sstevel@tonic-gate 	struct in_addr in;
2132*2830Sdjl 	struct in6_addr in6;
2133*2830Sdjl 	char abuf[INET6_ADDRSTRLEN];
21340Sstevel@tonic-gate 
21350Sstevel@tonic-gate 	/*
21360Sstevel@tonic-gate 	 * don't clobber our argument
21370Sstevel@tonic-gate 	 */
21380Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
21390Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
21400Sstevel@tonic-gate 		return (GENENT_PARSEERR);
21410Sstevel@tonic-gate 	}
21420Sstevel@tonic-gate 	(void) strcpy(buf, line);
21430Sstevel@tonic-gate 
21440Sstevel@tonic-gate 	/*
21450Sstevel@tonic-gate 	 * clear column data
21460Sstevel@tonic-gate 	 */
21470Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
21480Sstevel@tonic-gate 
21490Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
21500Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no cname");
21510Sstevel@tonic-gate 		return (GENENT_PARSEERR);
21520Sstevel@tonic-gate 	}
21530Sstevel@tonic-gate 
21540Sstevel@tonic-gate 	/*
21550Sstevel@tonic-gate 	 * Special case:  /etc/publickey usually has an entry
21560Sstevel@tonic-gate 	 * for principal "nobody".  We skip it.
21570Sstevel@tonic-gate 	 */
21580Sstevel@tonic-gate 	if (strcmp(t, "nobody") == 0)
21590Sstevel@tonic-gate 		return (GENENT_OK);
21600Sstevel@tonic-gate 
21610Sstevel@tonic-gate 	/*
21620Sstevel@tonic-gate 	 * cname (col 0)
21630Sstevel@tonic-gate 	 */
21640Sstevel@tonic-gate 	if (strncmp(t, "unix.", 5)) {
21650Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "bad cname");
21660Sstevel@tonic-gate 		return (GENENT_PARSEERR);
21670Sstevel@tonic-gate 	}
21680Sstevel@tonic-gate 	(void) strcpy(tmpbuf, &(t[5]));
21690Sstevel@tonic-gate 	if ((p = strchr(tmpbuf, '@')) == 0) {
21700Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "bad cname");
21710Sstevel@tonic-gate 		return (GENENT_PARSEERR);
21720Sstevel@tonic-gate 	}
21730Sstevel@tonic-gate 	*(p++) = 0;
21740Sstevel@tonic-gate 	if (isdigit(*tmpbuf)) {
21750Sstevel@tonic-gate 
21760Sstevel@tonic-gate 		uid = atoi(tmpbuf);
21770Sstevel@tonic-gate 		/*
21780Sstevel@tonic-gate 		 * don't generate entries for uids without passwd entries
21790Sstevel@tonic-gate 		 */
21800Sstevel@tonic-gate 		if ((pwd = getpwuid(uid)) == 0) {
21810Sstevel@tonic-gate 			(void) fprintf(stderr,
21820Sstevel@tonic-gate 			gettext("can't map uid %d to username, skipping\n"),
21830Sstevel@tonic-gate 				uid);
21840Sstevel@tonic-gate 			return (GENENT_OK);
21850Sstevel@tonic-gate 		}
21860Sstevel@tonic-gate 		(void) strcpy(cname, pwd->pw_name);
21870Sstevel@tonic-gate 		data.hostcred = NS_HOSTCRED_FALSE;
21880Sstevel@tonic-gate 	} else {
2189*2830Sdjl 		if ((hp = getipnodebyname(tmpbuf, AF_INET6,
2190*2830Sdjl 				AI_ALL | AI_V4MAPPED, &errnum)) == NULL) {
21910Sstevel@tonic-gate 			(void) fprintf(stderr,
2192*2830Sdjl 			gettext("can't map hostname %s to hostaddress, "
2193*2830Sdjl 				"errnum %d %s skipping\n"), tmpbuf, errnum,
2194*2830Sdjl 				h_errno2str(errnum));
21950Sstevel@tonic-gate 			return (GENENT_OK);
21960Sstevel@tonic-gate 		}
2197*2830Sdjl 		(void) memcpy((char *)&in6.s6_addr, hp->h_addr_list[0],
2198*2830Sdjl 				hp->h_length);
2199*2830Sdjl 		if (IN6_IS_ADDR_V4MAPPED(&in6) ||
2200*2830Sdjl 					IN6_IS_ADDR_V4COMPAT(&in6)) {
2201*2830Sdjl 			IN6_V4MAPPED_TO_INADDR(&in6, &in);
2202*2830Sdjl 			if (inet_ntop(AF_INET, (const void *)&in, abuf,
2203*2830Sdjl 					INET6_ADDRSTRLEN) == NULL) {
2204*2830Sdjl 				(void) fprintf(stderr,
2205*2830Sdjl 					gettext("can't convert IPV4 address of"
2206*2830Sdjl 						" hostname %s to string, "
2207*2830Sdjl 						"skipping\n"), tmpbuf);
2208*2830Sdjl 					return (GENENT_OK);
2209*2830Sdjl 			}
2210*2830Sdjl 		} else {
2211*2830Sdjl 			if (inet_ntop(AF_INET6, (const void *)&in6, abuf,
2212*2830Sdjl 					INET6_ADDRSTRLEN) == NULL) {
2213*2830Sdjl 				(void) fprintf(stderr,
2214*2830Sdjl 					gettext("can't convert IPV6 address of"
2215*2830Sdjl 						" hostname %s to string, "
2216*2830Sdjl 						"skipping\n"), tmpbuf);
2217*2830Sdjl 					return (GENENT_OK);
2218*2830Sdjl 			}
2219*2830Sdjl 		}
22200Sstevel@tonic-gate 		data.hostcred = NS_HOSTCRED_TRUE;
2221*2830Sdjl 		/*
2222*2830Sdjl 		 * tmpbuf could be an alias, use hp->h_name instead.
2223*2830Sdjl 		 * hp->h_name is in FQDN format, so extract 1st field.
2224*2830Sdjl 		 */
2225*2830Sdjl 		if ((dot = strchr(hp->h_name, '.')) != NULL)
2226*2830Sdjl 			*dot = '\0';
22270Sstevel@tonic-gate 		(void) snprintf(cname, sizeof (cname),
2228*2830Sdjl 		    "%s+ipHostNumber=%s", hp->h_name, abuf);
2229*2830Sdjl 		if (dot)
2230*2830Sdjl 			*dot = '.';
22310Sstevel@tonic-gate 	}
22320Sstevel@tonic-gate 
22330Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = cname;
22340Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(cname)+1;
22350Sstevel@tonic-gate 
22360Sstevel@tonic-gate 	/*
22370Sstevel@tonic-gate 	 * public_data (col 1)
22380Sstevel@tonic-gate 	 */
22390Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
22400Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no private_data");
22410Sstevel@tonic-gate 		return (GENENT_PARSEERR);
22420Sstevel@tonic-gate 	}
22430Sstevel@tonic-gate 	if ((p = strchr(t, ':')) == 0) {
22440Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "bad public_data");
22450Sstevel@tonic-gate 		return (GENENT_PARSEERR);
22460Sstevel@tonic-gate 	}
22470Sstevel@tonic-gate 	*(p++) = 0;
22480Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = t;
22490Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_len = strlen(t)+1;
22500Sstevel@tonic-gate 	keylen = (strlen(t) / 2) * 8;
22510Sstevel@tonic-gate 
22520Sstevel@tonic-gate 	/*
22530Sstevel@tonic-gate 	 * private_data (col 2) and algtype extraction
22540Sstevel@tonic-gate 	 */
22550Sstevel@tonic-gate 	if (*p == ':')
22560Sstevel@tonic-gate 		p++;
22570Sstevel@tonic-gate 	t = p;
22580Sstevel@tonic-gate 	if (!(t = strchr(t, ':'))) {
22590Sstevel@tonic-gate 		(void) fprintf(stderr,
22600Sstevel@tonic-gate 		gettext("WARNING: No algorithm type data found "
22610Sstevel@tonic-gate 			"in publickey file, assuming 0\n"));
22620Sstevel@tonic-gate 		algtype = 0;
22630Sstevel@tonic-gate 	} else {
22640Sstevel@tonic-gate 		*t = '\0';
22650Sstevel@tonic-gate 		t++;
22660Sstevel@tonic-gate 		algtype = atoi(t);
22670Sstevel@tonic-gate 	}
22680Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = p;
22690Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(p)+1;
22700Sstevel@tonic-gate 
22710Sstevel@tonic-gate 	/*
22720Sstevel@tonic-gate 	 * auth_type (col 1)
22730Sstevel@tonic-gate 	 */
2274*2830Sdjl 	if (AUTH_DES_KEY(keylen, algtype))
2275*2830Sdjl 		/*
2276*2830Sdjl 		 * {DES} and {DH192-0} means same thing.
2277*2830Sdjl 		 * However, nisplus uses "DES" and ldap uses "DH192-0"
2278*2830Sdjl 		 * internally.
2279*2830Sdjl 		 * See newkey(1M), __nis_mechalias2authtype() which is
2280*2830Sdjl 		 * called by __nis_keyalg2authtype() and getkey_ldap_g()
2281*2830Sdjl 		 */
2282*2830Sdjl 		(void) strlcpy(auth_type, "DH192-0", BUFSIZ+1);
2283*2830Sdjl 	else if (!(__nis_keyalg2authtype(keylen, algtype, auth_type,
22840Sstevel@tonic-gate 						MECH_MAXATNAME))) {
22850Sstevel@tonic-gate 		(void) fprintf(stderr,
22860Sstevel@tonic-gate 		gettext("Could not convert algorithm type to "
22870Sstevel@tonic-gate 			"corresponding auth type string\n"));
22880Sstevel@tonic-gate 		return (GENENT_ERR);
22890Sstevel@tonic-gate 	}
22900Sstevel@tonic-gate 
22910Sstevel@tonic-gate 	/*
22920Sstevel@tonic-gate 	 * build entry
22930Sstevel@tonic-gate 	 */
22940Sstevel@tonic-gate 	data.name = strdup(ecol[0].ec_value.ec_value_val);
22950Sstevel@tonic-gate 	if (data.name == NULL) {
22960Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
22970Sstevel@tonic-gate 		exit(1);
22980Sstevel@tonic-gate 	}
22990Sstevel@tonic-gate 
23000Sstevel@tonic-gate 	buflen = sizeof (auth_type) + strlen(ecol[1].ec_value.ec_value_val) + 3;
23010Sstevel@tonic-gate 	if ((tmppubkey = (char *)malloc(buflen)) == NULL) {
23020Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
23030Sstevel@tonic-gate 		exit(1);
23040Sstevel@tonic-gate 	}
23050Sstevel@tonic-gate 	(void) snprintf(tmppubkey, buflen, "{%s}%s", auth_type,
23060Sstevel@tonic-gate 	    ecol[1].ec_value.ec_value_val);
23070Sstevel@tonic-gate 	data.pubkey = tmppubkey;
23080Sstevel@tonic-gate 
23090Sstevel@tonic-gate 	buflen = sizeof (auth_type) + strlen(ecol[2].ec_value.ec_value_val) + 3;
23100Sstevel@tonic-gate 	if ((tmpprivkey = (char *)malloc(buflen)) == NULL) {
23110Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
23120Sstevel@tonic-gate 		exit(1);
23130Sstevel@tonic-gate 	}
23140Sstevel@tonic-gate 
23150Sstevel@tonic-gate 	(void) snprintf(tmpprivkey, buflen, "{%s}%s", auth_type,
23160Sstevel@tonic-gate 	    ecol[2].ec_value.ec_value_val);
23170Sstevel@tonic-gate 	data.privkey = tmpprivkey;
23180Sstevel@tonic-gate 
23190Sstevel@tonic-gate 	retval = (*cback)(&data, 1);
23202277Sjs198686 	if (retval != NS_LDAP_SUCCESS) {
23212277Sjs198686 		if (retval == LDAP_NO_SUCH_OBJECT) {
23222277Sjs198686 			if (data.hostcred == NS_HOSTCRED_TRUE)
23232277Sjs198686 				(void) fprintf(stdout,
23242277Sjs198686 				gettext("Cannot add publickey entry (%s), "
23252277Sjs198686 					"add host entry first\n"),
23262277Sjs198686 					tmpbuf);
23272277Sjs198686 			else
23282277Sjs198686 				(void) fprintf(stdout,
23292277Sjs198686 				gettext("Cannot add publickey entry (%s), "
23302277Sjs198686 					"add passwd entry first\n"),
23312277Sjs198686 					data.name);
23322277Sjs198686 		}
23332277Sjs198686 		if (continue_onerror == 0)
23342277Sjs198686 			return (GENENT_CBERR);
23350Sstevel@tonic-gate 	}
23362277Sjs198686 
23372277Sjs198686 	free(data.name);
23382277Sjs198686 	free(data.pubkey);
23392277Sjs198686 	free(data.privkey);
23402277Sjs198686 	return (GENENT_OK);
23410Sstevel@tonic-gate }
23420Sstevel@tonic-gate 
23430Sstevel@tonic-gate static void
23440Sstevel@tonic-gate dump_publickey(ns_ldap_result_t *res, char *container)
23450Sstevel@tonic-gate {
23460Sstevel@tonic-gate 	char	**value = NULL;
23470Sstevel@tonic-gate 	char	buf[BUFSIZ];
23480Sstevel@tonic-gate 	char	domainname[BUFSIZ];
23490Sstevel@tonic-gate 	char	*pubptr, *prvptr;
23500Sstevel@tonic-gate 
23510Sstevel@tonic-gate 	if (res == NULL)
23520Sstevel@tonic-gate 		return;
23530Sstevel@tonic-gate 
23540Sstevel@tonic-gate 	if (sysinfo(SI_SRPC_DOMAIN, domainname, BUFSIZ) < 0) {
23550Sstevel@tonic-gate 		(void) fprintf(stderr,
23560Sstevel@tonic-gate 			gettext("could not obtain domainname\n"));
23570Sstevel@tonic-gate 		exit(1);
23580Sstevel@tonic-gate 	}
23590Sstevel@tonic-gate 
23600Sstevel@tonic-gate 	/*
23610Sstevel@tonic-gate 	 * Retrieve all the attributes, but don't print
23620Sstevel@tonic-gate 	 * until we have all the required ones.
23630Sstevel@tonic-gate 	 */
23640Sstevel@tonic-gate 
23650Sstevel@tonic-gate 	if (strcmp(container, "passwd") == 0)
23660Sstevel@tonic-gate 		value = __ns_ldap_getAttr(res->entry, "uidNumber");
23670Sstevel@tonic-gate 	else
23680Sstevel@tonic-gate 		value = __ns_ldap_getAttr(res->entry, "cn");
23690Sstevel@tonic-gate 
23700Sstevel@tonic-gate 	if (value && value[0])
23710Sstevel@tonic-gate 		(void) snprintf(buf, sizeof (buf), "unix.%s@%s",
23720Sstevel@tonic-gate 		    value[0], domainname);
23730Sstevel@tonic-gate 	else
23740Sstevel@tonic-gate 		return;
23750Sstevel@tonic-gate 
23760Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "nisPublickey");
23770Sstevel@tonic-gate 	if (value != NULL && value[0] != NULL) {
23780Sstevel@tonic-gate 		if ((pubptr = strchr(value[0], '}')) == NULL)
23790Sstevel@tonic-gate 			return;
23800Sstevel@tonic-gate 	}
23810Sstevel@tonic-gate 
23820Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "nisSecretkey");
23830Sstevel@tonic-gate 	if (value != NULL && value[0] != NULL)
23840Sstevel@tonic-gate 		if ((prvptr = strchr(value[0], '}')) == NULL)
23850Sstevel@tonic-gate 			return;
23860Sstevel@tonic-gate 
23870Sstevel@tonic-gate 	/* print the attributes, algorithm type is always 0 */
23880Sstevel@tonic-gate 	(void) fprintf(stdout, "%s	%s:%s:0\n", buf, ++pubptr, ++prvptr);
23890Sstevel@tonic-gate }
23900Sstevel@tonic-gate 
23910Sstevel@tonic-gate 
23920Sstevel@tonic-gate 
23930Sstevel@tonic-gate /*
23940Sstevel@tonic-gate  * /etc/netmasks
23950Sstevel@tonic-gate  */
23960Sstevel@tonic-gate 
23970Sstevel@tonic-gate static int
23980Sstevel@tonic-gate genent_netmasks(char *line, int (*cback)())
23990Sstevel@tonic-gate {
24000Sstevel@tonic-gate 	char buf[BUFSIZ+1];
24010Sstevel@tonic-gate 	char *t;
24020Sstevel@tonic-gate 	entry_col ecol[3];
24032277Sjs198686 	int retval;
24040Sstevel@tonic-gate 
24050Sstevel@tonic-gate 	struct _ns_netmasks data;
24060Sstevel@tonic-gate 
24070Sstevel@tonic-gate 
24080Sstevel@tonic-gate 	/*
24090Sstevel@tonic-gate 	 * don't clobber our argument
24100Sstevel@tonic-gate 	 */
24110Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
24120Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
24130Sstevel@tonic-gate 		return (GENENT_PARSEERR);
24140Sstevel@tonic-gate 	}
24150Sstevel@tonic-gate 	(void) strcpy(buf, line);
24160Sstevel@tonic-gate 
24170Sstevel@tonic-gate 	/*
24180Sstevel@tonic-gate 	 * clear column data
24190Sstevel@tonic-gate 	 */
24200Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
24210Sstevel@tonic-gate 
24220Sstevel@tonic-gate 	/*
24230Sstevel@tonic-gate 	 * comment (col 2)
24240Sstevel@tonic-gate 	 */
24250Sstevel@tonic-gate 	t = strchr(buf, '#');
24260Sstevel@tonic-gate 	if (t) {
24270Sstevel@tonic-gate 		*t++ = 0;
24280Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val = t;
24290Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_len = strlen(t)+1;
24300Sstevel@tonic-gate 	} else {
24310Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val = 0;
24320Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_len = 0;
24330Sstevel@tonic-gate 	}
24340Sstevel@tonic-gate 
24350Sstevel@tonic-gate 	/*
24360Sstevel@tonic-gate 	 * addr(col 0)
24370Sstevel@tonic-gate 	 */
24380Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
24390Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no mask");
24400Sstevel@tonic-gate 		return (GENENT_PARSEERR);
24410Sstevel@tonic-gate 	}
24420Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
24430Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
24440Sstevel@tonic-gate 
24450Sstevel@tonic-gate 	/*
24460Sstevel@tonic-gate 	 * mask (col 1)
24470Sstevel@tonic-gate 	 */
24480Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
24490Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no mask");
24500Sstevel@tonic-gate 		return (GENENT_PARSEERR);
24510Sstevel@tonic-gate 	}
24520Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = t;
24530Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_len = strlen(t)+1;
24540Sstevel@tonic-gate 
24550Sstevel@tonic-gate 	/* build entry */
24560Sstevel@tonic-gate 	data.netnumber = ecol[0].ec_value.ec_value_val;
24570Sstevel@tonic-gate 	data.netmask = ecol[1].ec_value.ec_value_val;
24580Sstevel@tonic-gate 
24590Sstevel@tonic-gate 	if (flags & F_VERBOSE)
24600Sstevel@tonic-gate 		(void) fprintf(stdout,
24610Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.netnumber);
24620Sstevel@tonic-gate 
24632277Sjs198686 	retval = (*cback)(&data, 1);
24642277Sjs198686 	if (retval != NS_LDAP_SUCCESS) {
24652277Sjs198686 		if (retval == LDAP_NO_SUCH_OBJECT)
24662277Sjs198686 			(void) fprintf(stdout,
24672277Sjs198686 			gettext("Cannot add netmask entry (%s), "
24682277Sjs198686 				"add network entry first\n"), data.netnumber);
24692277Sjs198686 		if (continue_onerror == 0)
24702277Sjs198686 			return (GENENT_CBERR);
24712277Sjs198686 	}
24720Sstevel@tonic-gate 
24730Sstevel@tonic-gate 	return (GENENT_OK);
24740Sstevel@tonic-gate }
24750Sstevel@tonic-gate 
24760Sstevel@tonic-gate static void
24770Sstevel@tonic-gate dump_netmasks(ns_ldap_result_t *res)
24780Sstevel@tonic-gate {
24790Sstevel@tonic-gate 	char	**value = NULL;
24800Sstevel@tonic-gate 
24810Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "ipNetworkNumber");
24820Sstevel@tonic-gate 	if (value && value[0])
24830Sstevel@tonic-gate 		(void) fprintf(stdout, "%s", value[0]);
24840Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "ipNetmaskNumber");
24850Sstevel@tonic-gate 	if (value && value[0])
24860Sstevel@tonic-gate 		(void) fprintf(stdout, "	%s\n", value[0]);
24870Sstevel@tonic-gate }
24880Sstevel@tonic-gate 
24890Sstevel@tonic-gate 
24900Sstevel@tonic-gate /*
24910Sstevel@tonic-gate  * /etc/netgroup
24920Sstevel@tonic-gate  * column data format is:
24930Sstevel@tonic-gate  *    col 0: netgroup name (or cname)
24940Sstevel@tonic-gate  *    col 1: netgroup member, if this is a triplet
24950Sstevel@tonic-gate  *    col 2: netgroup member, if not a triplet
24960Sstevel@tonic-gate  *    col 3: comment
24970Sstevel@tonic-gate  */
24980Sstevel@tonic-gate 
24990Sstevel@tonic-gate static int
25000Sstevel@tonic-gate genent_netgroup(char *line, int (*cback)())
25010Sstevel@tonic-gate {
25020Sstevel@tonic-gate 	char buf[BIGBUF+1];    /* netgroup entries tend to be big */
25030Sstevel@tonic-gate 	char *t;
25040Sstevel@tonic-gate 	char *cname = NULL;
25050Sstevel@tonic-gate 	entry_col ecol[4];
25060Sstevel@tonic-gate 	char *netg_tmp = NULL, *triplet_tmp = NULL;
25071603Svl199446 	int netgcount = 0, tripletcount = 0, retval = 1, i;
25080Sstevel@tonic-gate 	struct _ns_netgroups data;
25090Sstevel@tonic-gate 	int rc = GENENT_OK;
25100Sstevel@tonic-gate 
25110Sstevel@tonic-gate 	/* don't clobber our argument */
25120Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
25130Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
25140Sstevel@tonic-gate 		return (GENENT_PARSEERR);
25150Sstevel@tonic-gate 	}
25160Sstevel@tonic-gate 	(void) strcpy(buf, line);
25170Sstevel@tonic-gate 
25180Sstevel@tonic-gate 	/* clear column data */
25190Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
25200Sstevel@tonic-gate 
25210Sstevel@tonic-gate 	/*
25220Sstevel@tonic-gate 	 * process 1st minimal entry, to validate that there is no
25230Sstevel@tonic-gate 	 * parsing error.
25240Sstevel@tonic-gate 	 * start with comment(col 3)
25250Sstevel@tonic-gate 	 */
25260Sstevel@tonic-gate 	t = strchr(buf, '#');
25270Sstevel@tonic-gate 	if (t) {
25280Sstevel@tonic-gate 		*t++ = 0;
25290Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = t;
25300Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = strlen(t)+1;
25310Sstevel@tonic-gate 	} else {
25320Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = "";
25330Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
25340Sstevel@tonic-gate 	}
25350Sstevel@tonic-gate 
25360Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = NULL;
25370Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = NULL;
25380Sstevel@tonic-gate 
25390Sstevel@tonic-gate 	/* cname (col 0) */
25400Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
25410Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no cname");
25420Sstevel@tonic-gate 		return (GENENT_PARSEERR);
25430Sstevel@tonic-gate 	}
25441603Svl199446 
25450Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
25460Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
25470Sstevel@tonic-gate 	cname = t;
25480Sstevel@tonic-gate 
25490Sstevel@tonic-gate 	/* addr(col 1 and 2) */
25500Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
25510Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no members for netgroup");
25520Sstevel@tonic-gate 		return (GENENT_PARSEERR);
25530Sstevel@tonic-gate 	}
25540Sstevel@tonic-gate 
25550Sstevel@tonic-gate 	if (*t == '(') {
25561603Svl199446 		/* if token starts with '(' it must be a valid triplet */
25571603Svl199446 		if (is_triplet(t)) {
25581603Svl199446 			ecol[1].ec_value.ec_value_val = t;
25591603Svl199446 			ecol[1].ec_value.ec_value_len = strlen(t)+1;
25601603Svl199446 		} else {
25611603Svl199446 			(void) strcpy(parse_err_msg, "invalid triplet");
25621603Svl199446 			return (GENENT_PARSEERR);
25631603Svl199446 		}
25640Sstevel@tonic-gate 	} else {
25650Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val = t;
25660Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_len = strlen(t)+1;
25670Sstevel@tonic-gate 	}
25680Sstevel@tonic-gate 
25690Sstevel@tonic-gate 	/*
25700Sstevel@tonic-gate 	 * now build entry.
25710Sstevel@tonic-gate 	 * start by clearing entry data
25720Sstevel@tonic-gate 	 */
25730Sstevel@tonic-gate 	(void) memset((struct _ns_netgroups *)&data, 0, sizeof (data));
25740Sstevel@tonic-gate 
25750Sstevel@tonic-gate 	data.name = strdup(ecol[0].ec_value.ec_value_val);
25760Sstevel@tonic-gate 
25770Sstevel@tonic-gate 	if (ecol[1].ec_value.ec_value_val != NULL) {
25780Sstevel@tonic-gate 		if ((data.triplet = calloc(1, sizeof (char **))) == NULL) {
25790Sstevel@tonic-gate 				(void) fprintf(stderr,
25800Sstevel@tonic-gate 					gettext("out of memory\n"));
25810Sstevel@tonic-gate 				exit(1);
25820Sstevel@tonic-gate 		}
25830Sstevel@tonic-gate 		data.triplet[tripletcount++] =
25840Sstevel@tonic-gate 		    strdup(ecol[1].ec_value.ec_value_val);
25850Sstevel@tonic-gate 	} else if (ecol[2].ec_value.ec_value_val != NULL) {
25860Sstevel@tonic-gate 			if ((data.netgroup = calloc(1, sizeof (char **)))
25870Sstevel@tonic-gate 			    == NULL) {
25880Sstevel@tonic-gate 					(void) fprintf(stderr,
25890Sstevel@tonic-gate 				    gettext("out of memory\n"));
25900Sstevel@tonic-gate 					exit(1);
25910Sstevel@tonic-gate 			}
25920Sstevel@tonic-gate 			data.netgroup[netgcount++] =
25930Sstevel@tonic-gate 			    strdup(ecol[2].ec_value.ec_value_val);
25940Sstevel@tonic-gate 	}
25950Sstevel@tonic-gate 
25960Sstevel@tonic-gate 	/*
25970Sstevel@tonic-gate 	 * we now have a valid entry (at least 1 netgroup name and
25980Sstevel@tonic-gate 	 * 1 netgroup member), proceed with the rest of the line
25990Sstevel@tonic-gate 	 */
26001603Svl199446 	while (rc == GENENT_OK && (t = strtok(NULL, " \t"))) {
26010Sstevel@tonic-gate 
26020Sstevel@tonic-gate 		/* if next token is equal to netgroup name, ignore */
26030Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
26040Sstevel@tonic-gate 			continue;
26050Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
26060Sstevel@tonic-gate 			continue;
26070Sstevel@tonic-gate 
26080Sstevel@tonic-gate 		if (*t == '(') {
26091603Svl199446 			if (is_triplet(t)) {
26101603Svl199446 				/* skip a triplet if it is added already */
26111603Svl199446 				for (i = 0; i < tripletcount &&
26121603Svl199446 					strcmp(t, data.triplet[i]); i++)
26131603Svl199446 					;
26141603Svl199446 				if (i < tripletcount)
26151603Svl199446 					continue;
26161603Svl199446 
26171603Svl199446 				tripletcount++;
26181603Svl199446 				triplet_tmp = strdup(t);
26191603Svl199446 				if ((data.triplet = (char **)realloc(
26201603Svl199446 					data.triplet,
26211603Svl199446 					tripletcount * sizeof (char **)))
26221603Svl199446 					== NULL) {
26231603Svl199446 					(void) fprintf(stderr,
26241603Svl199446 						gettext("out of memory\n"));
26251603Svl199446 					exit(1);
26261603Svl199446 				}
26271603Svl199446 				data.triplet[tripletcount-1] = triplet_tmp;
26281603Svl199446 			} else {
26291603Svl199446 				(void) strcpy(parse_err_msg, "invalid triplet");
26301603Svl199446 				rc = GENENT_PARSEERR;
26310Sstevel@tonic-gate 			}
26320Sstevel@tonic-gate 		} else {
26331603Svl199446 			/* skip a netgroup if it is added already */
26341603Svl199446 			for (i = 0; i < netgcount &&
26351603Svl199446 				strcmp(t, data.netgroup[i]); i++)
26361603Svl199446 				;
26371603Svl199446 			if (i < netgcount)
26381603Svl199446 				continue;
26391603Svl199446 
26400Sstevel@tonic-gate 			netgcount++;
26410Sstevel@tonic-gate 			netg_tmp = strdup(t);
26420Sstevel@tonic-gate 			if ((data.netgroup = (char **)realloc(data.netgroup,
26430Sstevel@tonic-gate 				netgcount * sizeof (char **))) == NULL) {
26440Sstevel@tonic-gate 				(void) fprintf(stderr,
26450Sstevel@tonic-gate 				gettext("out of memory\n"));
26460Sstevel@tonic-gate 				exit(1);
26470Sstevel@tonic-gate 			}
26480Sstevel@tonic-gate 			data.netgroup[netgcount-1] = netg_tmp;
26490Sstevel@tonic-gate 		}
26500Sstevel@tonic-gate 	}
26510Sstevel@tonic-gate 
26520Sstevel@tonic-gate 	/* End the list with NULL */
26530Sstevel@tonic-gate 	if ((data.triplet = (char **)realloc(data.triplet,
26540Sstevel@tonic-gate 		(tripletcount + 1) * sizeof (char **))) == NULL) {
26550Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
26560Sstevel@tonic-gate 		exit(1);
26570Sstevel@tonic-gate 	}
26580Sstevel@tonic-gate 	data.triplet[tripletcount] = NULL;
26590Sstevel@tonic-gate 	if ((data.netgroup = (char **)realloc(data.netgroup,
26600Sstevel@tonic-gate 		(netgcount + 1) * sizeof (char **))) == NULL) {
26610Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
26620Sstevel@tonic-gate 		exit(1);
26630Sstevel@tonic-gate 	}
26640Sstevel@tonic-gate 	data.netgroup[netgcount] = NULL;
26650Sstevel@tonic-gate 
26661603Svl199446 	if (rc == GENENT_OK) {
26671603Svl199446 		if (flags & F_VERBOSE)
26681603Svl199446 			(void) fprintf(stdout,
26691603Svl199446 			    gettext("Adding entry : %s\n"), data.name);
26701603Svl199446 
26711603Svl199446 		retval = (*cback)(&data, 0);
26721603Svl199446 
26731603Svl199446 		if (retval == LDAP_ALREADY_EXISTS) {
26741603Svl199446 			if (continue_onerror)
26751603Svl199446 				(void) fprintf(stderr, gettext(
26761603Svl199446 				"Entry: %s - already Exists, skipping it.\n"),
26771603Svl199446 				data.name);
26781603Svl199446 			else {
26791603Svl199446 				rc = GENENT_CBERR;
26801603Svl199446 				(void) fprintf(stderr,
26811603Svl199446 					gettext("Entry: %s - already Exists\n"),
26821603Svl199446 					data.name);
26831603Svl199446 			}
26841603Svl199446 		} else if (retval)
26850Sstevel@tonic-gate 			rc = GENENT_CBERR;
26861603Svl199446 	}
26871603Svl199446 
26881603Svl199446 	/* release memory allocated by strdup() */
26891603Svl199446 	for (i = 0; i < tripletcount; i++) {
26901603Svl199446 		free(data.triplet[i]);
26911603Svl199446 	}
26921603Svl199446 	for (i = 0; i < netgcount; i++) {
26931603Svl199446 		free(data.netgroup[i]);
26941603Svl199446 	}
26950Sstevel@tonic-gate 
26960Sstevel@tonic-gate 	free(data.name);
26970Sstevel@tonic-gate 	free(data.triplet);
26980Sstevel@tonic-gate 	free(data.netgroup);
26990Sstevel@tonic-gate 
27000Sstevel@tonic-gate 	return (rc);
27010Sstevel@tonic-gate }
27020Sstevel@tonic-gate 
27030Sstevel@tonic-gate static void
27040Sstevel@tonic-gate dump_netgroup(ns_ldap_result_t *res)
27050Sstevel@tonic-gate {
27060Sstevel@tonic-gate 	char	**value = NULL;
27070Sstevel@tonic-gate 	int	attr_count = 0;
27080Sstevel@tonic-gate 
27090Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "cn");
27100Sstevel@tonic-gate 	if ((value != NULL) && (value[0] != NULL))
27110Sstevel@tonic-gate 		(void) fprintf(stdout, "%s", value[0]);
27120Sstevel@tonic-gate 	else
27130Sstevel@tonic-gate 		return;
27140Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "nisNetgroupTriple");
27150Sstevel@tonic-gate 	if (value != NULL)
27160Sstevel@tonic-gate 		while (value[attr_count] != NULL) {
27170Sstevel@tonic-gate 			(void) fprintf(stdout, " %s", value[attr_count]);
27180Sstevel@tonic-gate 			attr_count++;
27190Sstevel@tonic-gate 		}
27202300Sjs198686 	attr_count = 0;
27210Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "memberNisNetgroup");
27220Sstevel@tonic-gate 	if (value != NULL)
27230Sstevel@tonic-gate 		while (value[attr_count] != NULL) {
27240Sstevel@tonic-gate 			(void) fprintf(stdout, " %s", value[attr_count]);
27250Sstevel@tonic-gate 			attr_count++;
27260Sstevel@tonic-gate 		}
27270Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
27280Sstevel@tonic-gate 
27290Sstevel@tonic-gate }
27300Sstevel@tonic-gate 
27310Sstevel@tonic-gate static int
27320Sstevel@tonic-gate genent_automount(char *line, int (*cback)())
27330Sstevel@tonic-gate {
27340Sstevel@tonic-gate 	char buf[BUFSIZ+1];
27350Sstevel@tonic-gate 	char *t, *s;
27360Sstevel@tonic-gate 	entry_col ecol[2];
27370Sstevel@tonic-gate 	struct _ns_automount data;
27380Sstevel@tonic-gate 	int retval = 1;
27390Sstevel@tonic-gate 	int rc = GENENT_OK;
27400Sstevel@tonic-gate 
27410Sstevel@tonic-gate 	/*
27420Sstevel@tonic-gate 	 * don't clobber our argument
27430Sstevel@tonic-gate 	 */
27440Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
27450Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
27460Sstevel@tonic-gate 		return (GENENT_PARSEERR);
27470Sstevel@tonic-gate 		}
27480Sstevel@tonic-gate 
27490Sstevel@tonic-gate 	/* replace every tabspace with single space */
27500Sstevel@tonic-gate 	replace_tab2space(line);
27510Sstevel@tonic-gate 	(void) strcpy(buf, line);
27520Sstevel@tonic-gate 
27530Sstevel@tonic-gate 	/*
27540Sstevel@tonic-gate 	 * clear column data
27550Sstevel@tonic-gate 	 */
27560Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
27570Sstevel@tonic-gate 
27580Sstevel@tonic-gate 	/*
27590Sstevel@tonic-gate 	 * key (col 0)
27600Sstevel@tonic-gate 	 */
27610Sstevel@tonic-gate 	t = buf;
27620Sstevel@tonic-gate 	while (t[0] == ' ')
27630Sstevel@tonic-gate 		t++;
27640Sstevel@tonic-gate 
27650Sstevel@tonic-gate 	if ((s = strchr(t, ' ')) == 0) {
27660Sstevel@tonic-gate 		return (GENENT_PARSEERR);
27670Sstevel@tonic-gate 	}
27680Sstevel@tonic-gate 	*s++ = 0;
27690Sstevel@tonic-gate 
27700Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
27710Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
27720Sstevel@tonic-gate 	t = s;
27730Sstevel@tonic-gate 
27740Sstevel@tonic-gate 	while (t[0] == ' ')
27750Sstevel@tonic-gate 		t++;
27760Sstevel@tonic-gate 
27770Sstevel@tonic-gate 	/*
27780Sstevel@tonic-gate 	 * mapentry (col 1)
27790Sstevel@tonic-gate 	 */
27800Sstevel@tonic-gate 
27810Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = t;
27820Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_len = strlen(t)+1;
27830Sstevel@tonic-gate 
27840Sstevel@tonic-gate 	data.mapname = strdup(databasetype);
27850Sstevel@tonic-gate 	data.key = strdup(ecol[0].ec_value.ec_value_val);
27860Sstevel@tonic-gate 	data.value = strdup(ecol[1].ec_value.ec_value_val);
27870Sstevel@tonic-gate 
27880Sstevel@tonic-gate 	if (flags & F_VERBOSE)
27890Sstevel@tonic-gate 		(void) fprintf(stdout,
27900Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.key);
27910Sstevel@tonic-gate 
27920Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
27930Sstevel@tonic-gate 
27940Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
27950Sstevel@tonic-gate 		if (continue_onerror)
27960Sstevel@tonic-gate 			(void) fprintf(stderr,
27970Sstevel@tonic-gate 			gettext("Entry: %s - already Exists, skipping it.\n"),
27980Sstevel@tonic-gate 			data.key);
27990Sstevel@tonic-gate 		else {
28000Sstevel@tonic-gate 			rc = GENENT_CBERR;
28010Sstevel@tonic-gate 			(void) fprintf(stderr,
28020Sstevel@tonic-gate 				gettext("Entry: %s - already Exists\n"),
28030Sstevel@tonic-gate 				data.key);
28040Sstevel@tonic-gate 		}
28050Sstevel@tonic-gate 	} else if (retval)
28060Sstevel@tonic-gate 		rc = GENENT_CBERR;
28070Sstevel@tonic-gate 
28080Sstevel@tonic-gate 	free(data.mapname);
28090Sstevel@tonic-gate 	free(data.key);
28100Sstevel@tonic-gate 	free(data.value);
28110Sstevel@tonic-gate 	return (rc);
28120Sstevel@tonic-gate }
28130Sstevel@tonic-gate 
28140Sstevel@tonic-gate static void
28150Sstevel@tonic-gate dump_automount(ns_ldap_result_t *res)
28160Sstevel@tonic-gate {
28170Sstevel@tonic-gate 	char	**value = NULL;
28180Sstevel@tonic-gate 
28190Sstevel@tonic-gate 	if (res == NULL)
28200Sstevel@tonic-gate 		return;
28210Sstevel@tonic-gate 
28220Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "automountKey");
28230Sstevel@tonic-gate 	if (value != NULL) {
28240Sstevel@tonic-gate 		(void) fprintf(stdout, "%s", value[0]);
28250Sstevel@tonic-gate 		value = __ns_ldap_getAttr(res->entry, "automountInformation");
28260Sstevel@tonic-gate 		if (value != NULL)
28270Sstevel@tonic-gate 			(void) fprintf(stdout, "	%s\n", value[0]);
28280Sstevel@tonic-gate 		else
28290Sstevel@tonic-gate 			(void) fprintf(stdout, "\n");
28300Sstevel@tonic-gate 	}
28310Sstevel@tonic-gate }
28320Sstevel@tonic-gate 
28330Sstevel@tonic-gate 
28340Sstevel@tonic-gate /*
28350Sstevel@tonic-gate  * /etc/passwd
28360Sstevel@tonic-gate  *
28370Sstevel@tonic-gate  */
28380Sstevel@tonic-gate 
28390Sstevel@tonic-gate static int
28400Sstevel@tonic-gate genent_passwd(char *line, int (*cback)())
28410Sstevel@tonic-gate {
28420Sstevel@tonic-gate 	char buf[BUFSIZ+1];
28430Sstevel@tonic-gate 	char *s, *t;
28440Sstevel@tonic-gate 	entry_col ecol[8];
28450Sstevel@tonic-gate 	int retval = 1;
28460Sstevel@tonic-gate 	char pname[BUFSIZ];
28470Sstevel@tonic-gate 
28480Sstevel@tonic-gate 	struct passwd	data;
28490Sstevel@tonic-gate 	int rc = GENENT_OK;
28500Sstevel@tonic-gate 
28510Sstevel@tonic-gate 
28520Sstevel@tonic-gate 	/*
28530Sstevel@tonic-gate 	 * don't clobber our argument
28540Sstevel@tonic-gate 	 */
28550Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
28560Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
28570Sstevel@tonic-gate 		return (GENENT_PARSEERR);
28580Sstevel@tonic-gate 	}
28590Sstevel@tonic-gate 	(void) strcpy(buf, line);
28600Sstevel@tonic-gate 	t = buf;
28610Sstevel@tonic-gate 
28620Sstevel@tonic-gate 	/* ignore empty entries */
28630Sstevel@tonic-gate 	if (*t == '\0')
28640Sstevel@tonic-gate 		return (GENENT_OK);
28650Sstevel@tonic-gate 
28660Sstevel@tonic-gate 	/*
28670Sstevel@tonic-gate 	 * clear column data
28680Sstevel@tonic-gate 	 */
28690Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
28700Sstevel@tonic-gate 
28710Sstevel@tonic-gate 	/*
28720Sstevel@tonic-gate 	 * name (col 0)
28730Sstevel@tonic-gate 	 */
28740Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
28750Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no password");
28760Sstevel@tonic-gate 		return (GENENT_PARSEERR);
28770Sstevel@tonic-gate 	}
28780Sstevel@tonic-gate 	*s++ = 0;
28790Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
28800Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
28810Sstevel@tonic-gate 	t = s;
28820Sstevel@tonic-gate 
28830Sstevel@tonic-gate 	/*
28840Sstevel@tonic-gate 	 * passwd (col 1)
28850Sstevel@tonic-gate 	 */
28860Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
28870Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no uid");
28880Sstevel@tonic-gate 		return (GENENT_PARSEERR);
28890Sstevel@tonic-gate 	}
28900Sstevel@tonic-gate 	*s++ = 0;
28910Sstevel@tonic-gate 
28920Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = t;
28930Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_len = strlen(t)+1;
28940Sstevel@tonic-gate 
28950Sstevel@tonic-gate 	t = s;
28960Sstevel@tonic-gate 
28970Sstevel@tonic-gate 	/*
28980Sstevel@tonic-gate 	 * uid (col 2)
28990Sstevel@tonic-gate 	 */
29000Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0 || s == t) {
29010Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no gid");
29020Sstevel@tonic-gate 		return (GENENT_PARSEERR);
29030Sstevel@tonic-gate 	}
29040Sstevel@tonic-gate 	*s++ = 0;
29050Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
29060Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
29070Sstevel@tonic-gate 	t = s;
29080Sstevel@tonic-gate 
29090Sstevel@tonic-gate 	/*
29100Sstevel@tonic-gate 	 * gid (col 3)
29110Sstevel@tonic-gate 	 */
29120Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0 || s == t) {
29130Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no gcos");
29140Sstevel@tonic-gate 		return (GENENT_PARSEERR);
29150Sstevel@tonic-gate 	}
29160Sstevel@tonic-gate 	*s++ = 0;
29170Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_val = t;
29180Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_len = strlen(t)+1;
29190Sstevel@tonic-gate 	t = s;
29200Sstevel@tonic-gate 
29210Sstevel@tonic-gate 	/*
29220Sstevel@tonic-gate 	 * gcos (col 4)
29230Sstevel@tonic-gate 	 */
29240Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
29250Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no home");
29260Sstevel@tonic-gate 		return (GENENT_PARSEERR);
29270Sstevel@tonic-gate 	}
29280Sstevel@tonic-gate 	*s++ = 0;
29290Sstevel@tonic-gate 	ecol[4].ec_value.ec_value_val = t;
29300Sstevel@tonic-gate 	ecol[4].ec_value.ec_value_len = strlen(t)+1;
29310Sstevel@tonic-gate 	t = s;
29320Sstevel@tonic-gate 
29330Sstevel@tonic-gate 	/*
29340Sstevel@tonic-gate 	 * home (col 5)
29350Sstevel@tonic-gate 	 */
29360Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
29370Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no shell");
29380Sstevel@tonic-gate 		return (GENENT_PARSEERR);
29390Sstevel@tonic-gate 	}
29400Sstevel@tonic-gate 	*s++ = 0;
29410Sstevel@tonic-gate 	ecol[5].ec_value.ec_value_val = t;
29420Sstevel@tonic-gate 	ecol[5].ec_value.ec_value_len = strlen(t)+1;
29430Sstevel@tonic-gate 	t = s;
29440Sstevel@tonic-gate 
29450Sstevel@tonic-gate 	/*
29460Sstevel@tonic-gate 	 * shell (col 6)
29470Sstevel@tonic-gate 	 */
29480Sstevel@tonic-gate 	ecol[6].ec_value.ec_value_val = t;
29490Sstevel@tonic-gate 	ecol[6].ec_value.ec_value_len = strlen(t)+1;
29500Sstevel@tonic-gate 
29510Sstevel@tonic-gate 	/*
29520Sstevel@tonic-gate 	 * build entry
29530Sstevel@tonic-gate 	 */
29540Sstevel@tonic-gate 	data.pw_name = strdup(ecol[0].ec_value.ec_value_val);
29550Sstevel@tonic-gate 
29560Sstevel@tonic-gate 	if (flags & F_PASSWD) {
29570Sstevel@tonic-gate 		/* Add {crypt} before passwd entry */
29580Sstevel@tonic-gate 		(void) snprintf(pname, sizeof (pname), "{crypt}%s",
29590Sstevel@tonic-gate 		    ecol[1].ec_value.ec_value_val);
29600Sstevel@tonic-gate 		data.pw_passwd = strdup(pname);
29610Sstevel@tonic-gate 	}
29620Sstevel@tonic-gate 	else
29630Sstevel@tonic-gate 		data.pw_passwd = NULL;
29640Sstevel@tonic-gate 
29650Sstevel@tonic-gate 	if (ecol[2].ec_value.ec_value_val != NULL &&
29660Sstevel@tonic-gate 	    ecol[2].ec_value.ec_value_val[0] != '\0') {
29670Sstevel@tonic-gate 		data.pw_uid = ascii_to_int(ecol[2].ec_value.ec_value_val);
29680Sstevel@tonic-gate 		if (data.pw_uid == -1) {
29690Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
29700Sstevel@tonic-gate 			    "invalid uid : %s", ecol[2].ec_value.ec_value_val);
29710Sstevel@tonic-gate 		return (GENENT_PARSEERR);
29720Sstevel@tonic-gate 		}
29730Sstevel@tonic-gate 	} else
29740Sstevel@tonic-gate 		data.pw_uid = -1;
29750Sstevel@tonic-gate 
29760Sstevel@tonic-gate 	if (ecol[3].ec_value.ec_value_val != NULL &&
29770Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val[0] != '\0') {
29780Sstevel@tonic-gate 
29790Sstevel@tonic-gate 		data.pw_gid = ascii_to_int(ecol[3].ec_value.ec_value_val);
29800Sstevel@tonic-gate 		if (data.pw_gid == -1) {
29810Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
29820Sstevel@tonic-gate 			    "invalid gid : %s", ecol[3].ec_value.ec_value_val);
29830Sstevel@tonic-gate 		return (GENENT_PARSEERR);
29840Sstevel@tonic-gate 		}
29850Sstevel@tonic-gate 	} else
29860Sstevel@tonic-gate 		data.pw_gid = -1;
29870Sstevel@tonic-gate 
29880Sstevel@tonic-gate 	data.pw_age = NULL;
29890Sstevel@tonic-gate 	data.pw_comment = NULL;
29900Sstevel@tonic-gate 	data.pw_gecos = strdup(ecol[4].ec_value.ec_value_val);
29910Sstevel@tonic-gate 	data.pw_dir = strdup(ecol[5].ec_value.ec_value_val);
29920Sstevel@tonic-gate 	data.pw_shell = strdup(ecol[6].ec_value.ec_value_val);
29930Sstevel@tonic-gate 
29940Sstevel@tonic-gate 	if (flags & F_VERBOSE)
29950Sstevel@tonic-gate 		(void) fprintf(stdout,
29960Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.pw_name);
29970Sstevel@tonic-gate 
29980Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
29990Sstevel@tonic-gate 
30000Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
30010Sstevel@tonic-gate 		if (continue_onerror)
30020Sstevel@tonic-gate 			(void) fprintf(stderr,
30030Sstevel@tonic-gate 			gettext("Entry: %s - already Exists, skipping it.\n"),
30040Sstevel@tonic-gate 			data.pw_name);
30050Sstevel@tonic-gate 		else {
30060Sstevel@tonic-gate 			rc = GENENT_CBERR;
30070Sstevel@tonic-gate 			(void) fprintf(stderr,
30080Sstevel@tonic-gate 				gettext("Entry: %s - already Exists\n"),
30090Sstevel@tonic-gate 				data.pw_name);
30100Sstevel@tonic-gate 		}
30110Sstevel@tonic-gate 	} else if (retval)
30120Sstevel@tonic-gate 		rc = GENENT_CBERR;
30130Sstevel@tonic-gate 
30140Sstevel@tonic-gate 	free(data.pw_name);
30150Sstevel@tonic-gate 	free(data.pw_gecos);
30160Sstevel@tonic-gate 	free(data.pw_dir);
30170Sstevel@tonic-gate 	free(data.pw_shell);
30180Sstevel@tonic-gate 	return (rc);
30190Sstevel@tonic-gate }
30200Sstevel@tonic-gate 
30210Sstevel@tonic-gate 
30220Sstevel@tonic-gate static void
30230Sstevel@tonic-gate dump_passwd(ns_ldap_result_t *res)
30240Sstevel@tonic-gate {
30250Sstevel@tonic-gate 	char    **value = NULL;
30260Sstevel@tonic-gate 	char	pnam[256];
30270Sstevel@tonic-gate 
30280Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "uid");
30290Sstevel@tonic-gate 	if (value == NULL)
30300Sstevel@tonic-gate 		return;
30310Sstevel@tonic-gate 	else
30320Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
30330Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "userPassword");
30340Sstevel@tonic-gate 	if (value == NULL)
30350Sstevel@tonic-gate 		(void) fprintf(stdout, "*:");
30360Sstevel@tonic-gate 	else {
30370Sstevel@tonic-gate 		(void) strcpy(pnam, value[0]);
30380Sstevel@tonic-gate 		if (strncasecmp(value[0], "{crypt}", 7) == 0)
30390Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", (pnam+7));
30400Sstevel@tonic-gate 		else
30410Sstevel@tonic-gate 			(void) fprintf(stdout, "*:");
30420Sstevel@tonic-gate 	}
30430Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "uidNumber");
30440Sstevel@tonic-gate 	if (value && value[0])
30450Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
30460Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "gidNumber");
30470Sstevel@tonic-gate 	if (value && value[0])
30480Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
30490Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "gecos");
30500Sstevel@tonic-gate 	if (value == NULL)
30510Sstevel@tonic-gate 		(void) fprintf(stdout, ":");
30520Sstevel@tonic-gate 	else
30530Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
30540Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "homeDirectory");
30550Sstevel@tonic-gate 	if (value == NULL)
30560Sstevel@tonic-gate 		(void) fprintf(stdout, ":");
30570Sstevel@tonic-gate 	else
30580Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
30590Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "loginShell");
30600Sstevel@tonic-gate 	if (value == NULL)
30610Sstevel@tonic-gate 		(void) fprintf(stdout, "\n");
30620Sstevel@tonic-gate 	else
30630Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\n", value[0]);
30640Sstevel@tonic-gate 
30650Sstevel@tonic-gate }
30660Sstevel@tonic-gate 
30670Sstevel@tonic-gate /*
30680Sstevel@tonic-gate  * /etc/shadow
30690Sstevel@tonic-gate  */
30700Sstevel@tonic-gate 
30710Sstevel@tonic-gate static int
30720Sstevel@tonic-gate genent_shadow(char *line, int (*cback)())
30730Sstevel@tonic-gate {
30740Sstevel@tonic-gate 	char buf[BUFSIZ+1];
30750Sstevel@tonic-gate 	char *s, *t;
30760Sstevel@tonic-gate 	entry_col ecol[9];
30770Sstevel@tonic-gate 	char pname[BUFSIZ];
30780Sstevel@tonic-gate 
30790Sstevel@tonic-gate 	struct spwd	data;
30800Sstevel@tonic-gate 	int spflag;
30812277Sjs198686 	int retval;
30820Sstevel@tonic-gate 
30830Sstevel@tonic-gate 
30840Sstevel@tonic-gate 	/*
30850Sstevel@tonic-gate 	 * don't clobber our argument
30860Sstevel@tonic-gate 	 */
30870Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
30880Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
30890Sstevel@tonic-gate 		return (GENENT_PARSEERR);
30900Sstevel@tonic-gate 	}
30910Sstevel@tonic-gate 	(void) strcpy(buf, line);
30920Sstevel@tonic-gate 	t = buf;
30930Sstevel@tonic-gate 
30940Sstevel@tonic-gate 	/* ignore empty entries */
30950Sstevel@tonic-gate 	if (*t == '\0')
30960Sstevel@tonic-gate 		return (GENENT_OK);
30970Sstevel@tonic-gate 
30980Sstevel@tonic-gate 	/*
30990Sstevel@tonic-gate 	 * clear column data
31000Sstevel@tonic-gate 	 */
31010Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
31020Sstevel@tonic-gate 
31030Sstevel@tonic-gate 	/*
31040Sstevel@tonic-gate 	 * name (col 0)
31050Sstevel@tonic-gate 	 */
31060Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
31070Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no uid");
31080Sstevel@tonic-gate 		return (GENENT_PARSEERR);
31090Sstevel@tonic-gate 	}
31100Sstevel@tonic-gate 	*s++ = 0;
31110Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
31120Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
31130Sstevel@tonic-gate 	t = s;
31140Sstevel@tonic-gate 
31150Sstevel@tonic-gate 	/*
31160Sstevel@tonic-gate 	 * passwd (col 1)
31170Sstevel@tonic-gate 	 */
31180Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
31190Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "Improper format");
31200Sstevel@tonic-gate 		return (GENENT_PARSEERR);
31210Sstevel@tonic-gate 	}
31220Sstevel@tonic-gate 	*s++ = 0;
31230Sstevel@tonic-gate 
31240Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
31250Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
31260Sstevel@tonic-gate 
31270Sstevel@tonic-gate 	t = s;
31280Sstevel@tonic-gate 
31290Sstevel@tonic-gate 	/*
31300Sstevel@tonic-gate 	 * shadow last change (col 2)
31310Sstevel@tonic-gate 	 */
31320Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
31330Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "Improper format");
31340Sstevel@tonic-gate 		return (GENENT_PARSEERR);
31350Sstevel@tonic-gate 	}
31360Sstevel@tonic-gate 	*s++ = 0;
31370Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
31380Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
31390Sstevel@tonic-gate 	t = s;
31400Sstevel@tonic-gate 
31410Sstevel@tonic-gate 	/*
31420Sstevel@tonic-gate 	 * shadow min (col 3)
31430Sstevel@tonic-gate 	 */
31440Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
31450Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "Improper format");
31460Sstevel@tonic-gate 		return (GENENT_PARSEERR);
31470Sstevel@tonic-gate 	}
31480Sstevel@tonic-gate 	*s++ = 0;
31490Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_val = t;
31500Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_len = strlen(t)+1;
31510Sstevel@tonic-gate 	t = s;
31520Sstevel@tonic-gate 
31530Sstevel@tonic-gate 	/*
31540Sstevel@tonic-gate 	 * shadow max (col 4)
31550Sstevel@tonic-gate 	 */
31560Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
31570Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "Improper format");
31580Sstevel@tonic-gate 		return (GENENT_PARSEERR);
31590Sstevel@tonic-gate 	}
31600Sstevel@tonic-gate 	*s++ = 0;
31610Sstevel@tonic-gate 	ecol[4].ec_value.ec_value_val = t;
31620Sstevel@tonic-gate 	ecol[4].ec_value.ec_value_len = strlen(t)+1;
31630Sstevel@tonic-gate 	t = s;
31640Sstevel@tonic-gate 
31650Sstevel@tonic-gate 	/*
31660Sstevel@tonic-gate 	 * shadow warn (col 5)
31670Sstevel@tonic-gate 	 */
31680Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
31690Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "Improper format");
31700Sstevel@tonic-gate 		return (GENENT_PARSEERR);
31710Sstevel@tonic-gate 	}
31720Sstevel@tonic-gate 	*s++ = 0;
31730Sstevel@tonic-gate 	ecol[5].ec_value.ec_value_val = t;
31740Sstevel@tonic-gate 	ecol[5].ec_value.ec_value_len = strlen(t)+1;
31750Sstevel@tonic-gate 	t = s;
31760Sstevel@tonic-gate 
31770Sstevel@tonic-gate 	/*
31780Sstevel@tonic-gate 	 * shadow inactive (col 6)
31790Sstevel@tonic-gate 	 */
31800Sstevel@tonic-gate 	if ((s = strchr(t, ':')) != 0) {
31810Sstevel@tonic-gate 	*s++ = 0;
31820Sstevel@tonic-gate 	ecol[6].ec_value.ec_value_val = t;
31830Sstevel@tonic-gate 	ecol[6].ec_value.ec_value_len = strlen(t)+1;
31840Sstevel@tonic-gate 	t = s;
31850Sstevel@tonic-gate 	}
31860Sstevel@tonic-gate 
31870Sstevel@tonic-gate 	/*
31880Sstevel@tonic-gate 	 * shadow expire  (col 7)
31890Sstevel@tonic-gate 	 */
31900Sstevel@tonic-gate 	if ((s = strchr(t, ':')) != 0) {
31910Sstevel@tonic-gate 	*s++ = 0;
31920Sstevel@tonic-gate 	ecol[7].ec_value.ec_value_val = t;
31930Sstevel@tonic-gate 	ecol[7].ec_value.ec_value_len = strlen(t)+1;
31940Sstevel@tonic-gate 	t = s;
31950Sstevel@tonic-gate 
31960Sstevel@tonic-gate 	/*
31970Sstevel@tonic-gate 	 * flag (col 8)
31980Sstevel@tonic-gate 	 */
31990Sstevel@tonic-gate 	ecol[8].ec_value.ec_value_val = t;
32000Sstevel@tonic-gate 	ecol[8].ec_value.ec_value_len = strlen(t)+1;
32010Sstevel@tonic-gate 	}
32020Sstevel@tonic-gate 
32030Sstevel@tonic-gate 	/*
32040Sstevel@tonic-gate 	 * build entry
32050Sstevel@tonic-gate 	 */
32060Sstevel@tonic-gate 
32070Sstevel@tonic-gate 	data.sp_namp = strdup(ecol[0].ec_value.ec_value_val);
32080Sstevel@tonic-gate 
32090Sstevel@tonic-gate 	if (ecol[1].ec_value.ec_value_val != NULL &&
32100Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val[0] != '\0') {
32110Sstevel@tonic-gate 		/* Add {crypt} before passwd entry */
32120Sstevel@tonic-gate 		(void) snprintf(pname, sizeof (pname), "{crypt}%s",
32130Sstevel@tonic-gate 		    ecol[1].ec_value.ec_value_val);
32140Sstevel@tonic-gate 		data.sp_pwdp = strdup(pname);
32150Sstevel@tonic-gate 	} else
32160Sstevel@tonic-gate 		data.sp_pwdp = NULL;
32170Sstevel@tonic-gate 
32180Sstevel@tonic-gate 	if (ecol[2].ec_value.ec_value_val != NULL &&
32190Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val[0] != '\0') {
32200Sstevel@tonic-gate 
32210Sstevel@tonic-gate 		data.sp_lstchg = ascii_to_int(ecol[2].ec_value.ec_value_val);
32220Sstevel@tonic-gate 		if (data.sp_lstchg < -1) {
32230Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
32240Sstevel@tonic-gate 			    "invalid last changed date: %s",
32250Sstevel@tonic-gate 			    ecol[2].ec_value.ec_value_val);
32260Sstevel@tonic-gate 		return (GENENT_PARSEERR);
32270Sstevel@tonic-gate 		}
32280Sstevel@tonic-gate 	} else
32290Sstevel@tonic-gate 		data.sp_lstchg = -1;
32300Sstevel@tonic-gate 
32310Sstevel@tonic-gate 	if (ecol[3].ec_value.ec_value_val != NULL &&
32320Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val[0] != '\0') {
32330Sstevel@tonic-gate 
32340Sstevel@tonic-gate 		data.sp_min = ascii_to_int(ecol[3].ec_value.ec_value_val);
32350Sstevel@tonic-gate 		if (data.sp_min < -1) {
32360Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
32370Sstevel@tonic-gate 			    "invalid sp_min : %s",
32380Sstevel@tonic-gate 			    ecol[3].ec_value.ec_value_val);
32390Sstevel@tonic-gate 		return (GENENT_PARSEERR);
32400Sstevel@tonic-gate 		}
32410Sstevel@tonic-gate 	} else
32420Sstevel@tonic-gate 		data.sp_min = -1;
32430Sstevel@tonic-gate 
32440Sstevel@tonic-gate 	if (ecol[4].ec_value.ec_value_val != NULL &&
32450Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_val[0] != '\0') {
32460Sstevel@tonic-gate 
32470Sstevel@tonic-gate 		data.sp_max = ascii_to_int(ecol[4].ec_value.ec_value_val);
32480Sstevel@tonic-gate 		if (data.sp_max < -1) {
32490Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
32500Sstevel@tonic-gate 			    "invalid sp_max : %s",
32510Sstevel@tonic-gate 			    ecol[4].ec_value.ec_value_val);
32520Sstevel@tonic-gate 		return (GENENT_PARSEERR);
32530Sstevel@tonic-gate 		}
32540Sstevel@tonic-gate 	} else
32550Sstevel@tonic-gate 		data.sp_max = -1;
32560Sstevel@tonic-gate 
32570Sstevel@tonic-gate 	if (ecol[5].ec_value.ec_value_val != NULL &&
32580Sstevel@tonic-gate 		ecol[5].ec_value.ec_value_val[0] != '\0') {
32590Sstevel@tonic-gate 
32600Sstevel@tonic-gate 		data.sp_warn = ascii_to_int(ecol[5].ec_value.ec_value_val);
32610Sstevel@tonic-gate 		if (data.sp_warn < -1) {
32620Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
32630Sstevel@tonic-gate 			    "invalid sp_warn : %s",
32640Sstevel@tonic-gate 			    ecol[5].ec_value.ec_value_val);
32650Sstevel@tonic-gate 		return (GENENT_PARSEERR);
32660Sstevel@tonic-gate 		}
32670Sstevel@tonic-gate 	} else
32680Sstevel@tonic-gate 		data.sp_warn = -1;
32690Sstevel@tonic-gate 
32700Sstevel@tonic-gate 	if (ecol[6].ec_value.ec_value_val != NULL &&
32710Sstevel@tonic-gate 		ecol[6].ec_value.ec_value_val[0] != '\0') {
32720Sstevel@tonic-gate 
32730Sstevel@tonic-gate 		data.sp_inact = ascii_to_int(ecol[6].ec_value.ec_value_val);
32740Sstevel@tonic-gate 		if (data.sp_inact < -1) {
32750Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
32760Sstevel@tonic-gate 			    "invalid sp_inact : %s",
32770Sstevel@tonic-gate 			    ecol[6].ec_value.ec_value_val);
32780Sstevel@tonic-gate 		return (GENENT_PARSEERR);
32790Sstevel@tonic-gate 		}
32800Sstevel@tonic-gate 	} else
32810Sstevel@tonic-gate 		data.sp_inact = -1;
32820Sstevel@tonic-gate 
32830Sstevel@tonic-gate 	if (ecol[7].ec_value.ec_value_val != NULL &&
32840Sstevel@tonic-gate 		ecol[7].ec_value.ec_value_val[0] != '\0') {
32850Sstevel@tonic-gate 
32860Sstevel@tonic-gate 		data.sp_expire = ascii_to_int(ecol[7].ec_value.ec_value_val);
32870Sstevel@tonic-gate 		if (data.sp_expire < -1) {
32880Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
32890Sstevel@tonic-gate 			    "invalid login expiry date : %s",
32900Sstevel@tonic-gate 			    ecol[7].ec_value.ec_value_val);
32910Sstevel@tonic-gate 		return (GENENT_PARSEERR);
32920Sstevel@tonic-gate 		}
32930Sstevel@tonic-gate 	} else
32940Sstevel@tonic-gate 		data.sp_expire = -1;
32950Sstevel@tonic-gate 
32960Sstevel@tonic-gate 	if (ecol[8].ec_value.ec_value_val != NULL &&
32970Sstevel@tonic-gate 		ecol[8].ec_value.ec_value_val[0] != '\0') {
32980Sstevel@tonic-gate 
32990Sstevel@tonic-gate 		/*
33000Sstevel@tonic-gate 		 * data.sp_flag is an unsigned int,
33010Sstevel@tonic-gate 		 * assign -1 to it, make no sense.
33020Sstevel@tonic-gate 		 * Use spflag here to avoid lint warning.
33030Sstevel@tonic-gate 		 */
33040Sstevel@tonic-gate 		spflag = ascii_to_int(ecol[8].ec_value.ec_value_val);
33050Sstevel@tonic-gate 		if (spflag < 0) {
33060Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
33070Sstevel@tonic-gate 			    "invalid flag value: %s",
33080Sstevel@tonic-gate 			    ecol[8].ec_value.ec_value_val);
33090Sstevel@tonic-gate 		return (GENENT_PARSEERR);
33100Sstevel@tonic-gate 		} else
33110Sstevel@tonic-gate 			data.sp_flag = spflag;
33120Sstevel@tonic-gate 	} else
33130Sstevel@tonic-gate 		data.sp_flag = 0;
33140Sstevel@tonic-gate 
33150Sstevel@tonic-gate 	if (flags & F_VERBOSE)
33160Sstevel@tonic-gate 		(void) fprintf(stdout,
33170Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.sp_namp);
33180Sstevel@tonic-gate 
33192277Sjs198686 	retval = (*cback)(&data, 1);
33202277Sjs198686 	if (retval != NS_LDAP_SUCCESS) {
33212277Sjs198686 		if (retval == LDAP_NO_SUCH_OBJECT)
33222277Sjs198686 			(void) fprintf(stdout,
33232277Sjs198686 			gettext("Cannot add shadow entry (%s), "
33242277Sjs198686 				"add passwd entry first\n"), data.sp_namp);
33252277Sjs198686 		if (continue_onerror == 0)
33262277Sjs198686 			return (GENENT_CBERR);
33272277Sjs198686 	}
33280Sstevel@tonic-gate 
33290Sstevel@tonic-gate 	free(data.sp_namp);
33300Sstevel@tonic-gate 	free(data.sp_pwdp);
33310Sstevel@tonic-gate 	return (GENENT_OK);
33320Sstevel@tonic-gate }
33330Sstevel@tonic-gate 
33340Sstevel@tonic-gate static void
33350Sstevel@tonic-gate dump_shadow(ns_ldap_result_t *res)
33360Sstevel@tonic-gate {
33370Sstevel@tonic-gate 	char    **value = NULL;
33380Sstevel@tonic-gate 	char   pnam[256];
33390Sstevel@tonic-gate 
33400Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "uid");
33410Sstevel@tonic-gate 	if (value == NULL)
33420Sstevel@tonic-gate 		return;
33430Sstevel@tonic-gate 	else
33440Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
33450Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "userPassword");
33460Sstevel@tonic-gate 	if (value == NULL)
33470Sstevel@tonic-gate 		(void) fprintf(stdout, "*:");
33480Sstevel@tonic-gate 	else {
33490Sstevel@tonic-gate 		(void) strcpy(pnam, value[0]);
33500Sstevel@tonic-gate 		if (strncasecmp(value[0], "{crypt}", 7) == 0)
33510Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", (pnam+7));
33520Sstevel@tonic-gate 		else
33530Sstevel@tonic-gate 			(void) fprintf(stdout, "*:");
33540Sstevel@tonic-gate 	}
33550Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "shadowLastChange");
33560Sstevel@tonic-gate 	if (value == NULL)
33570Sstevel@tonic-gate 		(void) fprintf(stdout, ":");
33580Sstevel@tonic-gate 	else
33590Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
33600Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "shadowMin");
33610Sstevel@tonic-gate 	if (value == NULL)
33620Sstevel@tonic-gate 		(void) fprintf(stdout, ":");
33630Sstevel@tonic-gate 	else
33640Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
33650Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "shadowMax");
33660Sstevel@tonic-gate 	if (value == NULL)
33670Sstevel@tonic-gate 		(void) fprintf(stdout, ":");
33680Sstevel@tonic-gate 	else
33690Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
33700Sstevel@tonic-gate 
33710Sstevel@tonic-gate 	/* ignore shadowWarning, shadowInactive, shadowExpire, shadowFlag */
33720Sstevel@tonic-gate 	(void) fprintf(stdout, ":::\n");
33730Sstevel@tonic-gate 
33740Sstevel@tonic-gate }
33750Sstevel@tonic-gate 
33760Sstevel@tonic-gate 
33770Sstevel@tonic-gate static int
33780Sstevel@tonic-gate genent_bootparams(char *line, int (*cback)())
33790Sstevel@tonic-gate {
33800Sstevel@tonic-gate 	char buf[BUFSIZ+1];
33810Sstevel@tonic-gate 	char *t;
33820Sstevel@tonic-gate 	entry_col ecol[2];
33830Sstevel@tonic-gate 	int ctr = 0, retval = 1;
33840Sstevel@tonic-gate 
33850Sstevel@tonic-gate 	struct _ns_bootp data;
33860Sstevel@tonic-gate 	char *parameter;
33870Sstevel@tonic-gate 	int rc = GENENT_OK;
33880Sstevel@tonic-gate 
33890Sstevel@tonic-gate 	/*
33900Sstevel@tonic-gate 	 * don't clobber our argument
33910Sstevel@tonic-gate 	 */
33920Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
33930Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "line too long");
33940Sstevel@tonic-gate 		return (GENENT_PARSEERR);
33950Sstevel@tonic-gate 	}
33960Sstevel@tonic-gate 	(void) strcpy(buf, line);
33970Sstevel@tonic-gate 
33980Sstevel@tonic-gate 	/*
33990Sstevel@tonic-gate 	 * clear column data
34000Sstevel@tonic-gate 	 */
34010Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
34020Sstevel@tonic-gate 
34030Sstevel@tonic-gate 
34040Sstevel@tonic-gate 	/*
34050Sstevel@tonic-gate 	 * cname (col 0)
34060Sstevel@tonic-gate 	 */
34070Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
34080Sstevel@tonic-gate 		(void) strcpy(parse_err_msg, "no cname");
34090Sstevel@tonic-gate 		return (GENENT_PARSEERR);
34100Sstevel@tonic-gate 	}
34110Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
34120Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
34130Sstevel@tonic-gate 
34140Sstevel@tonic-gate 
34150Sstevel@tonic-gate 
34160Sstevel@tonic-gate 	/* build entry */
34170Sstevel@tonic-gate 	data.name = strdup(ecol[0].ec_value.ec_value_val);
34180Sstevel@tonic-gate 
34190Sstevel@tonic-gate 	/*
34200Sstevel@tonic-gate 	 * name (col 1)
34210Sstevel@tonic-gate 	 */
34220Sstevel@tonic-gate 
34230Sstevel@tonic-gate 	data.param = NULL;
34240Sstevel@tonic-gate 
34251831Sdm199847 	while (t = strtok(NULL, " \t"))  {
34260Sstevel@tonic-gate 
34270Sstevel@tonic-gate 		/*
34280Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
34290Sstevel@tonic-gate 		 */
34300Sstevel@tonic-gate 
34310Sstevel@tonic-gate 
34320Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
34330Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
34340Sstevel@tonic-gate 
34350Sstevel@tonic-gate 		ctr++;
34360Sstevel@tonic-gate 		parameter = strdup(ecol[1].ec_value.ec_value_val);
34370Sstevel@tonic-gate 		if ((data.param = (char **)realloc(data.param,
34380Sstevel@tonic-gate 			(ctr + 1) * sizeof (char **))) == NULL) {
34390Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
34400Sstevel@tonic-gate 			exit(1);
34410Sstevel@tonic-gate 		}
34420Sstevel@tonic-gate 		data.param[ctr-1] = parameter;
34430Sstevel@tonic-gate 
34441831Sdm199847 	}
34450Sstevel@tonic-gate 
34460Sstevel@tonic-gate 
34470Sstevel@tonic-gate 	/* End the list of all the aliases by NULL */
34480Sstevel@tonic-gate 	if ((data.param = (char **)realloc(data.param,
34490Sstevel@tonic-gate 		(ctr + 1) * sizeof (char **))) == NULL) {
34500Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
34510Sstevel@tonic-gate 		exit(1);
34520Sstevel@tonic-gate 	}
34530Sstevel@tonic-gate 	data.param[ctr] = NULL;
34540Sstevel@tonic-gate 
34550Sstevel@tonic-gate 	if (flags & F_VERBOSE)
34560Sstevel@tonic-gate 		(void) fprintf(stdout,
34570Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.name);
34580Sstevel@tonic-gate 
34590Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
34600Sstevel@tonic-gate 
34610Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
34620Sstevel@tonic-gate 		if (continue_onerror)
34630Sstevel@tonic-gate 			(void) fprintf(stderr,
34640Sstevel@tonic-gate 			gettext("Entry: %s - already Exists, skipping it.\n"),
34650Sstevel@tonic-gate 			data.name);
34660Sstevel@tonic-gate 		else {
34670Sstevel@tonic-gate 			rc = GENENT_CBERR;
34680Sstevel@tonic-gate 			(void) fprintf(stderr,
34690Sstevel@tonic-gate 				gettext("Entry: %s - already Exists\n"),
34700Sstevel@tonic-gate 				data.name);
34710Sstevel@tonic-gate 		}
34720Sstevel@tonic-gate 	} else if (retval)
34730Sstevel@tonic-gate 		rc = GENENT_CBERR;
34740Sstevel@tonic-gate 
34750Sstevel@tonic-gate 	free(data.name);
34760Sstevel@tonic-gate 	free(data.param);
34770Sstevel@tonic-gate 
34780Sstevel@tonic-gate 	return (rc);
34790Sstevel@tonic-gate 
34800Sstevel@tonic-gate }
34810Sstevel@tonic-gate 
34820Sstevel@tonic-gate 
34830Sstevel@tonic-gate static void
34840Sstevel@tonic-gate dump_bootparams(ns_ldap_result_t *res)
34850Sstevel@tonic-gate {
34860Sstevel@tonic-gate 	char	**value = NULL;
34870Sstevel@tonic-gate 	int		attr_count = 0;
34880Sstevel@tonic-gate 
34890Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "cn");
34900Sstevel@tonic-gate 	if (value[0] != NULL)
34910Sstevel@tonic-gate 		(void) fprintf(stdout, "%s", value[0]);
34920Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "bootParameter");
34930Sstevel@tonic-gate 	if (value != NULL)
34940Sstevel@tonic-gate 		while (value[attr_count] != NULL) {
34950Sstevel@tonic-gate 		(void) fprintf(stdout, "\t%s", value[attr_count]);
34960Sstevel@tonic-gate 			attr_count++;
34970Sstevel@tonic-gate 		}
34980Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
34990Sstevel@tonic-gate 
35000Sstevel@tonic-gate 
35010Sstevel@tonic-gate }
35020Sstevel@tonic-gate 
35030Sstevel@tonic-gate static char *
35040Sstevel@tonic-gate fget_line_at(struct line_buf *line, int n, FILE *fp)
35050Sstevel@tonic-gate {
35060Sstevel@tonic-gate 	int c;
35070Sstevel@tonic-gate 
35080Sstevel@tonic-gate 	line->len = n;
35090Sstevel@tonic-gate 
35100Sstevel@tonic-gate 	for (;;) {
35110Sstevel@tonic-gate 		c = fgetc(fp);
35120Sstevel@tonic-gate 		if (c == -1)
35130Sstevel@tonic-gate 			break;
35140Sstevel@tonic-gate 		if (line->len >= line->alloc)
35150Sstevel@tonic-gate 			line_buf_expand(line);
35160Sstevel@tonic-gate 		line->str[line->len++] = c;
35170Sstevel@tonic-gate 
35180Sstevel@tonic-gate 		if (c == '\n')
35190Sstevel@tonic-gate 			break;
35200Sstevel@tonic-gate 	}
35210Sstevel@tonic-gate 
35220Sstevel@tonic-gate 	/* Null Terminate */
35230Sstevel@tonic-gate 	if (line->len >= line->alloc)
35240Sstevel@tonic-gate 		line_buf_expand(line);
35250Sstevel@tonic-gate 	line->str[line->len++] = 0;
35260Sstevel@tonic-gate 
35270Sstevel@tonic-gate 	/* if no characters are read, return NULL to indicate EOF */
35280Sstevel@tonic-gate 	if (line->str[0] == '\0')
35290Sstevel@tonic-gate 		return (0);
35300Sstevel@tonic-gate 
35310Sstevel@tonic-gate 	return (line->str);
35320Sstevel@tonic-gate }
35330Sstevel@tonic-gate 
35340Sstevel@tonic-gate /*
35350Sstevel@tonic-gate  * return a line from the file, discarding comments and blank lines
35360Sstevel@tonic-gate  */
35370Sstevel@tonic-gate static int
35380Sstevel@tonic-gate filedbmline_comment(struct line_buf *line, FILE *etcf, int *lineno,
35390Sstevel@tonic-gate     struct file_loc *loc)
35400Sstevel@tonic-gate {
35410Sstevel@tonic-gate 	int i, len = 0;
35420Sstevel@tonic-gate 
35430Sstevel@tonic-gate 	loc->offset = ftell(etcf);
35440Sstevel@tonic-gate 	for (;;) {
35450Sstevel@tonic-gate 		if (fget_line_at(line, len, etcf) == 0)
35460Sstevel@tonic-gate 			return (0);
35470Sstevel@tonic-gate 
35480Sstevel@tonic-gate 		if (lineno)
35490Sstevel@tonic-gate 			(*lineno)++;
35500Sstevel@tonic-gate 
35510Sstevel@tonic-gate 		len = strlen(line->str);
35520Sstevel@tonic-gate 		if (len >= 2 &&
35530Sstevel@tonic-gate 		    line->str[0] != '#' &&
35540Sstevel@tonic-gate 		    line->str[len-2] == '\\' && line->str[len-1] == '\n') {
35550Sstevel@tonic-gate 			line->str[len-2] = 0;
35560Sstevel@tonic-gate 			len -= 2;
35570Sstevel@tonic-gate 			continue;    /* append next line at end */
35580Sstevel@tonic-gate 		}
35590Sstevel@tonic-gate 
35600Sstevel@tonic-gate 		if (line->str[len-1] == '\n') {
35610Sstevel@tonic-gate 			line->str[len-1] = 0;
35620Sstevel@tonic-gate 			len -= 1;
35630Sstevel@tonic-gate 		}
35640Sstevel@tonic-gate 
35650Sstevel@tonic-gate 		/*
35660Sstevel@tonic-gate 		 * Skip lines where '#' is the first non-blank character.
35670Sstevel@tonic-gate 		 */
35680Sstevel@tonic-gate 		for (i = 0; i < len; i++) {
35690Sstevel@tonic-gate 			if (line->str[i] == '#') {
35700Sstevel@tonic-gate 				line->str[i] = '\0';
35710Sstevel@tonic-gate 				len = i;
35720Sstevel@tonic-gate 				break;
35730Sstevel@tonic-gate 			}
35740Sstevel@tonic-gate 			if (line->str[i] != ' ' && line->str[i] != '\t')
35750Sstevel@tonic-gate 				break;
35760Sstevel@tonic-gate 		}
35770Sstevel@tonic-gate 
35780Sstevel@tonic-gate 		/*
35790Sstevel@tonic-gate 		 * A line with one or more white space characters followed
35800Sstevel@tonic-gate 		 * by a comment will now be blank. The special case of a
35810Sstevel@tonic-gate 		 * line with '#' in the first byte will have len == 0.
35820Sstevel@tonic-gate 		 */
35830Sstevel@tonic-gate 		if (len > 0 && !blankline(line->str))
35840Sstevel@tonic-gate 			break;
35850Sstevel@tonic-gate 
35860Sstevel@tonic-gate 		len = 0;
35870Sstevel@tonic-gate 		loc->offset = ftell(etcf);
35880Sstevel@tonic-gate 	}
35890Sstevel@tonic-gate 
35900Sstevel@tonic-gate 	loc->size = len;
35910Sstevel@tonic-gate 	return (1);
35920Sstevel@tonic-gate }
35930Sstevel@tonic-gate 
35940Sstevel@tonic-gate /*
35950Sstevel@tonic-gate  * return a line from the file, discarding comments, blanks, and '+' lines
35960Sstevel@tonic-gate  */
35970Sstevel@tonic-gate static int
35980Sstevel@tonic-gate filedbmline_plus(struct line_buf *line, FILE *etcf, int *lineno,
35990Sstevel@tonic-gate     struct file_loc *loc)
36000Sstevel@tonic-gate {
36010Sstevel@tonic-gate 	int len = 0;
36020Sstevel@tonic-gate 
36030Sstevel@tonic-gate 	loc->offset = ftell(etcf);
36040Sstevel@tonic-gate 	for (;;) {
36050Sstevel@tonic-gate 		if (fget_line_at(line, len, etcf) == 0)
36060Sstevel@tonic-gate 			return (0);
36070Sstevel@tonic-gate 
36080Sstevel@tonic-gate 		if (lineno)
36090Sstevel@tonic-gate 			(*lineno)++;
36100Sstevel@tonic-gate 
36110Sstevel@tonic-gate 		len = strlen(line->str);
36120Sstevel@tonic-gate 		if (line->str[len-1] == '\n') {
36130Sstevel@tonic-gate 			line->str[len-1] = 0;
36140Sstevel@tonic-gate 			len -= 1;
36150Sstevel@tonic-gate 		}
36160Sstevel@tonic-gate 
36170Sstevel@tonic-gate 		if (!blankline(line->str) &&
36180Sstevel@tonic-gate 		line->str[0] != '+' && line->str[0] != '-' &&
36190Sstevel@tonic-gate 		line->str[0] != '#')
36200Sstevel@tonic-gate 			break;
36210Sstevel@tonic-gate 
36220Sstevel@tonic-gate 		len = 0;
36230Sstevel@tonic-gate 		loc->offset = ftell(etcf);
36240Sstevel@tonic-gate 	}
36250Sstevel@tonic-gate 
36260Sstevel@tonic-gate 	loc->size = len;
36270Sstevel@tonic-gate 	return (1);
36280Sstevel@tonic-gate }
36290Sstevel@tonic-gate 
36300Sstevel@tonic-gate 
36310Sstevel@tonic-gate /* Populating the ttypelist structure */
36320Sstevel@tonic-gate 
36330Sstevel@tonic-gate static struct ttypelist_t ttypelist[] = {
36340Sstevel@tonic-gate 	{ NS_LDAP_TYPE_HOSTS, genent_hosts, dump_hosts,
36350Sstevel@tonic-gate 		filedbmline_comment, "iphost" },
36360Sstevel@tonic-gate 	{ NS_LDAP_TYPE_IPNODES, genent_hosts, dump_hosts,
36370Sstevel@tonic-gate 		filedbmline_comment, "iphost" },
36380Sstevel@tonic-gate 	{ NS_LDAP_TYPE_RPC, genent_rpc, dump_rpc,
36390Sstevel@tonic-gate 		filedbmline_comment, "oncrpc" },
36400Sstevel@tonic-gate 	{ NS_LDAP_TYPE_PROTOCOLS, genent_protocols, dump_protocols,
36410Sstevel@tonic-gate 		filedbmline_comment, "ipprotocol" },
36420Sstevel@tonic-gate 	{ NS_LDAP_TYPE_NETWORKS, genent_networks, dump_networks,
36430Sstevel@tonic-gate 		filedbmline_comment, "ipnetwork"  },
36440Sstevel@tonic-gate 	{ NS_LDAP_TYPE_SERVICES, genent_services, dump_services,
36450Sstevel@tonic-gate 		filedbmline_comment, "ipservice" },
36460Sstevel@tonic-gate 	{ NS_LDAP_TYPE_GROUP, genent_group, dump_group,
36470Sstevel@tonic-gate 		filedbmline_plus, "posixgroup" },
36480Sstevel@tonic-gate 	{ NS_LDAP_TYPE_NETMASKS, genent_netmasks, dump_netmasks,
36490Sstevel@tonic-gate 		filedbmline_comment, "ipnetwork" },
36500Sstevel@tonic-gate 	{ NS_LDAP_TYPE_ETHERS, genent_ethers, dump_ethers,
36510Sstevel@tonic-gate 		filedbmline_comment, "ieee802Device" },
36520Sstevel@tonic-gate 	{ NS_LDAP_TYPE_NETGROUP, genent_netgroup, dump_netgroup,
36530Sstevel@tonic-gate 		filedbmline_comment, "nisnetgroup" },
36540Sstevel@tonic-gate 	{ NS_LDAP_TYPE_BOOTPARAMS, genent_bootparams, dump_bootparams,
36550Sstevel@tonic-gate 		filedbmline_comment, "bootableDevice" },
36560Sstevel@tonic-gate 	{ NS_LDAP_TYPE_PUBLICKEY, genent_publickey, NULL /* dump_publickey */,
36570Sstevel@tonic-gate 		filedbmline_comment, "niskeyobject" },
36580Sstevel@tonic-gate 	{ NS_LDAP_TYPE_PASSWD, genent_passwd, dump_passwd,
36590Sstevel@tonic-gate 		filedbmline_plus, "posixaccount" },
36600Sstevel@tonic-gate 	{ NS_LDAP_TYPE_SHADOW, genent_shadow, dump_shadow,
36610Sstevel@tonic-gate 		filedbmline_plus, "shadowaccount" },
36620Sstevel@tonic-gate 	{ NS_LDAP_TYPE_ALIASES, genent_aliases, dump_aliases,
36630Sstevel@tonic-gate 		filedbmline_plus, "mailGroup" },
36640Sstevel@tonic-gate 	{ NS_LDAP_TYPE_AUTOMOUNT, genent_automount, dump_automount,
36650Sstevel@tonic-gate 		filedbmline_comment, "automount" },
36660Sstevel@tonic-gate 	{ NS_LDAP_TYPE_USERATTR, genent_user_attr, dump_user_attr,
36670Sstevel@tonic-gate 		filedbmline_comment, "SolarisUserAttr" },
36680Sstevel@tonic-gate 	{ NS_LDAP_TYPE_PROFILE, genent_prof_attr, dump_prof_attr,
36690Sstevel@tonic-gate 		filedbmline_comment, "SolarisProfAttr" },
36700Sstevel@tonic-gate 	{ NS_LDAP_TYPE_EXECATTR, genent_exec_attr, dump_exec_attr,
36710Sstevel@tonic-gate 		filedbmline_comment, "SolarisExecAttr" },
36720Sstevel@tonic-gate 	{ NS_LDAP_TYPE_AUTHATTR, genent_auth_attr, dump_auth_attr,
36730Sstevel@tonic-gate 		filedbmline_comment, "SolarisAuthAttr" },
36740Sstevel@tonic-gate 	{ NS_LDAP_TYPE_AUUSER, genent_audit_user, dump_audit_user,
36750Sstevel@tonic-gate 		filedbmline_comment, "SolarisAuditUser" },
36761676Sjpk 	{ NS_LDAP_TYPE_TNRHDB, genent_tnrhdb, dump_tnrhdb,
36771676Sjpk 		filedbmline_comment, "ipTnetHost" },
36781676Sjpk 	{ NS_LDAP_TYPE_TNRHTP, genent_tnrhtp, dump_tnrhtp,
36791676Sjpk 		filedbmline_comment, "ipTnetTemplate" },
36800Sstevel@tonic-gate 	{ 0, 0, 0, 0, 0 }
36810Sstevel@tonic-gate };
36820Sstevel@tonic-gate 
36830Sstevel@tonic-gate 
36840Sstevel@tonic-gate 
36850Sstevel@tonic-gate 
36860Sstevel@tonic-gate static int lineno = 0;
36870Sstevel@tonic-gate 
36880Sstevel@tonic-gate static	void
36890Sstevel@tonic-gate addfile()
36900Sstevel@tonic-gate {
36910Sstevel@tonic-gate 	struct line_buf line;
36920Sstevel@tonic-gate 	struct file_loc loc;
36930Sstevel@tonic-gate 
36940Sstevel@tonic-gate 	/* Initializing the Line Buffer */
36950Sstevel@tonic-gate 	line_buf_init(&line);
36960Sstevel@tonic-gate 
36970Sstevel@tonic-gate 	/* Loop through all the lines in the file */
36980Sstevel@tonic-gate 	while (tt->filedbmline(&line, etcf, &lineno, &loc)) {
36990Sstevel@tonic-gate 		switch ((*(tt->genent))(line.str, addentry)) {
37000Sstevel@tonic-gate 		case GENENT_OK:
37010Sstevel@tonic-gate 			break;
37020Sstevel@tonic-gate 		case GENENT_PARSEERR:
37030Sstevel@tonic-gate 			(void) fprintf(stderr,
37040Sstevel@tonic-gate 			    gettext("parse error: %s (line %d)\n"),
37050Sstevel@tonic-gate 			    parse_err_msg, lineno);
37060Sstevel@tonic-gate 			exit_val = 1;
37070Sstevel@tonic-gate 			break;
37080Sstevel@tonic-gate 		case GENENT_CBERR:
37090Sstevel@tonic-gate 			(void) fprintf(stderr,
37100Sstevel@tonic-gate 			    gettext("Error while adding line: %s\n"),
37110Sstevel@tonic-gate 			    line.str);
37120Sstevel@tonic-gate 			exit_val = 2;
37130Sstevel@tonic-gate 			free(line.str);
37140Sstevel@tonic-gate 			return;
37150Sstevel@tonic-gate 			break;
37160Sstevel@tonic-gate 		case GENENT_ERR:
37170Sstevel@tonic-gate 			(void) fprintf(stderr,
37180Sstevel@tonic-gate 			    gettext("Internal Error while adding line: %s\n"),
37190Sstevel@tonic-gate 			    line.str);
37200Sstevel@tonic-gate 			exit_val = 3;
37210Sstevel@tonic-gate 			free(line.str);
37220Sstevel@tonic-gate 			return;
37230Sstevel@tonic-gate 			break;
37240Sstevel@tonic-gate 		}
37250Sstevel@tonic-gate 	}
37260Sstevel@tonic-gate 	free(line.str);
37270Sstevel@tonic-gate }
37280Sstevel@tonic-gate 
37290Sstevel@tonic-gate static void
37300Sstevel@tonic-gate dumptable(char *service)
37310Sstevel@tonic-gate {
37320Sstevel@tonic-gate 
37330Sstevel@tonic-gate 	ns_ldap_result_t *eres = NULL;
37340Sstevel@tonic-gate 	ns_ldap_error_t *err = NULL;
37350Sstevel@tonic-gate 	int	rc = 0, success = 0;
37360Sstevel@tonic-gate 	char	filter[BUFSIZ];
37370Sstevel@tonic-gate 	int	done = 0;
37380Sstevel@tonic-gate 	void	*cookie = NULL;
37390Sstevel@tonic-gate 
37400Sstevel@tonic-gate 	/* set the appropriate filter */
37410Sstevel@tonic-gate 	if (strcmp(tt->ttype, NS_LDAP_TYPE_PROFILE) == 0) {
37420Sstevel@tonic-gate 		/*
37430Sstevel@tonic-gate 		 * prof_attr entries are SolarisProfAttr
37440Sstevel@tonic-gate 		 * without AUXILIARY SolarisExecAttr
37450Sstevel@tonic-gate 		 */
37460Sstevel@tonic-gate 		(void) snprintf(filter, sizeof (filter),
37470Sstevel@tonic-gate 		    "(&(objectclass=%s)(!(objectclass=SolarisExecAttr)))",
37480Sstevel@tonic-gate 		    tt->objclass);
37491676Sjpk 	} else if (strcmp(tt->ttype, NS_LDAP_TYPE_TNRHDB) == 0) {
37501676Sjpk 		/*
37511676Sjpk 		 * tnrhtp entries are ipTnet entries with SolarisAttrKeyValue
37521676Sjpk 		 */
37531676Sjpk 		(void) snprintf(filter, sizeof (filter),
37541676Sjpk 		    "(&(objectclass=%s)(SolarisAttrKeyValue=*)))",
37551676Sjpk 		    tt->objclass);
37561676Sjpk 	} else {
37570Sstevel@tonic-gate 		(void) snprintf(filter, sizeof (filter),
37580Sstevel@tonic-gate 		    "(objectclass=%s)", tt->objclass);
37591676Sjpk 	}
37600Sstevel@tonic-gate 
37610Sstevel@tonic-gate 	if (flags & F_VERBOSE)
37620Sstevel@tonic-gate 		(void) fprintf(stdout, gettext("FILTER = %s\n"), filter);
37630Sstevel@tonic-gate 
37640Sstevel@tonic-gate 	/* Pass cred only if supplied. Cred is not always needed for dump */
37650Sstevel@tonic-gate 	if (authority.cred.unix_cred.userID == NULL ||
37660Sstevel@tonic-gate 	    authority.cred.unix_cred.passwd == NULL)
37670Sstevel@tonic-gate 		rc = __ns_ldap_firstEntry(service, filter, NULL, NULL,
37680Sstevel@tonic-gate 		    NULL, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
37690Sstevel@tonic-gate 	else
37700Sstevel@tonic-gate 		rc = __ns_ldap_firstEntry(service, filter, NULL, NULL,
37710Sstevel@tonic-gate 		    &authority, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
37720Sstevel@tonic-gate 
37730Sstevel@tonic-gate 	switch (rc) {
37740Sstevel@tonic-gate 	case NS_LDAP_SUCCESS:
37750Sstevel@tonic-gate 		nent_add++;
37760Sstevel@tonic-gate 		success = 1;
37770Sstevel@tonic-gate 		if (eres != NULL) {
37780Sstevel@tonic-gate 			if (strcmp(databasetype, "publickey") == 0)
37790Sstevel@tonic-gate 				dump_publickey(eres, service);
37800Sstevel@tonic-gate 			else
37810Sstevel@tonic-gate 				(*(tt->dump))(eres);
37820Sstevel@tonic-gate 		}
37830Sstevel@tonic-gate 		else
37840Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("No entries found.\n"));
37850Sstevel@tonic-gate 		break;
37860Sstevel@tonic-gate 
37870Sstevel@tonic-gate 	case NS_LDAP_OP_FAILED:
37880Sstevel@tonic-gate 		exit_val = 2;
37890Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("operation failed.\n"));
37900Sstevel@tonic-gate 		break;
37910Sstevel@tonic-gate 
37920Sstevel@tonic-gate 	case NS_LDAP_INVALID_PARAM:
37930Sstevel@tonic-gate 		exit_val = 2;
37940Sstevel@tonic-gate 		(void) fprintf(stderr,
37950Sstevel@tonic-gate 		    gettext("invalid parameter(s) passed.\n"));
37960Sstevel@tonic-gate 		break;
37970Sstevel@tonic-gate 
37980Sstevel@tonic-gate 	case NS_LDAP_NOTFOUND:
37990Sstevel@tonic-gate 		exit_val = 2;
38000Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("entry not found.\n"));
38010Sstevel@tonic-gate 		break;
38020Sstevel@tonic-gate 
38030Sstevel@tonic-gate 	case NS_LDAP_MEMORY:
38040Sstevel@tonic-gate 		exit_val = 2;
38050Sstevel@tonic-gate 		(void) fprintf(stderr,
38060Sstevel@tonic-gate 			gettext("internal memory allocation error.\n"));
38070Sstevel@tonic-gate 		break;
38080Sstevel@tonic-gate 
38090Sstevel@tonic-gate 	case NS_LDAP_CONFIG:
38100Sstevel@tonic-gate 		exit_val = 2;
38110Sstevel@tonic-gate 		(void) fprintf(stderr,
38120Sstevel@tonic-gate 			gettext("LDAP Configuration problem.\n"));
38130Sstevel@tonic-gate 		perr(err);
38140Sstevel@tonic-gate 		break;
38150Sstevel@tonic-gate 
38160Sstevel@tonic-gate 	case NS_LDAP_PARTIAL:
38170Sstevel@tonic-gate 		exit_val = 2;
38180Sstevel@tonic-gate 		(void) fprintf(stderr,
38190Sstevel@tonic-gate 			gettext("partial result returned\n"));
38200Sstevel@tonic-gate 		perr(err);
38210Sstevel@tonic-gate 		break;
38220Sstevel@tonic-gate 
38230Sstevel@tonic-gate 	case NS_LDAP_INTERNAL:
38240Sstevel@tonic-gate 		exit_val = 2;
38250Sstevel@tonic-gate 		(void) fprintf(stderr,
38260Sstevel@tonic-gate 			gettext("internal LDAP error occured.\n"));
38270Sstevel@tonic-gate 		perr(err);
38280Sstevel@tonic-gate 		break;
38290Sstevel@tonic-gate 	}
38300Sstevel@tonic-gate 
38310Sstevel@tonic-gate 	if (eres != NULL) {
38320Sstevel@tonic-gate 		(void) __ns_ldap_freeResult(&eres);
38330Sstevel@tonic-gate 		eres = NULL;
38340Sstevel@tonic-gate 	}
38350Sstevel@tonic-gate 
38360Sstevel@tonic-gate 	if (success) {
38370Sstevel@tonic-gate 		while (!done) {
38380Sstevel@tonic-gate 			rc = __ns_ldap_nextEntry(cookie, &eres, &err);
38390Sstevel@tonic-gate 			if (rc != NS_LDAP_SUCCESS || eres  == NULL) {
38400Sstevel@tonic-gate 				done = 1;
38410Sstevel@tonic-gate 				continue;
38420Sstevel@tonic-gate 			}
38430Sstevel@tonic-gate 
38440Sstevel@tonic-gate 			/* Print the result */
38450Sstevel@tonic-gate 			if (eres != NULL) {
38460Sstevel@tonic-gate 				if (strcmp(databasetype, "publickey") == 0)
38470Sstevel@tonic-gate 					dump_publickey(eres, service);
38480Sstevel@tonic-gate 				else
38490Sstevel@tonic-gate 					(*(tt->dump))(eres);
38500Sstevel@tonic-gate 				(void) __ns_ldap_freeResult(&eres);
38510Sstevel@tonic-gate 				eres = NULL;
38520Sstevel@tonic-gate 			}
38530Sstevel@tonic-gate 		}
38540Sstevel@tonic-gate 	}
38550Sstevel@tonic-gate }
38560Sstevel@tonic-gate 
3857702Sth160488 int
38580Sstevel@tonic-gate main(int argc, char **argv)
38590Sstevel@tonic-gate {
38600Sstevel@tonic-gate 	char	*password;
38610Sstevel@tonic-gate 	int	c;
38620Sstevel@tonic-gate 	int	rc;
38630Sstevel@tonic-gate 	int	ldaprc;
38640Sstevel@tonic-gate 	int		authstried = 0;
3865*2830Sdjl 	int		supportedauth = 0, gssapi = 0;
38660Sstevel@tonic-gate 	int		op = OP_ADD;
38670Sstevel@tonic-gate 	char	*ttype, *authmech = 0, *etcfile = 0;
38680Sstevel@tonic-gate 	char	ps[LDAP_MAXNAMELEN]; /* Temporary password variable */
38690Sstevel@tonic-gate 	char	filter[BUFSIZ];
38700Sstevel@tonic-gate 	void	**paramVal = NULL;
38710Sstevel@tonic-gate 	ns_auth_t	**app;
38720Sstevel@tonic-gate 	ns_auth_t	**authpp = NULL;
38730Sstevel@tonic-gate 	ns_auth_t	*authp = NULL;
38740Sstevel@tonic-gate 	ns_ldap_error_t	*errorp = NULL;
38750Sstevel@tonic-gate 	ns_ldap_result_t *resultp;
38760Sstevel@tonic-gate 	ns_ldap_entry_t *e;
38770Sstevel@tonic-gate 	int	flag = 0;
38780Sstevel@tonic-gate 	int	version1 = 0;
38790Sstevel@tonic-gate 
38800Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
38810Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
38820Sstevel@tonic-gate 
38830Sstevel@tonic-gate 	openlog("ldapaddent", LOG_PID, LOG_USER);
38840Sstevel@tonic-gate 
38850Sstevel@tonic-gate 	inputbasedn = NULL;
38860Sstevel@tonic-gate 	authority.cred.unix_cred.passwd = NULL;
38870Sstevel@tonic-gate 	authority.cred.unix_cred.userID = NULL;
38880Sstevel@tonic-gate 	authority.auth.type = NS_LDAP_AUTH_SIMPLE;
38890Sstevel@tonic-gate 
38900Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "cdhvpf:D:w:b:a:")) != EOF) {
38910Sstevel@tonic-gate 		switch (c) {
38920Sstevel@tonic-gate 		case 'd':
38930Sstevel@tonic-gate 			if (op)
38940Sstevel@tonic-gate 				usage("no other option should be specified");
38950Sstevel@tonic-gate 			op = OP_DUMP;
38960Sstevel@tonic-gate 			break;
38970Sstevel@tonic-gate 		case 'c':
38980Sstevel@tonic-gate 			continue_onerror = 1;
38990Sstevel@tonic-gate 			break;
39000Sstevel@tonic-gate 		case 'v':
39010Sstevel@tonic-gate 			flags |= F_VERBOSE;
39020Sstevel@tonic-gate 			break;
39030Sstevel@tonic-gate 		case 'p':
39040Sstevel@tonic-gate 			flags |= F_PASSWD;
39050Sstevel@tonic-gate 			break;
39060Sstevel@tonic-gate 		case 'f':
39070Sstevel@tonic-gate 			etcfile = optarg;
39080Sstevel@tonic-gate 			break;
39090Sstevel@tonic-gate 		case 'D':
39100Sstevel@tonic-gate 			authority.cred.unix_cred.userID = strdup(optarg);
39110Sstevel@tonic-gate 			break;
39120Sstevel@tonic-gate 		case 'w':
39130Sstevel@tonic-gate 			authority.cred.unix_cred.passwd = strdup(optarg);
39140Sstevel@tonic-gate 			break;
39150Sstevel@tonic-gate 		case 'b':
39160Sstevel@tonic-gate 			inputbasedn = strdup(optarg);
39170Sstevel@tonic-gate 			break;
39180Sstevel@tonic-gate 		case 'a':
39190Sstevel@tonic-gate 			authmech = strdup(optarg);
39200Sstevel@tonic-gate 			break;
39210Sstevel@tonic-gate 
39220Sstevel@tonic-gate 		default:
39230Sstevel@tonic-gate 			usage(gettext("Invalid option"));
39240Sstevel@tonic-gate 		}
39250Sstevel@tonic-gate 	}
39260Sstevel@tonic-gate 
39270Sstevel@tonic-gate 
39280Sstevel@tonic-gate 	if (authority.cred.unix_cred.userID == NULL && op != OP_DUMP) {
39290Sstevel@tonic-gate 	    /* This is not an optional parameter. Exit */
39300Sstevel@tonic-gate 		(void) fprintf(stderr,
39310Sstevel@tonic-gate 			gettext("Distinguished Name to bind to directory"
39320Sstevel@tonic-gate 				" must be specified. use option -D.\n"));
39330Sstevel@tonic-gate 		exit(1);
39340Sstevel@tonic-gate 	}
39350Sstevel@tonic-gate 
39360Sstevel@tonic-gate 	if (authority.cred.unix_cred.passwd == NULL && op != OP_DUMP) {
39370Sstevel@tonic-gate 		/* If password is not specified, then prompt user for it. */
39380Sstevel@tonic-gate 		password = getpassphrase("Enter password:");
39390Sstevel@tonic-gate 		(void) strcpy(ps, password);
39400Sstevel@tonic-gate 		authority.cred.unix_cred.passwd = strdup(ps);
39410Sstevel@tonic-gate 	}
39420Sstevel@tonic-gate 
39430Sstevel@tonic-gate 	if (authmech != NULL) {
39440Sstevel@tonic-gate 		if (strcasecmp(authmech, "simple") == 0) {
39450Sstevel@tonic-gate 		authority.auth.type = NS_LDAP_AUTH_SIMPLE;
39460Sstevel@tonic-gate 		authority.auth.tlstype = NS_LDAP_TLS_NONE;
39470Sstevel@tonic-gate 		authority.auth.saslmech = NS_LDAP_SASL_NONE;
39480Sstevel@tonic-gate 		authority.auth.saslopt = NS_LDAP_SASLOPT_NONE;
39490Sstevel@tonic-gate 		supportedauth = 1;
39500Sstevel@tonic-gate 		}
39510Sstevel@tonic-gate 		if (strcasecmp(authmech, "sasl/CRAM-MD5") == 0) {
39520Sstevel@tonic-gate 		authority.auth.type = NS_LDAP_AUTH_SASL;
39530Sstevel@tonic-gate 		authority.auth.tlstype = NS_LDAP_TLS_SASL;
39540Sstevel@tonic-gate 		authority.auth.saslmech = NS_LDAP_SASL_CRAM_MD5;
39550Sstevel@tonic-gate 		authority.auth.saslopt = NS_LDAP_SASLOPT_NONE;
39560Sstevel@tonic-gate 		supportedauth = 1;
39570Sstevel@tonic-gate 		}
39580Sstevel@tonic-gate 		if (strcasecmp(authmech, "sasl/DIGEST-MD5") == 0) {
39590Sstevel@tonic-gate 		authority.auth.type = NS_LDAP_AUTH_SASL;
39600Sstevel@tonic-gate 		authority.auth.tlstype = NS_LDAP_TLS_SASL;
39610Sstevel@tonic-gate 		authority.auth.saslmech = NS_LDAP_SASL_DIGEST_MD5;
39620Sstevel@tonic-gate 		authority.auth.saslopt = NS_LDAP_SASLOPT_NONE;
39630Sstevel@tonic-gate 		supportedauth = 1;
39640Sstevel@tonic-gate 		}
3965*2830Sdjl 		if (strcasecmp(authmech, "sasl/GSSAPI") == 0) {
3966*2830Sdjl 		authority.auth.type = NS_LDAP_AUTH_SASL;
3967*2830Sdjl 		authority.auth.tlstype = NS_LDAP_TLS_SASL;
3968*2830Sdjl 		authority.auth.saslmech = NS_LDAP_SASL_GSSAPI;
3969*2830Sdjl 		authority.auth.saslopt = NS_LDAP_SASLOPT_PRIV |
3970*2830Sdjl 					NS_LDAP_SASLOPT_INT;
3971*2830Sdjl 		gssapi = 1;
3972*2830Sdjl 		supportedauth = 1;
3973*2830Sdjl 		}
39740Sstevel@tonic-gate 		if (strcasecmp(authmech, "tls:simple") == 0) {
39750Sstevel@tonic-gate 		authority.auth.type = NS_LDAP_AUTH_TLS;
39760Sstevel@tonic-gate 		authority.auth.tlstype = NS_LDAP_TLS_SIMPLE;
39770Sstevel@tonic-gate 		authority.auth.saslmech = NS_LDAP_SASL_NONE;
39780Sstevel@tonic-gate 		authority.auth.saslopt = NS_LDAP_SASLOPT_NONE;
39790Sstevel@tonic-gate 		supportedauth = 1;
39800Sstevel@tonic-gate 		}
39810Sstevel@tonic-gate 		if (strcasecmp(authmech, "tls:sasl/CRAM-MD5") == 0) {
39820Sstevel@tonic-gate 		authority.auth.type = NS_LDAP_AUTH_TLS;
39830Sstevel@tonic-gate 		authority.auth.tlstype = NS_LDAP_TLS_SASL;
39840Sstevel@tonic-gate 		authority.auth.saslmech = NS_LDAP_SASL_CRAM_MD5;
39850Sstevel@tonic-gate 		authority.auth.saslopt = NS_LDAP_SASLOPT_NONE;
39860Sstevel@tonic-gate 		supportedauth = 1;
39870Sstevel@tonic-gate 		}
39880Sstevel@tonic-gate 		if (strcasecmp(authmech, "tls:sasl/DIGEST-MD5") == 0) {
39890Sstevel@tonic-gate 		authority.auth.type = NS_LDAP_AUTH_TLS;
39900Sstevel@tonic-gate 		authority.auth.tlstype = NS_LDAP_TLS_SASL;
39910Sstevel@tonic-gate 		authority.auth.saslmech = NS_LDAP_SASL_DIGEST_MD5;
39920Sstevel@tonic-gate 		authority.auth.saslopt = NS_LDAP_SASLOPT_NONE;
39930Sstevel@tonic-gate 		supportedauth = 1;
39940Sstevel@tonic-gate 		}
39950Sstevel@tonic-gate 		if (!supportedauth) {
39960Sstevel@tonic-gate 			(void) fprintf(stderr,
39970Sstevel@tonic-gate 			gettext("Invalid authentication method specified"));
39980Sstevel@tonic-gate 			exit(1);
39990Sstevel@tonic-gate 		}
40000Sstevel@tonic-gate 	}
40010Sstevel@tonic-gate 
4002*2830Sdjl 	if (!gssapi && authority.cred.unix_cred.userID == NULL &&
4003*2830Sdjl 			op != OP_DUMP) {
4004*2830Sdjl 	    /* This is not an optional parameter. Exit */
4005*2830Sdjl 		(void) fprintf(stderr,
4006*2830Sdjl 			gettext("Distinguished Name to bind to directory"
4007*2830Sdjl 				" must be specified. use option -D.\n"));
4008*2830Sdjl 		exit(1);
4009*2830Sdjl 	}
4010*2830Sdjl 
4011*2830Sdjl 	if (!gssapi && authority.cred.unix_cred.passwd == NULL &&
4012*2830Sdjl 			op != OP_DUMP) {
4013*2830Sdjl 		/* If password is not specified, then prompt user for it. */
4014*2830Sdjl 		password = getpassphrase("Enter password:");
4015*2830Sdjl 		(void) strcpy(ps, password);
4016*2830Sdjl 		authority.cred.unix_cred.passwd = strdup(ps);
4017*2830Sdjl 	}
4018*2830Sdjl 
40190Sstevel@tonic-gate 	if (authmech == NULL) {
40200Sstevel@tonic-gate 		ldaprc = __ns_ldap_getParam(NS_LDAP_AUTH_P, (void ***)&authpp,
40210Sstevel@tonic-gate 			&errorp);
40220Sstevel@tonic-gate 		if (ldaprc != NS_LDAP_SUCCESS ||
40230Sstevel@tonic-gate 		    (authpp == NULL && op != OP_DUMP)) {
40240Sstevel@tonic-gate 			(void) fprintf(stderr,
40250Sstevel@tonic-gate 			    gettext("No legal authentication method "
40260Sstevel@tonic-gate 			    "configured.\n"));
40270Sstevel@tonic-gate 			(void) fprintf(stderr,
40280Sstevel@tonic-gate 			    gettext("Provide a legal authentication method "
40290Sstevel@tonic-gate 			    "using -a option\n"));
40300Sstevel@tonic-gate 			exit(1);
40310Sstevel@tonic-gate 		}
40320Sstevel@tonic-gate 
40330Sstevel@tonic-gate 		/* Use the first authentication method which is not none */
40340Sstevel@tonic-gate 		for (app = authpp; *app; app++) {
40350Sstevel@tonic-gate 			authp = *app;
40360Sstevel@tonic-gate 			if (authp->type != NS_LDAP_AUTH_NONE) {
40370Sstevel@tonic-gate 				authstried++;
40380Sstevel@tonic-gate 				authority.auth.type = authp->type;
40390Sstevel@tonic-gate 				authority.auth.tlstype = authp->tlstype;
40400Sstevel@tonic-gate 				authority.auth.saslmech = authp->saslmech;
40410Sstevel@tonic-gate 				authority.auth.saslopt = authp->saslopt;
40420Sstevel@tonic-gate 				break;
40430Sstevel@tonic-gate 			}
40440Sstevel@tonic-gate 		}
40450Sstevel@tonic-gate 		if (authstried == 0 && op != OP_DUMP) {
40460Sstevel@tonic-gate 			(void) fprintf(stderr,
40470Sstevel@tonic-gate 			gettext("No legal authentication method configured.\n"
40480Sstevel@tonic-gate 				"Provide a legal authentication method using "
40490Sstevel@tonic-gate 				"-a option"));
40500Sstevel@tonic-gate 			exit(1);
40510Sstevel@tonic-gate 		}
4052*2830Sdjl 		if (authority.auth.saslmech == NS_LDAP_SASL_GSSAPI &&
4053*2830Sdjl 				authority.cred.unix_cred.passwd != NULL &&
4054*2830Sdjl 				authority.cred.unix_cred.userID != NULL) {
4055*2830Sdjl 			/*
4056*2830Sdjl 			 * -a is not specified and the auth method sasl/GSSAPI
4057*2830Sdjl 			 * is defined in the configuration of the ldap profile.
4058*2830Sdjl 			 * Even -D and -w is provided it's not valid usage.
4059*2830Sdjl 			 */
4060*2830Sdjl 
4061*2830Sdjl 			(void) fprintf(stderr,
4062*2830Sdjl 			gettext("The default authentication is sasl/GSSAPI.\n"
4063*2830Sdjl 				"The bind DN and and password is not allowed."
4064*2830Sdjl 				"\n"));
4065*2830Sdjl 			exit(1);
4066*2830Sdjl 		}
40670Sstevel@tonic-gate 	}
40680Sstevel@tonic-gate 
40690Sstevel@tonic-gate 	ttype = argv[optind++];
40700Sstevel@tonic-gate 
40710Sstevel@tonic-gate 	if (ttype == NULL) {
40720Sstevel@tonic-gate 		usage(gettext("No database type specified"));
40730Sstevel@tonic-gate 		exit(1);
40740Sstevel@tonic-gate 	}
40750Sstevel@tonic-gate 
40760Sstevel@tonic-gate 	if (strncasecmp(ttype, "automount", 9) == 0) {
40770Sstevel@tonic-gate 		(void) fprintf(stderr,
40780Sstevel@tonic-gate 		    gettext("automount is not a valid service for ldapaddent.\n"
40790Sstevel@tonic-gate 		    "Please use auto_*.\n"
40800Sstevel@tonic-gate 		    "e.g.  auto_home, auto_ws etc.\n "));
40810Sstevel@tonic-gate 		exit(1);
40820Sstevel@tonic-gate 	}
40830Sstevel@tonic-gate 
40840Sstevel@tonic-gate 	for (tt = ttypelist; tt->ttype; tt++) {
40850Sstevel@tonic-gate 		if (strcmp(tt->ttype, ttype) == 0)
40860Sstevel@tonic-gate 			break;
40870Sstevel@tonic-gate 		if (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0 &&
40880Sstevel@tonic-gate 		    strncmp(ttype, NS_LDAP_TYPE_AUTOMOUNT,
40890Sstevel@tonic-gate 		    sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0)
40900Sstevel@tonic-gate 			break;
40910Sstevel@tonic-gate 	}
40920Sstevel@tonic-gate 
40930Sstevel@tonic-gate 	if (tt->ttype == 0) {
40940Sstevel@tonic-gate 		(void) fprintf(stderr,
40950Sstevel@tonic-gate 		    gettext("database %s not supported;"
40960Sstevel@tonic-gate 		    " supported databases are:\n"), ttype);
40970Sstevel@tonic-gate 		for (tt = ttypelist; tt->ttype; tt++)
40980Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("\t%s\n"), tt->ttype);
40990Sstevel@tonic-gate 		exit(1);
41000Sstevel@tonic-gate 	}
41010Sstevel@tonic-gate 
41020Sstevel@tonic-gate 	if (flags & F_VERBOSE)
41030Sstevel@tonic-gate 		(void) fprintf(stdout, gettext("SERVICE = %s\n"), tt->ttype);
41040Sstevel@tonic-gate 
41050Sstevel@tonic-gate 	databasetype = ttype;
41060Sstevel@tonic-gate 
41070Sstevel@tonic-gate 	if (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0) {
41080Sstevel@tonic-gate 		paramVal = NULL;
41090Sstevel@tonic-gate 		errorp = NULL;
41100Sstevel@tonic-gate 		rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, &paramVal,
41110Sstevel@tonic-gate 			&errorp);
41120Sstevel@tonic-gate 		if (paramVal && *paramVal &&
41130Sstevel@tonic-gate 			strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0)
41140Sstevel@tonic-gate 			version1 = 1;
41150Sstevel@tonic-gate 		if (paramVal)
41160Sstevel@tonic-gate 			(void) __ns_ldap_freeParam(&paramVal);
41170Sstevel@tonic-gate 		if (errorp)
41180Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&errorp);
41190Sstevel@tonic-gate 	}
41200Sstevel@tonic-gate 
41210Sstevel@tonic-gate 	/* Check if the container exists in first place */
41220Sstevel@tonic-gate 	(void) strcpy(&filter[0], "(objectclass=*)");
41230Sstevel@tonic-gate 
41240Sstevel@tonic-gate 	rc = __ns_ldap_list(databasetype, filter, NULL, (const char **)NULL,
41250Sstevel@tonic-gate 	    NULL, NS_LDAP_SCOPE_BASE, &resultp, &errorp, NULL, NULL);
41260Sstevel@tonic-gate 
41270Sstevel@tonic-gate 	/* create a container for auto_* if it does not exist already */
41280Sstevel@tonic-gate 	if ((rc == NS_LDAP_NOTFOUND) && (op == OP_ADD) &&
41290Sstevel@tonic-gate 	    (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0)) {
41300Sstevel@tonic-gate 		static	char *oclist[] = {NULL, "top", NULL};
41310Sstevel@tonic-gate 		if (version1)
41320Sstevel@tonic-gate 			oclist[0] = "nisMap";
41330Sstevel@tonic-gate 		else
41340Sstevel@tonic-gate 			oclist[0] = "automountMap";
41350Sstevel@tonic-gate 		e = __s_mk_entry(oclist, 3);
41360Sstevel@tonic-gate 		if (e == NULL) {
41370Sstevel@tonic-gate 			(void) fprintf(stderr,
41380Sstevel@tonic-gate 			    gettext("internal memory allocation error.\n"));
41390Sstevel@tonic-gate 			exit(1);
41400Sstevel@tonic-gate 		}
41410Sstevel@tonic-gate 		if (__s_add_attr(e,
41420Sstevel@tonic-gate 		    version1 ? "nisMapName" : "automountMapName",
41430Sstevel@tonic-gate 		    databasetype) != NS_LDAP_SUCCESS) {
41440Sstevel@tonic-gate 			(void) fprintf(stderr,
41450Sstevel@tonic-gate 			    gettext("internal memory allocation error.\n"));
41460Sstevel@tonic-gate 			ldap_freeEntry(e);
41470Sstevel@tonic-gate 			exit(1);
41480Sstevel@tonic-gate 		}
41490Sstevel@tonic-gate 
41500Sstevel@tonic-gate 		if (inputbasedn == NULL) {
41510Sstevel@tonic-gate 			if (get_basedn(databasetype, &inputbasedn) !=
41520Sstevel@tonic-gate 			    NS_LDAP_SUCCESS) {
41530Sstevel@tonic-gate 				(void) fprintf(stderr,
41540Sstevel@tonic-gate 				    gettext("Could not obtain basedn\n"));
41550Sstevel@tonic-gate 				ldap_freeEntry(e);
41560Sstevel@tonic-gate 				exit(1);
41570Sstevel@tonic-gate 			}
41580Sstevel@tonic-gate 		}
41590Sstevel@tonic-gate 		if (__ns_ldap_addEntry(databasetype, inputbasedn, e,
41600Sstevel@tonic-gate 		    &authority, flag, &errorp) != NS_LDAP_SUCCESS) {
41610Sstevel@tonic-gate 			(void) fprintf(stderr,
41620Sstevel@tonic-gate 			    gettext("Could not create container for %s\n"),
41630Sstevel@tonic-gate 			    databasetype);
41640Sstevel@tonic-gate 			ldap_freeEntry(e);
41650Sstevel@tonic-gate 		}
41660Sstevel@tonic-gate 	} else if (strcmp(databasetype, "publickey") != 0) {
41670Sstevel@tonic-gate 		if (rc == NS_LDAP_NOTFOUND) {
41680Sstevel@tonic-gate 			(void) fprintf(stderr,
41690Sstevel@tonic-gate 			    gettext("Container %s does not exist\n"),
41700Sstevel@tonic-gate 			    databasetype);
41710Sstevel@tonic-gate 			exit(1);
41720Sstevel@tonic-gate 		}
41730Sstevel@tonic-gate 	}
41740Sstevel@tonic-gate 
41750Sstevel@tonic-gate 	if (op == OP_DUMP) {
41760Sstevel@tonic-gate 		if (strcmp(databasetype, "publickey") == 0) {
41770Sstevel@tonic-gate 			dumptable("hosts");
41780Sstevel@tonic-gate 			dumptable("passwd");
41790Sstevel@tonic-gate 		} else {
41800Sstevel@tonic-gate 			dumptable(databasetype);
41810Sstevel@tonic-gate 		}
41820Sstevel@tonic-gate 		exit(exit_val);
41830Sstevel@tonic-gate 	}
41840Sstevel@tonic-gate 
41850Sstevel@tonic-gate 	if (etcfile) {
41860Sstevel@tonic-gate 		if ((etcf = fopen(etcfile, "r")) == 0) {
41870Sstevel@tonic-gate 			(void) fprintf(stderr,
41880Sstevel@tonic-gate 			    gettext("can't open file %s\n"), etcfile);
41890Sstevel@tonic-gate 			exit(1);
41900Sstevel@tonic-gate 		}
41910Sstevel@tonic-gate 	} else {
41920Sstevel@tonic-gate 		etcfile = "stdin";
41930Sstevel@tonic-gate 		etcf = stdin;
41940Sstevel@tonic-gate 	}
41950Sstevel@tonic-gate 
41960Sstevel@tonic-gate 	if (op == OP_ADD) {
41970Sstevel@tonic-gate 		(void) addfile();
41980Sstevel@tonic-gate 		(void) fprintf(stdout, gettext("%d entries added\n"), nent_add);
41990Sstevel@tonic-gate 	}
42000Sstevel@tonic-gate 
4201839Smj162486 	/* exit() -> return for make lint */
4202839Smj162486 	return (exit_val);
42030Sstevel@tonic-gate }
42040Sstevel@tonic-gate 
42050Sstevel@tonic-gate 
42060Sstevel@tonic-gate /*
42070Sstevel@tonic-gate  * This is called when service == auto_*.
42080Sstevel@tonic-gate  * It calls __ns_ldap_getSearchDescriptors
42090Sstevel@tonic-gate  * to generate the dn from SSD's base dn.
42100Sstevel@tonic-gate  * If there is no SSD available,
42110Sstevel@tonic-gate  * default base dn will be used
42120Sstevel@tonic-gate  * Only the first baseDN in the SSD is used
42130Sstevel@tonic-gate  */
42140Sstevel@tonic-gate 
42150Sstevel@tonic-gate static int get_basedn(char *service, char **basedn) {
42160Sstevel@tonic-gate 	int rc = NS_LDAP_SUCCESS;
42170Sstevel@tonic-gate 	char *dn = NULL;
42180Sstevel@tonic-gate 	ns_ldap_search_desc_t **desc = NULL;
42190Sstevel@tonic-gate 	ns_ldap_error_t *errp = NULL;
42200Sstevel@tonic-gate 	void		**paramVal = NULL;
42210Sstevel@tonic-gate 	int		prepend_automountmapname = FALSE;
42220Sstevel@tonic-gate 
42230Sstevel@tonic-gate 	/*
42240Sstevel@tonic-gate 	 * Get auto_* SSD first
42250Sstevel@tonic-gate 	 */
42260Sstevel@tonic-gate 
42270Sstevel@tonic-gate 	if ((rc = __ns_ldap_getSearchDescriptors(
42280Sstevel@tonic-gate 			(const char *) service,
42290Sstevel@tonic-gate 			&desc, &errp))  == NS_LDAP_SUCCESS &&
42300Sstevel@tonic-gate 		desc != NULL) {
42310Sstevel@tonic-gate 
42320Sstevel@tonic-gate 		if (desc[0] != NULL && desc[0]->basedn != NULL) {
42330Sstevel@tonic-gate 			dn = strdup(desc[0]->basedn);
42340Sstevel@tonic-gate 			if (dn == NULL) {
42350Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors
42360Sstevel@tonic-gate 						(&desc);
42370Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
42380Sstevel@tonic-gate 			}
42390Sstevel@tonic-gate 		}
42400Sstevel@tonic-gate 	}
42410Sstevel@tonic-gate 
42420Sstevel@tonic-gate 	/* clean up */
42430Sstevel@tonic-gate 	if (desc) (void) __ns_ldap_freeSearchDescriptors(&desc);
42440Sstevel@tonic-gate 	if (errp) (void) __ns_ldap_freeError(&errp);
42450Sstevel@tonic-gate 
42460Sstevel@tonic-gate 	/*
42470Sstevel@tonic-gate 	 * If no dn is duplicated from auto_* SSD, try automount SSD
42480Sstevel@tonic-gate 	 */
42490Sstevel@tonic-gate 	if (dn == NULL) {
42500Sstevel@tonic-gate 		if ((rc = __ns_ldap_getSearchDescriptors(
42510Sstevel@tonic-gate 				"automount", &desc, &errp))
42520Sstevel@tonic-gate 				== NS_LDAP_SUCCESS && desc != NULL) {
42530Sstevel@tonic-gate 
42540Sstevel@tonic-gate 			if (desc[0] != NULL && desc[0]->basedn != NULL) {
42550Sstevel@tonic-gate 				dn = strdup(desc[0]->basedn);
42560Sstevel@tonic-gate 				if (dn == NULL) {
42570Sstevel@tonic-gate 					(void) __ns_ldap_freeSearchDescriptors
42580Sstevel@tonic-gate 							(&desc);
42590Sstevel@tonic-gate 					return (NS_LDAP_MEMORY);
42600Sstevel@tonic-gate 				}
42610Sstevel@tonic-gate 				prepend_automountmapname = TRUE;
42620Sstevel@tonic-gate 			}
42630Sstevel@tonic-gate 		}
42640Sstevel@tonic-gate 		/* clean up */
42650Sstevel@tonic-gate 		if (desc) (void) __ns_ldap_freeSearchDescriptors(&desc);
42660Sstevel@tonic-gate 		if (errp) (void) __ns_ldap_freeError(&errp);
42670Sstevel@tonic-gate 	}
42680Sstevel@tonic-gate 
42690Sstevel@tonic-gate 	/*
42700Sstevel@tonic-gate 	 * If no dn is duplicated from auto_* or automount SSD,
42710Sstevel@tonic-gate 	 * use default DN
42720Sstevel@tonic-gate 	 */
42730Sstevel@tonic-gate 
42740Sstevel@tonic-gate 	if (dn == NULL) {
42750Sstevel@tonic-gate 		if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P,
42760Sstevel@tonic-gate 			&paramVal, &errp)) == NS_LDAP_SUCCESS) {
42770Sstevel@tonic-gate 			dn = strdup((char *)paramVal[0]);
42780Sstevel@tonic-gate 			if (dn == NULL) {
42790Sstevel@tonic-gate 				(void) __ns_ldap_freeParam(&paramVal);
42800Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
42810Sstevel@tonic-gate 			}
42820Sstevel@tonic-gate 			prepend_automountmapname = TRUE;
42830Sstevel@tonic-gate 		}
42840Sstevel@tonic-gate 		if (paramVal) (void) __ns_ldap_freeParam(&paramVal);
42850Sstevel@tonic-gate 		if (errp) (void) __ns_ldap_freeError(&errp);
42860Sstevel@tonic-gate 	}
42870Sstevel@tonic-gate 
42880Sstevel@tonic-gate 
42890Sstevel@tonic-gate 	if (dn == NULL) {
42900Sstevel@tonic-gate 		return (NS_LDAP_OP_FAILED);
42910Sstevel@tonic-gate 	} else {
42920Sstevel@tonic-gate 		/*
42930Sstevel@tonic-gate 		 * If dn is duplicated from
42940Sstevel@tonic-gate 		 * automount SSD basedn or
42950Sstevel@tonic-gate 		 * default base dn
42960Sstevel@tonic-gate 		 * then prepend automountMapName=auto_xxx
42970Sstevel@tonic-gate 		 */
42980Sstevel@tonic-gate 		if (prepend_automountmapname)
42990Sstevel@tonic-gate 			rc = __s_api_prepend_automountmapname_to_dn(
43000Sstevel@tonic-gate 				service, &dn, &errp);
43010Sstevel@tonic-gate 
43020Sstevel@tonic-gate 		if (rc != NS_LDAP_SUCCESS) {
43030Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&errp);
43040Sstevel@tonic-gate 			free(dn);
43050Sstevel@tonic-gate 			return (rc);
43060Sstevel@tonic-gate 		}
43070Sstevel@tonic-gate 
43080Sstevel@tonic-gate 		*basedn = dn;
43090Sstevel@tonic-gate 
43100Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
43110Sstevel@tonic-gate 	}
43120Sstevel@tonic-gate }
4313*2830Sdjl static char *
4314*2830Sdjl h_errno2str(int h_errno) {
4315*2830Sdjl 	switch (h_errno) {
4316*2830Sdjl 	case HOST_NOT_FOUND:
4317*2830Sdjl 		return ("HOST_NOT_FOUND");
4318*2830Sdjl 		break;
4319*2830Sdjl 	case TRY_AGAIN:
4320*2830Sdjl 		return ("TRY_AGAIN");
4321*2830Sdjl 		break;
4322*2830Sdjl 	case NO_RECOVERY:
4323*2830Sdjl 		return ("NO_RECOVERY");
4324*2830Sdjl 		break;
4325*2830Sdjl 	case NO_DATA:
4326*2830Sdjl 		return ("NO_DATA");
4327*2830Sdjl 		break;
4328*2830Sdjl 	default:
4329*2830Sdjl 		break;
4330*2830Sdjl 	}
4331*2830Sdjl 	return ("UNKNOWN_ERROR");
4332*2830Sdjl }
4333