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 /*
22*6842Sth160488  * Copyright 2008 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>
55*6842Sth160488 #include <project.h>
560Sstevel@tonic-gate #include <shadow.h>
570Sstevel@tonic-gate #include <sys/systeminfo.h>
580Sstevel@tonic-gate #include "ns_internal.h"
590Sstevel@tonic-gate #include "ldapaddent.h"
60*6842Sth160488 #include "standalone.h"
610Sstevel@tonic-gate 
620Sstevel@tonic-gate #define	OP_ADD	0
630Sstevel@tonic-gate #define	OP_DUMP	3
640Sstevel@tonic-gate 
650Sstevel@tonic-gate static struct ttypelist_t {
660Sstevel@tonic-gate 	char *ttype;		/* type tag */
670Sstevel@tonic-gate 	int (*genent)(char *, int(*)());
680Sstevel@tonic-gate 				/* routine to turn line into ldap entries */
690Sstevel@tonic-gate 	void (*dump)(ns_ldap_result_t *);
700Sstevel@tonic-gate 				/* routine to print ldap containers */
710Sstevel@tonic-gate 	int (*filedbmline)();	/* routine to turn file line into dbm line */
720Sstevel@tonic-gate 	char *objclass;		/* Objectclass for the servicetype */
730Sstevel@tonic-gate } *tt;
740Sstevel@tonic-gate 
750Sstevel@tonic-gate char	parse_err_msg [PARSE_ERR_MSG_LEN];
760Sstevel@tonic-gate int	continue_onerror = 0;  /* do not exit on error */
770Sstevel@tonic-gate 
780Sstevel@tonic-gate static int get_basedn(char *service, char **basedn);
790Sstevel@tonic-gate static int check_ipaddr(char *addr, char **newaddr);
80*6842Sth160488 static int check_projname(char *addr);
810Sstevel@tonic-gate 
820Sstevel@tonic-gate extern	int	optind;
830Sstevel@tonic-gate extern	char	*optarg;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate extern	char	*__nis_quote_key(const char *, char *, int);
860Sstevel@tonic-gate 
870Sstevel@tonic-gate static char	*inputbasedn = NULL;
880Sstevel@tonic-gate static char	*databasetype = NULL;
890Sstevel@tonic-gate static int	exit_val = 0;
900Sstevel@tonic-gate static unsigned	nent_add = 0;
910Sstevel@tonic-gate static FILE	*etcf = 0;
920Sstevel@tonic-gate static ns_cred_t	authority;
930Sstevel@tonic-gate unsigned	flags = 0;
940Sstevel@tonic-gate 
950Sstevel@tonic-gate static void
960Sstevel@tonic-gate perr(ns_ldap_error_t *e)
970Sstevel@tonic-gate {
980Sstevel@tonic-gate 	if (e)
99*6842Sth160488 		(void) fprintf(stderr, "%d: %s\n",
100*6842Sth160488 		    e->status, e->message);
1010Sstevel@tonic-gate }
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate static int
1050Sstevel@tonic-gate ascii_to_int(char *str)
1060Sstevel@tonic-gate {
1070Sstevel@tonic-gate 	int i;
1080Sstevel@tonic-gate 	char *c = str;
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate 	if (c == NULL || *c == '\0')
1110Sstevel@tonic-gate 		return (-1);
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 	while (c != '\0' && *c == ' ')
1140Sstevel@tonic-gate 		c++;
1150Sstevel@tonic-gate 	if (*c == '\0')
1160Sstevel@tonic-gate 		return (-1);
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate 	for (i = 0; i < strlen(c); i++)
1190Sstevel@tonic-gate 		if (!isdigit(c[i]))
1200Sstevel@tonic-gate 			return (-1);
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate 	return (atoi(c));
1230Sstevel@tonic-gate }
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate /*
1260Sstevel@tonic-gate  * Internet network address interpretation routine.
1270Sstevel@tonic-gate  * The library routines call this routine to interpret
1280Sstevel@tonic-gate  * network numbers.
1290Sstevel@tonic-gate  */
1300Sstevel@tonic-gate static in_addr_t
1310Sstevel@tonic-gate encode_network(const char *cp)
1320Sstevel@tonic-gate {
1330Sstevel@tonic-gate 	in_addr_t val;
1340Sstevel@tonic-gate 	int base;
1350Sstevel@tonic-gate 	ptrdiff_t n;
1360Sstevel@tonic-gate 	char c;
1370Sstevel@tonic-gate 	in_addr_t parts[4], *pp = parts;
1380Sstevel@tonic-gate 	int i;
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate again:
1410Sstevel@tonic-gate 	val = 0; base = 10;
1420Sstevel@tonic-gate 	if (*cp == '0') {
1430Sstevel@tonic-gate 		if (*++cp == 'x' || *cp == 'X')
1440Sstevel@tonic-gate 			base = 16, cp++;
1450Sstevel@tonic-gate 		else
1460Sstevel@tonic-gate 			base = 8;
1470Sstevel@tonic-gate 	}
1480Sstevel@tonic-gate 	while ((c = *cp) != NULL) {
1490Sstevel@tonic-gate 		if (isdigit(c)) {
1500Sstevel@tonic-gate 			if ((c - '0') >= base)
151*6842Sth160488 				break;
1520Sstevel@tonic-gate 			val = (val * base) + (c - '0');
1530Sstevel@tonic-gate 			cp++;
1540Sstevel@tonic-gate 			continue;
1550Sstevel@tonic-gate 		}
1560Sstevel@tonic-gate 		if (base == 16 && isxdigit(c)) {
1570Sstevel@tonic-gate 			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
1580Sstevel@tonic-gate 			cp++;
1590Sstevel@tonic-gate 			continue;
1600Sstevel@tonic-gate 		}
1610Sstevel@tonic-gate 		break;
1620Sstevel@tonic-gate 	}
1630Sstevel@tonic-gate 	if (*cp == '.') {
1640Sstevel@tonic-gate 		if (pp >= parts + 4)
1650Sstevel@tonic-gate 			return ((in_addr_t)-1);
1660Sstevel@tonic-gate 		*pp++ = val, cp++;
1670Sstevel@tonic-gate 		goto again;
1680Sstevel@tonic-gate 	}
1690Sstevel@tonic-gate 	if (*cp && !isspace(*cp))
1700Sstevel@tonic-gate 		return ((in_addr_t)-1);
1710Sstevel@tonic-gate 	*pp++ = val;
1720Sstevel@tonic-gate 	n = pp - parts;
1730Sstevel@tonic-gate 	if (n > 4)
1740Sstevel@tonic-gate 		return ((in_addr_t)-1);
1750Sstevel@tonic-gate 	for (val = 0, i = 0; i < n; i++) {
1760Sstevel@tonic-gate 		val <<= 8;
1770Sstevel@tonic-gate 		val |= parts[i] & 0xff;
1780Sstevel@tonic-gate 	}
1790Sstevel@tonic-gate 	for (/* no init */; i < 4; i++)
1800Sstevel@tonic-gate 		val <<= 8;
1810Sstevel@tonic-gate 	return (val);
1820Sstevel@tonic-gate }
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate static void
1850Sstevel@tonic-gate replace_tab2space(char *str)
1860Sstevel@tonic-gate {
1870Sstevel@tonic-gate 	int i = 0;
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate 	while ((str) && (str[i])) {
1900Sstevel@tonic-gate 		if (str[i] == '\t')
1910Sstevel@tonic-gate 			str[i] = ' ';
1920Sstevel@tonic-gate 		i++;
1930Sstevel@tonic-gate 	}
1940Sstevel@tonic-gate }
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate static int
1970Sstevel@tonic-gate blankline(char *line)
1980Sstevel@tonic-gate {
1990Sstevel@tonic-gate 	char *p;
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	for (p = line; *p; p++)
2020Sstevel@tonic-gate 		if (*p != ' ' && *p != '\t')
2030Sstevel@tonic-gate 			return (0);
2040Sstevel@tonic-gate 	return (1);
2050Sstevel@tonic-gate }
2060Sstevel@tonic-gate 
2071603Svl199446 /*
2081603Svl199446  * check whether the token <tok> is a triplet,
2091603Svl199446  * i. e. <tok> := (<hostname>,<username>,<domainname>)
2101603Svl199446  * where <hostname>, <username>, <domainname> are IA5String
2111603Svl199446  * <tok> supposes to contain NO spaces and start with '('
2121603Svl199446  */
2131603Svl199446 static int
2141603Svl199446 is_triplet(char *tok)
2151603Svl199446 {
2161603Svl199446 	char *s;
2171603Svl199446 	return (strchr(++tok, '(') == NULL &&		/* no more '(' */
218*6842Sth160488 	    (s = strchr(tok, ')')) != NULL &&		/* find ')' */
219*6842Sth160488 	    !*++s &&					/* ')' ends token */
220*6842Sth160488 	    (tok = strchr(tok, ',')) != NULL &&		/* host up to ',' */
221*6842Sth160488 	    (tok = strchr(++tok, ',')) != NULL &&	/* user up to ',' */
222*6842Sth160488 	    strchr(++tok, ',') == NULL);		/* no more ',' */
2231603Svl199446 }
2241603Svl199446 
2250Sstevel@tonic-gate static void
2260Sstevel@tonic-gate line_buf_expand(struct line_buf *line)
2270Sstevel@tonic-gate {
2280Sstevel@tonic-gate 	line->alloc += BUFSIZ;
2290Sstevel@tonic-gate 	line->str = (char *)realloc(line->str, line->alloc);
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate 	if (line->str == NULL) {
2320Sstevel@tonic-gate 		(void) fprintf(stderr,
2330Sstevel@tonic-gate 		    gettext("line_buf_expand: out of memory\n"));
2340Sstevel@tonic-gate 		exit(1);
2350Sstevel@tonic-gate 	}
2360Sstevel@tonic-gate }
2370Sstevel@tonic-gate 
2380Sstevel@tonic-gate static void
2390Sstevel@tonic-gate line_buf_init(struct line_buf *line)
2400Sstevel@tonic-gate {
2410Sstevel@tonic-gate 	(void) memset((char *)line, 0, sizeof (*line));
2420Sstevel@tonic-gate 	line_buf_expand(line);
2430Sstevel@tonic-gate }
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate static int
2460Sstevel@tonic-gate __s_add_attr(ns_ldap_entry_t *e, char *attrname, char *value)
2470Sstevel@tonic-gate {
2480Sstevel@tonic-gate 	ns_ldap_attr_t	*a;
2490Sstevel@tonic-gate 	char		*v;
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 	a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t));
2520Sstevel@tonic-gate 	if (a == NULL)
2530Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2540Sstevel@tonic-gate 	a->attrname = strdup(attrname);
2550Sstevel@tonic-gate 	if (a->attrname == NULL) {
2560Sstevel@tonic-gate 		free(a);
2570Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2580Sstevel@tonic-gate 	}
2590Sstevel@tonic-gate 	a->attrvalue = (char **)calloc(1, sizeof (char **));
2600Sstevel@tonic-gate 	if (a->attrvalue == NULL) {
2610Sstevel@tonic-gate 		free(a->attrname);
2620Sstevel@tonic-gate 		free(a);
2630Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2640Sstevel@tonic-gate 	}
2650Sstevel@tonic-gate 	a->value_count = 1;
2660Sstevel@tonic-gate 	a->attrvalue[0] = NULL;
2670Sstevel@tonic-gate 	v = strdup(value);
2680Sstevel@tonic-gate 	if (v == NULL) {
2690Sstevel@tonic-gate 		free(a->attrname);
2700Sstevel@tonic-gate 		free(a->attrvalue);
2710Sstevel@tonic-gate 		free(a);
2720Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2730Sstevel@tonic-gate 	}
2740Sstevel@tonic-gate 	a->attrvalue[0] = v;
2750Sstevel@tonic-gate 	e->attr_pair[e->attr_count] = a;
2760Sstevel@tonic-gate 	e->attr_count++;
2770Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
2780Sstevel@tonic-gate }
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate static int
2810Sstevel@tonic-gate __s_add_attrlist(ns_ldap_entry_t *e, char *attrname, char **argv)
2820Sstevel@tonic-gate {
2830Sstevel@tonic-gate 	ns_ldap_attr_t	*a;
2840Sstevel@tonic-gate 	char		*v;
2850Sstevel@tonic-gate 	char		**av;
2860Sstevel@tonic-gate 	int		i, j;
2870Sstevel@tonic-gate 
2880Sstevel@tonic-gate 	a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t));
2890Sstevel@tonic-gate 	if (a == NULL)
2900Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2910Sstevel@tonic-gate 	a->attrname = strdup(attrname);
2920Sstevel@tonic-gate 	if (a->attrname == NULL) {
2930Sstevel@tonic-gate 		free(a);
2940Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2950Sstevel@tonic-gate 	}
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate 	for (i = 0, av = argv; *av != NULL; av++, i++)
2980Sstevel@tonic-gate 		;
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate 	a->attrvalue = (char **)calloc(i, sizeof (char **));
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate 	if (a->attrvalue == NULL) {
3030Sstevel@tonic-gate 		free(a->attrname);
3040Sstevel@tonic-gate 		free(a);
3050Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
3060Sstevel@tonic-gate 	}
3070Sstevel@tonic-gate 	a->value_count = i;
3080Sstevel@tonic-gate 	for (j = 0; j < i; j++) {
3090Sstevel@tonic-gate 		v = strdup(argv[j]);
3100Sstevel@tonic-gate 		if (v == NULL) {
3110Sstevel@tonic-gate 			free(a->attrname);
3120Sstevel@tonic-gate 			free(a->attrvalue);
3130Sstevel@tonic-gate 			free(a);
3140Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
3150Sstevel@tonic-gate 		}
3160Sstevel@tonic-gate 		a->attrvalue[j] = v;
3170Sstevel@tonic-gate 	}
3180Sstevel@tonic-gate 	e->attr_pair[e->attr_count] = a;
3190Sstevel@tonic-gate 	e->attr_count++;
3200Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
3210Sstevel@tonic-gate }
3220Sstevel@tonic-gate 
3230Sstevel@tonic-gate static ns_ldap_entry_t *
3240Sstevel@tonic-gate __s_mk_entry(char **objclass, int max_attr)
3250Sstevel@tonic-gate {
3260Sstevel@tonic-gate 	ns_ldap_entry_t *e;
3270Sstevel@tonic-gate 	e = (ns_ldap_entry_t *)calloc(1, sizeof (ns_ldap_entry_t));
3280Sstevel@tonic-gate 	if (e == NULL)
3290Sstevel@tonic-gate 		return (NULL);
3300Sstevel@tonic-gate 	e->attr_pair = (ns_ldap_attr_t **)calloc(max_attr+1,
331*6842Sth160488 	    sizeof (ns_ldap_attr_t *));
3320Sstevel@tonic-gate 	if (e->attr_pair == NULL) {
3330Sstevel@tonic-gate 		free(e);
3340Sstevel@tonic-gate 		return (NULL);
3350Sstevel@tonic-gate 	}
3360Sstevel@tonic-gate 	e->attr_count = 0;
3370Sstevel@tonic-gate 	if (__s_add_attrlist(e, "objectClass", objclass) != NS_LDAP_SUCCESS) {
3380Sstevel@tonic-gate 		free(e->attr_pair);
3390Sstevel@tonic-gate 		free(e);
3400Sstevel@tonic-gate 		return (NULL);
3410Sstevel@tonic-gate 	}
3420Sstevel@tonic-gate 	return (e);
3430Sstevel@tonic-gate }
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate static void
3460Sstevel@tonic-gate ldap_freeEntry(ns_ldap_entry_t *ep)
3470Sstevel@tonic-gate {
3480Sstevel@tonic-gate 	int		j, k = 0;
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 	if (ep == NULL)
3510Sstevel@tonic-gate 		return;
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate 	if (ep->attr_pair == NULL) {
3540Sstevel@tonic-gate 		free(ep);
3550Sstevel@tonic-gate 		return;
3560Sstevel@tonic-gate 	}
3570Sstevel@tonic-gate 	for (j = 0; j < ep->attr_count; j++) {
3580Sstevel@tonic-gate 		if (ep->attr_pair[j] == NULL)
3590Sstevel@tonic-gate 			continue;
3600Sstevel@tonic-gate 		if (ep->attr_pair[j]->attrname)
3610Sstevel@tonic-gate 			free(ep->attr_pair[j]->attrname);
3620Sstevel@tonic-gate 		if (ep->attr_pair[j]->attrvalue) {
3630Sstevel@tonic-gate 			for (k = 0; (k < ep->attr_pair[j]->value_count) &&
364*6842Sth160488 			    (ep->attr_pair[j]->attrvalue[k]); k++) {
3650Sstevel@tonic-gate 				free(ep->attr_pair[j]->attrvalue[k]);
3660Sstevel@tonic-gate 			}
3670Sstevel@tonic-gate 			free(ep->attr_pair[j]->attrvalue);
3680Sstevel@tonic-gate 		}
3690Sstevel@tonic-gate 		free(ep->attr_pair[j]);
3700Sstevel@tonic-gate 	}
3710Sstevel@tonic-gate 	free(ep->attr_pair);
3720Sstevel@tonic-gate 	free(ep);
3730Sstevel@tonic-gate }
3740Sstevel@tonic-gate 
3750Sstevel@tonic-gate static int
3760Sstevel@tonic-gate addentry(void *entry, int mod)
3770Sstevel@tonic-gate {
3780Sstevel@tonic-gate 	int		 result = 0;
3790Sstevel@tonic-gate 	ns_ldap_error_t	 *eres = NULL;
3800Sstevel@tonic-gate 	int		rc = 1;
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate 	/*  adds entry into the LDAP tree */
3840Sstevel@tonic-gate 	if (mod)
3850Sstevel@tonic-gate 		result = __ns_ldap_addTypedEntry(databasetype, inputbasedn,
386*6842Sth160488 		    entry, 0, &authority, NS_LDAP_FOLLOWREF | NS_LDAP_KEEP_CONN,
387*6842Sth160488 		    &eres);
3880Sstevel@tonic-gate 	else
3890Sstevel@tonic-gate 		result = __ns_ldap_addTypedEntry(databasetype, inputbasedn,
390*6842Sth160488 		    entry, 1, &authority, NS_LDAP_FOLLOWREF | NS_LDAP_KEEP_CONN,
391*6842Sth160488 		    &eres);
3920Sstevel@tonic-gate 	/*
3930Sstevel@tonic-gate 	 *  Return	0 on success
3940Sstevel@tonic-gate 	 *		LDAP_ALREADY_EXISTS if entry exists already
3950Sstevel@tonic-gate 	 *		1 for all other non-fatal errors.
3960Sstevel@tonic-gate 	 *  Exit on fatal errors.
3970Sstevel@tonic-gate 	 */
3980Sstevel@tonic-gate 	switch (result) {
3990Sstevel@tonic-gate 	case NS_LDAP_SUCCESS:
4000Sstevel@tonic-gate 		nent_add++;
4010Sstevel@tonic-gate 		rc = 0;
4020Sstevel@tonic-gate 		break;
4030Sstevel@tonic-gate 
4040Sstevel@tonic-gate 	case NS_LDAP_OP_FAILED:
4050Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("operation failed.\n"));
4060Sstevel@tonic-gate 		rc = 1;
4070Sstevel@tonic-gate 		break;
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate 	case NS_LDAP_INVALID_PARAM:
4100Sstevel@tonic-gate 		(void) fprintf(stderr,
4110Sstevel@tonic-gate 		    gettext("invalid parameter(s) passed.\n"));
4120Sstevel@tonic-gate 		rc = 1;
4130Sstevel@tonic-gate 		break;
4140Sstevel@tonic-gate 
4150Sstevel@tonic-gate 	case NS_LDAP_NOTFOUND:
4160Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("entry not found.\n"));
4170Sstevel@tonic-gate 		rc = 1;
4180Sstevel@tonic-gate 		break;
4190Sstevel@tonic-gate 
4200Sstevel@tonic-gate 	case NS_LDAP_MEMORY:
4210Sstevel@tonic-gate 		(void) fprintf(stderr,
4220Sstevel@tonic-gate 		    gettext("internal memory allocation error.\n"));
4230Sstevel@tonic-gate 		exit(1);
4240Sstevel@tonic-gate 		break;
4250Sstevel@tonic-gate 
4260Sstevel@tonic-gate 	case NS_LDAP_CONFIG:
4270Sstevel@tonic-gate 		(void) fprintf(stderr,
4280Sstevel@tonic-gate 		    gettext("LDAP Configuration problem.\n"));
4290Sstevel@tonic-gate 		perr(eres);
4300Sstevel@tonic-gate 		exit(1);
4310Sstevel@tonic-gate 		break;
4320Sstevel@tonic-gate 
4330Sstevel@tonic-gate 	case NS_LDAP_PARTIAL:
4340Sstevel@tonic-gate 		(void) fprintf(stderr,
4350Sstevel@tonic-gate 		    gettext("partial result returned\n"));
4360Sstevel@tonic-gate 		perr(eres);
4370Sstevel@tonic-gate 		rc = 1;
4380Sstevel@tonic-gate 		break;
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate 	case NS_LDAP_INTERNAL:
4412277Sjs198686 		if (eres->status == LDAP_ALREADY_EXISTS ||
442*6842Sth160488 		    eres->status == LDAP_NO_SUCH_OBJECT)
4430Sstevel@tonic-gate 			rc = eres->status;
4442830Sdjl 		else if (eres->status == LDAP_INSUFFICIENT_ACCESS) {
4452830Sdjl 			(void) fprintf(stderr,
446*6842Sth160488 			    gettext("The user does not have permission"
447*6842Sth160488 			    " to add/modify entries\n"));
4482830Sdjl 			perr(eres);
4492830Sdjl 			exit(1);
4502830Sdjl 		} else {
4510Sstevel@tonic-gate 			rc = 1;
4520Sstevel@tonic-gate 			perr(eres);
4530Sstevel@tonic-gate 		}
4540Sstevel@tonic-gate 		break;
4550Sstevel@tonic-gate 	}
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate 	if (eres)
4580Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&eres);
4590Sstevel@tonic-gate 	return (rc);
4600Sstevel@tonic-gate }
4610Sstevel@tonic-gate 
4620Sstevel@tonic-gate /*
4630Sstevel@tonic-gate  * usage(char *msg)
4640Sstevel@tonic-gate  * Display usage message to STDERR.
4650Sstevel@tonic-gate  */
4660Sstevel@tonic-gate static void
4670Sstevel@tonic-gate usage(char *msg) {
4680Sstevel@tonic-gate 
4690Sstevel@tonic-gate 	if (msg)
470*6842Sth160488 		(void) fprintf(stderr, "%s\n", msg);
4710Sstevel@tonic-gate 
4720Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
473*6842Sth160488 	"usage: ldapaddent [-cpv] [-a authenticationMethod] [-b baseDN]\n"
474*6842Sth160488 	"-D bindDN [-w bindPassword] [-j passwdFile] [-f filename]\n"
475*6842Sth160488 	"database\n"
476*6842Sth160488 	"\n"
477*6842Sth160488 	"usage: ldapaddent  [-cpv] -asasl/GSSAPI [-b baseDN] [-f filename]\n"
478*6842Sth160488 	"database\n"
479*6842Sth160488 	"\n"
480*6842Sth160488 	"usage: ldapaddent  -d [-v] [-a authenticationMethod] [-D bindDN]\n"
481*6842Sth160488 	"[-w bindPassword] [-j passwdFile] database\n"
482*6842Sth160488 	"\n"
483*6842Sth160488 	"usage: ldapaddent [-cpv] -h LDAP_server[:serverPort] [-M domainName]\n"
484*6842Sth160488 	"[-N  profileName]  [-P certifPath]  [-a authenticationMethod]\n"
485*6842Sth160488 	"[-b baseDN] -D bindDN [-w bindPassword] [-f filename]\n"
486*6842Sth160488 	"[-j passwdFile] database\n"
487*6842Sth160488 	"\n"
488*6842Sth160488 	"usage: ldapaddent [-cpv] -h LDAP_server[:serverPort] [-M domainName]\n"
489*6842Sth160488 	"[-N  profileName]  [-P certifPath] -asasl/GSSAPI  [-b baseDN]\n"
490*6842Sth160488 	"[-f filename] database\n"
491*6842Sth160488 	"\n"
492*6842Sth160488 	"usage: ldapaddent -d [-v] -h LDAP_server[:serverPort]"
493*6842Sth160488 	" [-M domainName]\n"
494*6842Sth160488 	"[-N profileName]  [-P certifPath]  [-a authenticationMethod]\n"
495*6842Sth160488 	"[-b baseDN] -D bindDN [-w bindPassword] [-j passwdFile]\n"
496*6842Sth160488 	"database\n"));
4970Sstevel@tonic-gate 	exit(1);
4980Sstevel@tonic-gate }
4990Sstevel@tonic-gate 
5000Sstevel@tonic-gate /*
5010Sstevel@tonic-gate  * Determine if the given string is an IP address (IPv4 or IPv6).
5020Sstevel@tonic-gate  * If so, it's converted to the preferred form (rfc2373) and
5030Sstevel@tonic-gate  * *newaddr will point to the new address.
5040Sstevel@tonic-gate  *
5050Sstevel@tonic-gate  * Returns	-2		: inet_ntop error
5060Sstevel@tonic-gate  *		-1		: not an IP address
5070Sstevel@tonic-gate  *		0		: unsupported IP address (future use)
5080Sstevel@tonic-gate  *		AF_INET		: IPv4
5090Sstevel@tonic-gate  *		AF_INET6	: IPv6
5100Sstevel@tonic-gate  */
5110Sstevel@tonic-gate static int
5120Sstevel@tonic-gate check_ipaddr(char *addr, char **newaddr) {
5130Sstevel@tonic-gate 	ipaddr_t	addr_ipv4 = 0;
5140Sstevel@tonic-gate 	in6_addr_t	addr_ipv6;
5150Sstevel@tonic-gate 
5160Sstevel@tonic-gate 	/* IPv6 */
5170Sstevel@tonic-gate 	if (inet_pton(AF_INET6, addr, &addr_ipv6) == 1) {
5180Sstevel@tonic-gate 		if (newaddr == NULL)
5190Sstevel@tonic-gate 			return (AF_INET6);
5200Sstevel@tonic-gate 
5210Sstevel@tonic-gate 		/* Convert IPv4-mapped IPv6 address to IPv4 */
5220Sstevel@tonic-gate 		if (IN6_IS_ADDR_V4MAPPED(&addr_ipv6) ||
5230Sstevel@tonic-gate 					IN6_IS_ADDR_V4COMPAT(&addr_ipv6)) {
5240Sstevel@tonic-gate 			IN6_V4MAPPED_TO_IPADDR(&addr_ipv6, addr_ipv4);
5250Sstevel@tonic-gate 			if ((*newaddr = calloc(1, INET_ADDRSTRLEN)) == NULL) {
5260Sstevel@tonic-gate 				(void) fprintf(stderr,
5270Sstevel@tonic-gate 				    gettext("out of memory\n"));
5280Sstevel@tonic-gate 				exit(1);
5290Sstevel@tonic-gate 			}
5300Sstevel@tonic-gate 			if (inet_ntop(AF_INET, &addr_ipv4, *newaddr,
5310Sstevel@tonic-gate 			    INET_ADDRSTRLEN))
5320Sstevel@tonic-gate 				return (AF_INET6);
5330Sstevel@tonic-gate 			free(*newaddr);
5340Sstevel@tonic-gate 			return (-2);
5350Sstevel@tonic-gate 		}
5360Sstevel@tonic-gate 
5370Sstevel@tonic-gate 		/* Processing general IPv6 addresses */
5380Sstevel@tonic-gate 		if ((*newaddr = calloc(1, INET6_ADDRSTRLEN)) == NULL) {
5390Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
5400Sstevel@tonic-gate 			exit(1);
5410Sstevel@tonic-gate 		}
5420Sstevel@tonic-gate 		if (inet_ntop(AF_INET6, &addr_ipv6, *newaddr, INET6_ADDRSTRLEN))
5430Sstevel@tonic-gate 			return (AF_INET6);
5440Sstevel@tonic-gate 		free(*newaddr);
5450Sstevel@tonic-gate 		return (-2);
5460Sstevel@tonic-gate 	}
5470Sstevel@tonic-gate 
5480Sstevel@tonic-gate 	/* Processing IPv4 addresses of the type d.d.d.d. */
5490Sstevel@tonic-gate 	if (inet_pton(AF_INET, addr, &addr_ipv4) == 1) {
5500Sstevel@tonic-gate 		if (newaddr == NULL)
5510Sstevel@tonic-gate 			return (AF_INET);
5520Sstevel@tonic-gate 		if ((*newaddr = calloc(1, INET_ADDRSTRLEN)) == NULL) {
5530Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
5540Sstevel@tonic-gate 			exit(1);
5550Sstevel@tonic-gate 		}
5560Sstevel@tonic-gate 		if (inet_ntop(AF_INET, &addr_ipv4, *newaddr, INET_ADDRSTRLEN))
5570Sstevel@tonic-gate 			return (AF_INET);
5580Sstevel@tonic-gate 		free(*newaddr);
5590Sstevel@tonic-gate 		return (-2);
5600Sstevel@tonic-gate 	}
5610Sstevel@tonic-gate 
5620Sstevel@tonic-gate 	/* Processing IPv4 addresses d.d.d , d.d and d */
5630Sstevel@tonic-gate 	if (inet_addr(addr) != (in_addr_t)-1) {
5640Sstevel@tonic-gate 		if (newaddr == NULL)
5650Sstevel@tonic-gate 			return (AF_INET);
5660Sstevel@tonic-gate 		if ((*newaddr = strdup(addr)) == NULL) {
5670Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
5680Sstevel@tonic-gate 			exit(1);
5690Sstevel@tonic-gate 		}
5700Sstevel@tonic-gate 		return (AF_INET);
5710Sstevel@tonic-gate 	}
5720Sstevel@tonic-gate 
5730Sstevel@tonic-gate 	return (-1);
5740Sstevel@tonic-gate }
5750Sstevel@tonic-gate 
576*6842Sth160488 /*
577*6842Sth160488  * Verifies that project name meets the restrictions defined by project(4).
578*6842Sth160488  */
579*6842Sth160488 static int
580*6842Sth160488 check_projname(char *addr)
581*6842Sth160488 {
582*6842Sth160488 	int i;
583*6842Sth160488 	if (addr == NULL || *addr == '\0')
584*6842Sth160488 		return (-1);
585*6842Sth160488 
586*6842Sth160488 	for (i = 0; i < strlen(addr); i++) {
587*6842Sth160488 		if (!isalpha(addr[i]) &&
588*6842Sth160488 		    !isdigit(addr[i]) &&
589*6842Sth160488 		    addr[i] != '_' &&
590*6842Sth160488 		    addr[i] != '-' &&
591*6842Sth160488 		    addr[i] != '.')
592*6842Sth160488 			return (-1);
593*6842Sth160488 	}
594*6842Sth160488 
595*6842Sth160488 	return (0);
596*6842Sth160488 }
597*6842Sth160488 
5980Sstevel@tonic-gate static int
5990Sstevel@tonic-gate genent_hosts(char *line, int (*cback)())
6000Sstevel@tonic-gate {
6010Sstevel@tonic-gate 	char buf[BUFSIZ+1];
6022689Siz202018 	char *t, *comment;
6030Sstevel@tonic-gate 	entry_col ecol[4];
6040Sstevel@tonic-gate 	char *cname, *pref_addr;
6050Sstevel@tonic-gate 	int ctr = 0, retval = 1;
6060Sstevel@tonic-gate 	int rc = GENENT_OK, af;
6070Sstevel@tonic-gate 
6080Sstevel@tonic-gate 	struct hostent  data;
6090Sstevel@tonic-gate 	char *alias;
6100Sstevel@tonic-gate 
6110Sstevel@tonic-gate 	/*
6120Sstevel@tonic-gate 	 * don't clobber our argument
6130Sstevel@tonic-gate 	 */
6140Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
615*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
616*6842Sth160488 		    PARSE_ERR_MSG_LEN);
6170Sstevel@tonic-gate 		return (GENENT_PARSEERR);
6180Sstevel@tonic-gate 	}
6190Sstevel@tonic-gate 	(void) strcpy(buf, line);
6200Sstevel@tonic-gate 
6210Sstevel@tonic-gate 	/*
6220Sstevel@tonic-gate 	 * clear column data
6230Sstevel@tonic-gate 	 */
6240Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
6250Sstevel@tonic-gate 
6260Sstevel@tonic-gate 	/*
6270Sstevel@tonic-gate 	 * comment (col 3)
6282689Siz202018 	 * All leading spaces will be deleted from the comment
6290Sstevel@tonic-gate 	 */
6302689Siz202018 	ecol[3].ec_value.ec_value_val = "";
6312689Siz202018 	ecol[3].ec_value.ec_value_len = 0;
6322689Siz202018 	comment = t = strchr(buf, '#');
6332689Siz202018 	if (comment) {
6342689Siz202018 		do {
6352689Siz202018 			++comment;
6362689Siz202018 		} while (*comment != '\0' && isspace(*comment));
6372689Siz202018 		if (*comment != '\0') {
6382689Siz202018 			*--comment = '#';
6392689Siz202018 			ecol[3].ec_value.ec_value_val = strdup(comment);
6402689Siz202018 			ecol[3].ec_value.ec_value_len = strlen(comment)+1;
6412689Siz202018 		}
6422689Siz202018 
6432689Siz202018 		*t = '\0';
6440Sstevel@tonic-gate 	}
6450Sstevel@tonic-gate 
6460Sstevel@tonic-gate 	/*
6470Sstevel@tonic-gate 	 * addr(col 2)
6480Sstevel@tonic-gate 	 */
6490Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
650*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no host"),
651*6842Sth160488 		    PARSE_ERR_MSG_LEN);
6520Sstevel@tonic-gate 		return (GENENT_PARSEERR);
6530Sstevel@tonic-gate 	}
6540Sstevel@tonic-gate 
6550Sstevel@tonic-gate 	af = check_ipaddr(t, &pref_addr);
6560Sstevel@tonic-gate 	if (af == -2) {
657*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("Internal error"),
658*6842Sth160488 		    PARSE_ERR_MSG_LEN);
6590Sstevel@tonic-gate 	} else if (af == -1) {
6600Sstevel@tonic-gate 		(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
661*6842Sth160488 		    gettext("Invalid IP address: %s"), t);
6620Sstevel@tonic-gate 	} else if (flags & F_VERBOSE) {
6630Sstevel@tonic-gate 		if ((strncasecmp(t, pref_addr, strlen(t))) != 0) {
6640Sstevel@tonic-gate 			(void) fprintf(stdout,
6650Sstevel@tonic-gate 			    gettext("IP address %s converted to %s\n"),
6660Sstevel@tonic-gate 			    t, pref_addr);
6670Sstevel@tonic-gate 		}
6680Sstevel@tonic-gate 	}
6690Sstevel@tonic-gate 
6700Sstevel@tonic-gate 	if (af < 0) {
671*6842Sth160488 		(void) fprintf(stderr, "%s\n", parse_err_msg);
6720Sstevel@tonic-gate 		if (continue_onerror == 0)
6730Sstevel@tonic-gate 			return (GENENT_CBERR);
6740Sstevel@tonic-gate 		else
6750Sstevel@tonic-gate 			return (rc);
6760Sstevel@tonic-gate 	}
6770Sstevel@tonic-gate 
6780Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = pref_addr;
6790Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(pref_addr)+1;
6800Sstevel@tonic-gate 
6810Sstevel@tonic-gate 	/*
6820Sstevel@tonic-gate 	 * cname (col 0)
6830Sstevel@tonic-gate 	 */
6840Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
685*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no cname"),
686*6842Sth160488 		    PARSE_ERR_MSG_LEN);
6870Sstevel@tonic-gate 		return (GENENT_PARSEERR);
6880Sstevel@tonic-gate 	}
6890Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
6900Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
6910Sstevel@tonic-gate 	cname = t;
6920Sstevel@tonic-gate 
6930Sstevel@tonic-gate 
6940Sstevel@tonic-gate 	/* build entry */
6950Sstevel@tonic-gate 	if ((data.h_addr_list = (char **)calloc(2, sizeof (char **))) == NULL) {
6960Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
6970Sstevel@tonic-gate 		exit(1);
6980Sstevel@tonic-gate 	}
6990Sstevel@tonic-gate 	data.h_addr_list[0] = strdup(ecol[2].ec_value.ec_value_val);
7000Sstevel@tonic-gate 	data.h_addr_list[1] = NULL;
7010Sstevel@tonic-gate 
7020Sstevel@tonic-gate 	free(pref_addr);
7030Sstevel@tonic-gate 	data.h_name = strdup(ecol[0].ec_value.ec_value_val);
7040Sstevel@tonic-gate 
7050Sstevel@tonic-gate 	/*
7060Sstevel@tonic-gate 	 * name (col 1)
7070Sstevel@tonic-gate 	 */
7080Sstevel@tonic-gate 
7090Sstevel@tonic-gate 	data.h_aliases = NULL;
7100Sstevel@tonic-gate 
7110Sstevel@tonic-gate 	do {
7120Sstevel@tonic-gate 		/*
7130Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
7140Sstevel@tonic-gate 		 */
7150Sstevel@tonic-gate 
7160Sstevel@tonic-gate 		/* This call to AddEntry may move out of the loop */
7170Sstevel@tonic-gate 		/* This is because we have to call the function just once */
7180Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
7190Sstevel@tonic-gate 			continue;
7200Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
7210Sstevel@tonic-gate 			continue;
7220Sstevel@tonic-gate 
7230Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
7240Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 		ctr++;
7270Sstevel@tonic-gate 		alias = strdup(ecol[1].ec_value.ec_value_val);
7280Sstevel@tonic-gate 		if ((data.h_aliases = (char **)realloc(data.h_aliases,
729*6842Sth160488 		    ctr * sizeof (char **))) == NULL) {
7300Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
7310Sstevel@tonic-gate 			exit(1);
7320Sstevel@tonic-gate 		}
7330Sstevel@tonic-gate 		data.h_aliases[ctr-1] = alias;
7340Sstevel@tonic-gate 	} while (t = strtok(NULL, " \t"));
7350Sstevel@tonic-gate 
7362689Siz202018 	/*
7372689Siz202018 	 * End the list of all the aliases by NULL
7382689Siz202018 	 * If there is some comment, it will be stored as the last entry
7392689Siz202018 	 * in the list of the host aliases
7402689Siz202018 	 */
7410Sstevel@tonic-gate 	if ((data.h_aliases = (char **)realloc(data.h_aliases,
742*6842Sth160488 	    (ecol[3].ec_value.ec_value_len != 0 ?
743*6842Sth160488 	    ctr + 2 : ctr + 1) * sizeof (char **))) == NULL) {
7440Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
7450Sstevel@tonic-gate 		exit(1);
7460Sstevel@tonic-gate 	}
7472689Siz202018 
7482689Siz202018 	if (ecol[3].ec_value.ec_value_len != 0) {
7492689Siz202018 		data.h_aliases[ctr++] = ecol[3].ec_value.ec_value_val;
7502689Siz202018 	}
7510Sstevel@tonic-gate 	data.h_aliases[ctr] = NULL;
7520Sstevel@tonic-gate 
7530Sstevel@tonic-gate 	if (flags & F_VERBOSE)
7540Sstevel@tonic-gate 		(void) fprintf(stdout,
7550Sstevel@tonic-gate 		    gettext("Adding entry : cn=%s+ipHostNumber=%s\n"),
7560Sstevel@tonic-gate 		    data.h_name, data.h_addr_list[0]);
7570Sstevel@tonic-gate 
7580Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
7590Sstevel@tonic-gate 
7602689Siz202018 	if (ecol[3].ec_value.ec_value_len != 0) {
7612689Siz202018 		free(ecol[3].ec_value.ec_value_val);
7622689Siz202018 	}
7632689Siz202018 
7640Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
7650Sstevel@tonic-gate 		if (continue_onerror)
7660Sstevel@tonic-gate 			(void) fprintf(stderr,
767*6842Sth160488 			    gettext("Entry: cn=%s+ipHostNumber=%s "
768*6842Sth160488 			    "already Exists -skipping it\n"),
769*6842Sth160488 			    data.h_name, data.h_addr_list[0]);
7700Sstevel@tonic-gate 		else {
7710Sstevel@tonic-gate 			rc = GENENT_CBERR;
7720Sstevel@tonic-gate 			(void) fprintf(stderr,
773*6842Sth160488 			    gettext("Entry: cn=%s+ipHostNumber=%s"
774*6842Sth160488 			    " already Exists\n"),
775*6842Sth160488 			    data.h_name, data.h_addr_list[0]);
7760Sstevel@tonic-gate 		}
7770Sstevel@tonic-gate 	} else if (retval)
7780Sstevel@tonic-gate 		rc = GENENT_CBERR;
7790Sstevel@tonic-gate 
7800Sstevel@tonic-gate 	free(data.h_name);
7810Sstevel@tonic-gate 	free(data.h_aliases);
7820Sstevel@tonic-gate 	free(data.h_addr_list);
7830Sstevel@tonic-gate 
7840Sstevel@tonic-gate 	return (rc);
7850Sstevel@tonic-gate }
7860Sstevel@tonic-gate 
7870Sstevel@tonic-gate 
7880Sstevel@tonic-gate 
7890Sstevel@tonic-gate static void
7900Sstevel@tonic-gate dump_hosts(ns_ldap_result_t *res)
7910Sstevel@tonic-gate {
7922689Siz202018 	ns_ldap_attr_t	*attrptr = NULL,
793*6842Sth160488 	    *cn = NULL,
794*6842Sth160488 	    *iphostnumber = NULL,
795*6842Sth160488 	    *desc = NULL;
7960Sstevel@tonic-gate 	int		 i, j;
7970Sstevel@tonic-gate 	char		*name; /* host name */
7980Sstevel@tonic-gate 
7990Sstevel@tonic-gate 	if (res == NULL || res->entry == NULL)
8000Sstevel@tonic-gate 		return;
8010Sstevel@tonic-gate 	for (i = 0; i < res->entry->attr_count; i++) {
8020Sstevel@tonic-gate 		attrptr = res->entry->attr_pair[i];
8030Sstevel@tonic-gate 		if (strcasecmp(attrptr->attrname, "cn") == 0)
8040Sstevel@tonic-gate 			cn = attrptr;
8050Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname, "iphostnumber") == 0)
8060Sstevel@tonic-gate 			iphostnumber = attrptr;
8072689Siz202018 		else if (strcasecmp(attrptr->attrname, "description") == 0) {
8082689Siz202018 			desc = attrptr;
8092689Siz202018 		}
8100Sstevel@tonic-gate 	}
8110Sstevel@tonic-gate 	/* sanity check */
8120Sstevel@tonic-gate 	if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
8130Sstevel@tonic-gate 	    iphostnumber == NULL || iphostnumber->attrvalue == NULL ||
8140Sstevel@tonic-gate 	    iphostnumber->attrvalue[0] == NULL)
8150Sstevel@tonic-gate 		return;
8160Sstevel@tonic-gate 
8170Sstevel@tonic-gate 	if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
8180Sstevel@tonic-gate 		return;
8190Sstevel@tonic-gate 
8200Sstevel@tonic-gate 	/* ip host/ipnode number */
8210Sstevel@tonic-gate 	if (strlen(iphostnumber->attrvalue[0]) <= INET_ADDRSTRLEN)
8220Sstevel@tonic-gate 		/* IPV4 or IPV6 but <= NET_ADDRSTRLEN */
8230Sstevel@tonic-gate 		(void) fprintf(stdout, "%-18s", iphostnumber->attrvalue[0]);
8240Sstevel@tonic-gate 	else
8250Sstevel@tonic-gate 		/* IPV6 */
8260Sstevel@tonic-gate 		(void) fprintf(stdout, "%-48s", iphostnumber->attrvalue[0]);
8270Sstevel@tonic-gate 
8280Sstevel@tonic-gate 	/* host/ipnode name */
8290Sstevel@tonic-gate 	(void) fprintf(stdout, "%s ", name);
8300Sstevel@tonic-gate 
8310Sstevel@tonic-gate 	/* aliases */
8320Sstevel@tonic-gate 	for (j = 0; j < cn->value_count; j++) {
8330Sstevel@tonic-gate 		if (cn->attrvalue[j]) {
8340Sstevel@tonic-gate 			if (strcasecmp(name, cn->attrvalue[j]) == 0)
8350Sstevel@tonic-gate 				/* skip host name */
8360Sstevel@tonic-gate 				continue;
8370Sstevel@tonic-gate 			(void) fprintf(stdout, "%s ", cn->attrvalue[j]);
8380Sstevel@tonic-gate 		}
8390Sstevel@tonic-gate 	}
8400Sstevel@tonic-gate 
8412689Siz202018 	/* description */
8422689Siz202018 	if (desc != NULL && desc->attrvalue != NULL &&
8432689Siz202018 	    desc->attrvalue[0] != NULL) {
8442689Siz202018 		(void) fprintf(stdout, "#%s", desc->attrvalue[0]);
8452689Siz202018 	}
8462689Siz202018 
8470Sstevel@tonic-gate 	/* end of line */
8480Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
8490Sstevel@tonic-gate }
8500Sstevel@tonic-gate 
8510Sstevel@tonic-gate /*
8520Sstevel@tonic-gate  * /etc/rpc
8530Sstevel@tonic-gate  */
8540Sstevel@tonic-gate 
8550Sstevel@tonic-gate static int
8560Sstevel@tonic-gate genent_rpc(char *line, int (*cback)())
8570Sstevel@tonic-gate {
8580Sstevel@tonic-gate 	char buf[BUFSIZ+1];
8590Sstevel@tonic-gate 	char *t;
8600Sstevel@tonic-gate 	entry_col ecol[4];
8610Sstevel@tonic-gate 	char *cname;
8620Sstevel@tonic-gate 
8630Sstevel@tonic-gate 	struct rpcent	data;
8640Sstevel@tonic-gate 	char *alias;
8650Sstevel@tonic-gate 	int ctr = 0;
8660Sstevel@tonic-gate 	int retval = 1;
8670Sstevel@tonic-gate 	int rc = GENENT_OK;
8680Sstevel@tonic-gate 
8690Sstevel@tonic-gate 	/*
8700Sstevel@tonic-gate 	 * don't clobber our argument
8710Sstevel@tonic-gate 	 */
8720Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
873*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
874*6842Sth160488 		    PARSE_ERR_MSG_LEN);
8750Sstevel@tonic-gate 		return (GENENT_PARSEERR);
8760Sstevel@tonic-gate 	}
8770Sstevel@tonic-gate 	(void) strcpy(buf, line);
8780Sstevel@tonic-gate 
8790Sstevel@tonic-gate 	/*
8800Sstevel@tonic-gate 	 * clear column data
8810Sstevel@tonic-gate 	 */
8820Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
8830Sstevel@tonic-gate 
8840Sstevel@tonic-gate 	/*
8850Sstevel@tonic-gate 	 * comment (col 3)
8860Sstevel@tonic-gate 	 */
8870Sstevel@tonic-gate 	t = strchr(buf, '#');
8880Sstevel@tonic-gate 	if (t) {
8890Sstevel@tonic-gate 		*t++ = 0;
8900Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = t;
8910Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = strlen(t)+1;
8920Sstevel@tonic-gate 	} else {
8930Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
8940Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
8950Sstevel@tonic-gate 	}
8960Sstevel@tonic-gate 
8970Sstevel@tonic-gate 	/*
8980Sstevel@tonic-gate 	 * cname(col 0)
8990Sstevel@tonic-gate 	 */
9000Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
901*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no number"),
902*6842Sth160488 		    PARSE_ERR_MSG_LEN);
9030Sstevel@tonic-gate 		return (GENENT_PARSEERR);
9040Sstevel@tonic-gate 	}
9050Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
9060Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
9070Sstevel@tonic-gate 	cname = t;
9080Sstevel@tonic-gate 
9090Sstevel@tonic-gate 	/*
9100Sstevel@tonic-gate 	 * number (col 2)
9110Sstevel@tonic-gate 	 */
9120Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
913*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no number"),
914*6842Sth160488 		    PARSE_ERR_MSG_LEN);
9150Sstevel@tonic-gate 		return (GENENT_PARSEERR);
9160Sstevel@tonic-gate 	}
9170Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
9180Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
9190Sstevel@tonic-gate 
9200Sstevel@tonic-gate 
9210Sstevel@tonic-gate 	/*
9220Sstevel@tonic-gate 	 * build entry
9230Sstevel@tonic-gate 	 */
9240Sstevel@tonic-gate 
9250Sstevel@tonic-gate 	data.r_name = strdup(ecol[0].ec_value.ec_value_val);
9260Sstevel@tonic-gate 	if (ecol[2].ec_value.ec_value_val != NULL &&
927*6842Sth160488 	    ecol[2].ec_value.ec_value_val[0] != '\0') {
9280Sstevel@tonic-gate 
9290Sstevel@tonic-gate 		data.r_number = ascii_to_int(ecol[2].ec_value.ec_value_val);
9300Sstevel@tonic-gate 		if (data.r_number == -1) {
9310Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
932*6842Sth160488 			    gettext("invalid program number: %s"),
9330Sstevel@tonic-gate 			    ecol[2].ec_value.ec_value_val);
9340Sstevel@tonic-gate 		return (GENENT_PARSEERR);
9350Sstevel@tonic-gate 		}
9360Sstevel@tonic-gate 	} else
9370Sstevel@tonic-gate 		data.r_number = -1;
9380Sstevel@tonic-gate 
9390Sstevel@tonic-gate 	/*
9400Sstevel@tonic-gate 	 * name (col 1)
9410Sstevel@tonic-gate 	 */
9420Sstevel@tonic-gate 	t = cname;
9430Sstevel@tonic-gate 	data.r_aliases = NULL;
9440Sstevel@tonic-gate 	do {
9450Sstevel@tonic-gate 
9460Sstevel@tonic-gate 		/*
9470Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
9480Sstevel@tonic-gate 		 */
9490Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
9500Sstevel@tonic-gate 			continue;
9510Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
9520Sstevel@tonic-gate 			continue;
9530Sstevel@tonic-gate 
9540Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
9550Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
9560Sstevel@tonic-gate 
9570Sstevel@tonic-gate 		ctr++;
9580Sstevel@tonic-gate 		alias = strdup(ecol[1].ec_value.ec_value_val);
9590Sstevel@tonic-gate 		if ((data.r_aliases = (char **)realloc(data.r_aliases,
960*6842Sth160488 		    ctr * sizeof (char **))) == NULL) {
9610Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
9620Sstevel@tonic-gate 			exit(1);
9630Sstevel@tonic-gate 		}
9640Sstevel@tonic-gate 		data.r_aliases[ctr-1] = alias;
9650Sstevel@tonic-gate 
9660Sstevel@tonic-gate 
9670Sstevel@tonic-gate 		/*
9680Sstevel@tonic-gate 		 * only put comment in canonical entry
9690Sstevel@tonic-gate 		 */
9700Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
9710Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
9720Sstevel@tonic-gate 
9730Sstevel@tonic-gate 	} while (t = strtok(NULL, " \t"));
9740Sstevel@tonic-gate 
9750Sstevel@tonic-gate 	/* End the list of all the aliases by NULL */
9760Sstevel@tonic-gate 	if ((data.r_aliases = (char **)realloc(data.r_aliases,
977*6842Sth160488 	    (ctr + 1) * sizeof (char **))) == NULL) {
9780Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
9790Sstevel@tonic-gate 		exit(1);
9800Sstevel@tonic-gate 	}
9810Sstevel@tonic-gate 	data.r_aliases[ctr] = NULL;
9820Sstevel@tonic-gate 
9830Sstevel@tonic-gate 	if (flags & F_VERBOSE)
9840Sstevel@tonic-gate 		(void) fprintf(stdout,
9850Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.r_name);
9860Sstevel@tonic-gate 
9870Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
9880Sstevel@tonic-gate 
9890Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
9900Sstevel@tonic-gate 		if (continue_onerror)
9910Sstevel@tonic-gate 			(void) fprintf(stderr,
992*6842Sth160488 			    gettext("Entry: %s - already Exists,"
993*6842Sth160488 			    " skipping it.\n"), data.r_name);
9940Sstevel@tonic-gate 		else {
9950Sstevel@tonic-gate 			rc = GENENT_CBERR;
9960Sstevel@tonic-gate 			(void) fprintf(stderr,
997*6842Sth160488 			    gettext("Entry: %s - already Exists\n"),
998*6842Sth160488 			    data.r_name);
9990Sstevel@tonic-gate 		}
10000Sstevel@tonic-gate 	} else if (retval)
10010Sstevel@tonic-gate 		rc = GENENT_CBERR;
10020Sstevel@tonic-gate 
10030Sstevel@tonic-gate 	free(data.r_name);
10040Sstevel@tonic-gate 	free(data.r_aliases);
10050Sstevel@tonic-gate 
10060Sstevel@tonic-gate 	return (rc);
10070Sstevel@tonic-gate }
10080Sstevel@tonic-gate 
10090Sstevel@tonic-gate 
10100Sstevel@tonic-gate 
10110Sstevel@tonic-gate static void
10120Sstevel@tonic-gate dump_rpc(ns_ldap_result_t *res)
10130Sstevel@tonic-gate {
10140Sstevel@tonic-gate 	ns_ldap_attr_t	*attrptr = NULL, *cn = NULL, *rpcnumber = NULL;
10150Sstevel@tonic-gate 	int		 i, j;
10160Sstevel@tonic-gate 	char		*name; /* rpc name */
10170Sstevel@tonic-gate 
10180Sstevel@tonic-gate 	if (res == NULL || res->entry == NULL)
10190Sstevel@tonic-gate 		return;
10200Sstevel@tonic-gate 	for (i = 0; i < res->entry->attr_count; i++) {
10210Sstevel@tonic-gate 		attrptr = res->entry->attr_pair[i];
10220Sstevel@tonic-gate 		if (strcasecmp(attrptr->attrname, "cn") == 0)
10230Sstevel@tonic-gate 			cn = attrptr;
10240Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname, "oncRpcNumber") == 0)
10250Sstevel@tonic-gate 			rpcnumber = attrptr;
10260Sstevel@tonic-gate 	}
10270Sstevel@tonic-gate 	/* sanity check */
10280Sstevel@tonic-gate 	if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
10290Sstevel@tonic-gate 	    rpcnumber == NULL || rpcnumber->attrvalue == NULL ||
10300Sstevel@tonic-gate 	    rpcnumber->attrvalue[0] == NULL)
10310Sstevel@tonic-gate 		return;
10320Sstevel@tonic-gate 
10330Sstevel@tonic-gate 	if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
10340Sstevel@tonic-gate 		return;
10350Sstevel@tonic-gate 
10360Sstevel@tonic-gate 	/* rpc name */
10370Sstevel@tonic-gate 	if (strlen(name) < 8)
10380Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\t\t", name);
10390Sstevel@tonic-gate 	else
10400Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\t", name);
10410Sstevel@tonic-gate 
10420Sstevel@tonic-gate 	/* rpc number */
10430Sstevel@tonic-gate 	(void) fprintf(stdout, "%-8s", rpcnumber->attrvalue[0]);
10440Sstevel@tonic-gate 
10450Sstevel@tonic-gate 
10460Sstevel@tonic-gate 	/* aliases */
10470Sstevel@tonic-gate 	for (j = 0; j < cn->value_count; j++) {
10480Sstevel@tonic-gate 		if (cn->attrvalue[j]) {
10490Sstevel@tonic-gate 			if (strcasecmp(name, cn->attrvalue[j]) == 0)
10500Sstevel@tonic-gate 				/* skip rpc name */
10510Sstevel@tonic-gate 				continue;
10520Sstevel@tonic-gate 			(void) fprintf(stdout, "%s ", cn->attrvalue[j]);
10530Sstevel@tonic-gate 		}
10540Sstevel@tonic-gate 	}
10550Sstevel@tonic-gate 
10560Sstevel@tonic-gate 	/* end of line */
10570Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
10580Sstevel@tonic-gate 
10590Sstevel@tonic-gate }
10600Sstevel@tonic-gate 
10610Sstevel@tonic-gate /*
10620Sstevel@tonic-gate  * /etc/protocols
10630Sstevel@tonic-gate  *
10640Sstevel@tonic-gate  */
10650Sstevel@tonic-gate 
10660Sstevel@tonic-gate static int
10670Sstevel@tonic-gate genent_protocols(char *line, int (*cback)())
10680Sstevel@tonic-gate {
10690Sstevel@tonic-gate 	char buf[BUFSIZ+1];
10700Sstevel@tonic-gate 	char *t;
10710Sstevel@tonic-gate 	entry_col ecol[4];
10720Sstevel@tonic-gate 	char *cname;
10730Sstevel@tonic-gate 
10740Sstevel@tonic-gate 	struct protoent	data;
10750Sstevel@tonic-gate 	char *alias;
10760Sstevel@tonic-gate 	int ctr = 0;
10770Sstevel@tonic-gate 	int retval = 1;
10780Sstevel@tonic-gate 	int rc = GENENT_OK;
10790Sstevel@tonic-gate 
10800Sstevel@tonic-gate 	/*
10810Sstevel@tonic-gate 	 * don't clobber our argument
10820Sstevel@tonic-gate 	 */
10830Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
1084*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
1085*6842Sth160488 		    PARSE_ERR_MSG_LEN);
10860Sstevel@tonic-gate 		return (GENENT_PARSEERR);
10870Sstevel@tonic-gate 	}
10880Sstevel@tonic-gate 	(void) strcpy(buf, line);
10890Sstevel@tonic-gate 
10900Sstevel@tonic-gate 	/*
10910Sstevel@tonic-gate 	 * clear column data
10920Sstevel@tonic-gate 	 */
10930Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
10940Sstevel@tonic-gate 
10950Sstevel@tonic-gate 	/*
10960Sstevel@tonic-gate 	 * comment (col 3)
10970Sstevel@tonic-gate 	 */
10980Sstevel@tonic-gate 	t = strchr(buf, '#');
10990Sstevel@tonic-gate 	if (t) {
11000Sstevel@tonic-gate 		*t++ = 0;
11010Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = t;
11020Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = strlen(t)+1;
11030Sstevel@tonic-gate 	} else {
11040Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
11050Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
11060Sstevel@tonic-gate 	}
11070Sstevel@tonic-gate 
11080Sstevel@tonic-gate 	/*
11090Sstevel@tonic-gate 	 * cname(col 0)
11100Sstevel@tonic-gate 	 */
11110Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
1112*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no number"),
1113*6842Sth160488 		    PARSE_ERR_MSG_LEN);
11140Sstevel@tonic-gate 		return (GENENT_PARSEERR);
11150Sstevel@tonic-gate 	}
11160Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
11170Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
11180Sstevel@tonic-gate 	cname = t;
11190Sstevel@tonic-gate 
11200Sstevel@tonic-gate 	/*
11210Sstevel@tonic-gate 	 * number (col 2)
11220Sstevel@tonic-gate 	 */
11230Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
1124*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no number"),
1125*6842Sth160488 		    PARSE_ERR_MSG_LEN);
11260Sstevel@tonic-gate 		return (GENENT_PARSEERR);
11270Sstevel@tonic-gate 	}
11280Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
11290Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
11300Sstevel@tonic-gate 
11310Sstevel@tonic-gate 
11320Sstevel@tonic-gate 	/*
11330Sstevel@tonic-gate 	 * build entry
11340Sstevel@tonic-gate 	 */
11350Sstevel@tonic-gate 	data.p_name = strdup(ecol[0].ec_value.ec_value_val);
11360Sstevel@tonic-gate 
11370Sstevel@tonic-gate 	if (ecol[2].ec_value.ec_value_val != NULL &&
1138*6842Sth160488 	    ecol[2].ec_value.ec_value_val[0] != '\0') {
11390Sstevel@tonic-gate 
11400Sstevel@tonic-gate 		data.p_proto = ascii_to_int(ecol[2].ec_value.ec_value_val);
11410Sstevel@tonic-gate 		if (data.p_proto == -1) {
11420Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1143*6842Sth160488 			    gettext("invalid protocol number: %s"),
11440Sstevel@tonic-gate 			    ecol[2].ec_value.ec_value_val);
11450Sstevel@tonic-gate 		return (GENENT_PARSEERR);
11460Sstevel@tonic-gate 		}
11470Sstevel@tonic-gate 	} else
11480Sstevel@tonic-gate 		data.p_proto = -1;
11490Sstevel@tonic-gate 
11500Sstevel@tonic-gate 	/*
11510Sstevel@tonic-gate 	 * name (col 1)
11520Sstevel@tonic-gate 	 */
11530Sstevel@tonic-gate 	t = cname;
11540Sstevel@tonic-gate 	ctr = 0;
11550Sstevel@tonic-gate 	data.p_aliases = NULL;
11560Sstevel@tonic-gate 
11570Sstevel@tonic-gate 	do {
11580Sstevel@tonic-gate 		/*
11590Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
11600Sstevel@tonic-gate 		 */
11610Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
11620Sstevel@tonic-gate 			continue;
11630Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
11640Sstevel@tonic-gate 			continue;
11650Sstevel@tonic-gate 
11660Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
11670Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
11680Sstevel@tonic-gate 
11690Sstevel@tonic-gate 		ctr++;
11700Sstevel@tonic-gate 		alias = strdup(ecol[1].ec_value.ec_value_val);
11710Sstevel@tonic-gate 		if ((data.p_aliases = (char **)realloc(data.p_aliases,
1172*6842Sth160488 		    ctr * sizeof (char **))) == NULL) {
11730Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
11740Sstevel@tonic-gate 			exit(1);
11750Sstevel@tonic-gate 		}
11760Sstevel@tonic-gate 		data.p_aliases[ctr-1] = alias;
11770Sstevel@tonic-gate 
11780Sstevel@tonic-gate 		/*
11790Sstevel@tonic-gate 		 * only put comment in canonical entry
11800Sstevel@tonic-gate 		 */
11810Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
11820Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
11830Sstevel@tonic-gate 
11840Sstevel@tonic-gate 	} while (t = strtok(NULL, " \t"));
11850Sstevel@tonic-gate 
11860Sstevel@tonic-gate 	/* End the list of all the aliases by NULL */
11870Sstevel@tonic-gate 	if ((data.p_aliases = (char **)realloc(data.p_aliases,
1188*6842Sth160488 	    (ctr + 1) * sizeof (char **))) == NULL) {
11890Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
11900Sstevel@tonic-gate 		exit(1);
11910Sstevel@tonic-gate 	}
11920Sstevel@tonic-gate 	data.p_aliases[ctr] = NULL;
11930Sstevel@tonic-gate 
11940Sstevel@tonic-gate 	if (flags & F_VERBOSE)
11950Sstevel@tonic-gate 		(void) fprintf(stdout,
11960Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.p_name);
11970Sstevel@tonic-gate 
11980Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
11990Sstevel@tonic-gate 
12000Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
12010Sstevel@tonic-gate 		if (continue_onerror)
12020Sstevel@tonic-gate 			(void) fprintf(stderr,
1203*6842Sth160488 			    gettext("Entry: %s - already Exists,"
1204*6842Sth160488 			    " skipping it.\n"), data.p_name);
12050Sstevel@tonic-gate 		else {
12060Sstevel@tonic-gate 			rc = GENENT_CBERR;
12070Sstevel@tonic-gate 			(void) fprintf(stderr,
1208*6842Sth160488 			    gettext("Entry: %s - already Exists\n"),
1209*6842Sth160488 			    data.p_name);
12100Sstevel@tonic-gate 		}
12110Sstevel@tonic-gate 	} else if (retval)
12120Sstevel@tonic-gate 		rc = GENENT_CBERR;
12130Sstevel@tonic-gate 
12140Sstevel@tonic-gate 	free(data.p_name);
12150Sstevel@tonic-gate 	free(data.p_aliases);
12160Sstevel@tonic-gate 
12170Sstevel@tonic-gate 	return (rc);
12180Sstevel@tonic-gate }
12190Sstevel@tonic-gate 
12200Sstevel@tonic-gate 
12210Sstevel@tonic-gate static void
12220Sstevel@tonic-gate dump_protocols(ns_ldap_result_t *res)
12230Sstevel@tonic-gate {
12240Sstevel@tonic-gate 	ns_ldap_attr_t	*attrptr = NULL, *cn = NULL, *protocolnumber = NULL;
12250Sstevel@tonic-gate 	int		 i, j;
12260Sstevel@tonic-gate 	char		*name, *cp;
12270Sstevel@tonic-gate 
12280Sstevel@tonic-gate 	if (res == NULL || res->entry == NULL)
12290Sstevel@tonic-gate 		return;
12300Sstevel@tonic-gate 	for (i = 0; i < res->entry->attr_count; i++) {
12310Sstevel@tonic-gate 		attrptr = res->entry->attr_pair[i];
12320Sstevel@tonic-gate 		if (strcasecmp(attrptr->attrname, "cn") == 0)
12330Sstevel@tonic-gate 			cn = attrptr;
12340Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname, "ipProtocolNumber")
1235*6842Sth160488 		    == 0)
12360Sstevel@tonic-gate 			protocolnumber = attrptr;
12370Sstevel@tonic-gate 	}
12380Sstevel@tonic-gate 	/* sanity check */
12390Sstevel@tonic-gate 	if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
12400Sstevel@tonic-gate 	    protocolnumber == NULL || protocolnumber->attrvalue == NULL ||
12410Sstevel@tonic-gate 	    protocolnumber->attrvalue[0] == NULL)
12420Sstevel@tonic-gate 		return;
12430Sstevel@tonic-gate 
12440Sstevel@tonic-gate 	if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
12450Sstevel@tonic-gate 		return;
12460Sstevel@tonic-gate 
12470Sstevel@tonic-gate 	/* protocol name */
12480Sstevel@tonic-gate 	if (strlen(name) < 8)
12490Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\t\t", name);
12500Sstevel@tonic-gate 	else
12510Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\t", name);
12520Sstevel@tonic-gate 
12530Sstevel@tonic-gate 	/* protocol number */
12540Sstevel@tonic-gate 	(void) fprintf(stdout, "%-16s", protocolnumber->attrvalue[0]);
12550Sstevel@tonic-gate 
12560Sstevel@tonic-gate 	/* aliases */
12570Sstevel@tonic-gate 	for (j = 0; j < cn->value_count; j++) {
12580Sstevel@tonic-gate 		if (cn->attrvalue[j]) {
12590Sstevel@tonic-gate 			if (strcasecmp(name, cn->attrvalue[j]) == 0) {
12600Sstevel@tonic-gate 				if (cn->value_count > 1)
12610Sstevel@tonic-gate 					/* Do not replicate */
12620Sstevel@tonic-gate 					continue;
12630Sstevel@tonic-gate 				/*
12640Sstevel@tonic-gate 				 * Replicate name in uppercase as an aliase
12650Sstevel@tonic-gate 				 */
12660Sstevel@tonic-gate 				for (cp = cn->attrvalue[j]; *cp; cp++)
12670Sstevel@tonic-gate 					*cp = toupper(*cp);
12680Sstevel@tonic-gate 			}
12690Sstevel@tonic-gate 			(void) fprintf(stdout, "%s ", cn->attrvalue[j]);
12700Sstevel@tonic-gate 		}
12710Sstevel@tonic-gate 	}
12720Sstevel@tonic-gate 
12730Sstevel@tonic-gate 	/* end of line */
12740Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
12750Sstevel@tonic-gate 
12760Sstevel@tonic-gate }
12770Sstevel@tonic-gate 
12780Sstevel@tonic-gate 
12790Sstevel@tonic-gate 
12800Sstevel@tonic-gate 
12810Sstevel@tonic-gate 
12820Sstevel@tonic-gate /*
12830Sstevel@tonic-gate  * /etc/networks
12840Sstevel@tonic-gate  *
12850Sstevel@tonic-gate  */
12860Sstevel@tonic-gate 
12870Sstevel@tonic-gate static int
12880Sstevel@tonic-gate genent_networks(char *line, int (*cback)())
12890Sstevel@tonic-gate {
12900Sstevel@tonic-gate 	char buf[BUFSIZ+1];
12910Sstevel@tonic-gate 	char *t;
12920Sstevel@tonic-gate 	entry_col ecol[4];
12930Sstevel@tonic-gate 	char *cname;
12940Sstevel@tonic-gate 
12950Sstevel@tonic-gate 	struct netent	data;
12960Sstevel@tonic-gate 	char *alias;
12970Sstevel@tonic-gate 	int ctr = 0;
12980Sstevel@tonic-gate 	int retval = 1;
12990Sstevel@tonic-gate 	int enet;
13000Sstevel@tonic-gate 	int rc = GENENT_OK;
13010Sstevel@tonic-gate 
13020Sstevel@tonic-gate 	/*
13030Sstevel@tonic-gate 	 * don't clobber our argument
13040Sstevel@tonic-gate 	 */
13050Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
1306*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
1307*6842Sth160488 		    PARSE_ERR_MSG_LEN);
13080Sstevel@tonic-gate 		return (GENENT_PARSEERR);
13090Sstevel@tonic-gate 	}
13100Sstevel@tonic-gate 	(void) strcpy(buf, line);
13110Sstevel@tonic-gate 
13120Sstevel@tonic-gate 	/*
13130Sstevel@tonic-gate 	 * clear column data
13140Sstevel@tonic-gate 	 */
13150Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
13160Sstevel@tonic-gate 
13170Sstevel@tonic-gate 	/*
13180Sstevel@tonic-gate 	 * comment (col 3)
13190Sstevel@tonic-gate 	 */
13200Sstevel@tonic-gate 	t = strchr(buf, '#');
13210Sstevel@tonic-gate 	if (t) {
13220Sstevel@tonic-gate 		*t++ = 0;
13230Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = t;
13240Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = strlen(t)+1;
13250Sstevel@tonic-gate 	} else {
13260Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
13270Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
13280Sstevel@tonic-gate 	}
13290Sstevel@tonic-gate 
13300Sstevel@tonic-gate 	/*
13310Sstevel@tonic-gate 	 * cname(col 0)
13320Sstevel@tonic-gate 	 */
13330Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
1334*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no number"),
1335*6842Sth160488 		    PARSE_ERR_MSG_LEN);
13360Sstevel@tonic-gate 		return (GENENT_PARSEERR);
13370Sstevel@tonic-gate 	}
13380Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
13390Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
13400Sstevel@tonic-gate 	cname = t;
13410Sstevel@tonic-gate 
13420Sstevel@tonic-gate 	/*
13430Sstevel@tonic-gate 	 * number (col 2)
13440Sstevel@tonic-gate 	 */
13450Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
1346*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no number"),
1347*6842Sth160488 		    PARSE_ERR_MSG_LEN);
13480Sstevel@tonic-gate 		return (GENENT_PARSEERR);
13490Sstevel@tonic-gate 	}
13500Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
13510Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
13520Sstevel@tonic-gate 
13530Sstevel@tonic-gate 
13540Sstevel@tonic-gate 	/*
13550Sstevel@tonic-gate 	 * build entry
13560Sstevel@tonic-gate 	 */
13570Sstevel@tonic-gate 
13580Sstevel@tonic-gate 	data.n_name = strdup(ecol[0].ec_value.ec_value_val);
13590Sstevel@tonic-gate 	/*
13600Sstevel@tonic-gate 	 * data.n_net is an unsigned field,
13610Sstevel@tonic-gate 	 * assign -1 to it, make no sense.
13620Sstevel@tonic-gate 	 * Use enet here to avoid lint warning.
13630Sstevel@tonic-gate 	 */
13640Sstevel@tonic-gate 	enet = encode_network(ecol[2].ec_value.ec_value_val);
13650Sstevel@tonic-gate 
13660Sstevel@tonic-gate 	if (enet == -1 && continue_onerror == 0) {
13670Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Invalid network number\n"));
13680Sstevel@tonic-gate 		if (continue_onerror == 0)
13690Sstevel@tonic-gate 			return (GENENT_CBERR);
13700Sstevel@tonic-gate 	} else
13710Sstevel@tonic-gate 		data.n_net = enet;
13720Sstevel@tonic-gate 
13730Sstevel@tonic-gate 	/*
13740Sstevel@tonic-gate 	 * name (col 1)
13750Sstevel@tonic-gate 	 */
13760Sstevel@tonic-gate 	t = cname;
13770Sstevel@tonic-gate 	data.n_aliases = NULL;
13780Sstevel@tonic-gate 
13790Sstevel@tonic-gate 	do {
13800Sstevel@tonic-gate 		/*
13810Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
13820Sstevel@tonic-gate 		 */
13830Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
13840Sstevel@tonic-gate 			continue;
13850Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
13860Sstevel@tonic-gate 			continue;
13870Sstevel@tonic-gate 
13880Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
13890Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
13900Sstevel@tonic-gate 
13910Sstevel@tonic-gate 		ctr++;
13920Sstevel@tonic-gate 		alias = strdup(ecol[1].ec_value.ec_value_val);
13930Sstevel@tonic-gate 		if ((data.n_aliases = (char **)realloc(data.n_aliases,
1394*6842Sth160488 		    ctr * sizeof (char **))) == NULL) {
13950Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
13960Sstevel@tonic-gate 			exit(1);
13970Sstevel@tonic-gate 		}
13980Sstevel@tonic-gate 		data.n_aliases[ctr-1] = alias;
13990Sstevel@tonic-gate 
14000Sstevel@tonic-gate 		/*
14010Sstevel@tonic-gate 		 * only put comment in canonical entry
14020Sstevel@tonic-gate 		 */
14030Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
14040Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
14050Sstevel@tonic-gate 
14060Sstevel@tonic-gate 	} while (t = strtok(NULL, " \t"));
14070Sstevel@tonic-gate 
14080Sstevel@tonic-gate 	/* End the list of all the aliases by NULL */
14090Sstevel@tonic-gate 	if ((data.n_aliases = (char **)realloc(data.n_aliases,
1410*6842Sth160488 	    (ctr + 1) * sizeof (char **))) == NULL) {
14110Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
14120Sstevel@tonic-gate 		exit(1);
14130Sstevel@tonic-gate 	}
14140Sstevel@tonic-gate 	data.n_aliases[ctr] = NULL;
14150Sstevel@tonic-gate 
14160Sstevel@tonic-gate 	if (flags & F_VERBOSE)
14170Sstevel@tonic-gate 		(void) fprintf(stdout,
14180Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.n_name);
14190Sstevel@tonic-gate 
14200Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
14210Sstevel@tonic-gate 
14220Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
14230Sstevel@tonic-gate 		if (continue_onerror)
14240Sstevel@tonic-gate 			(void) fprintf(stderr,
1425*6842Sth160488 			    gettext("Entry: %s - already Exists,"
1426*6842Sth160488 			    " skipping it.\n"), data.n_name);
14270Sstevel@tonic-gate 		else {
14280Sstevel@tonic-gate 			rc = GENENT_CBERR;
14290Sstevel@tonic-gate 			(void) fprintf(stderr,
1430*6842Sth160488 			    gettext("Entry: %s - already Exists\n"),
1431*6842Sth160488 			    data.n_name);
14320Sstevel@tonic-gate 		}
14330Sstevel@tonic-gate 	} else if (retval)
14340Sstevel@tonic-gate 		rc = GENENT_CBERR;
14350Sstevel@tonic-gate 
14360Sstevel@tonic-gate 	free(data.n_name);
14370Sstevel@tonic-gate 	free(data.n_aliases);
14380Sstevel@tonic-gate 
14390Sstevel@tonic-gate 	return (rc);
14400Sstevel@tonic-gate }
14410Sstevel@tonic-gate 
14420Sstevel@tonic-gate 
14430Sstevel@tonic-gate static void
14440Sstevel@tonic-gate dump_networks(ns_ldap_result_t *res)
14450Sstevel@tonic-gate {
14460Sstevel@tonic-gate 	ns_ldap_attr_t	*attrptr = NULL, *cn = NULL, *networknumber = NULL;
14470Sstevel@tonic-gate 	int		 i, j;
14480Sstevel@tonic-gate 	char		*name;
14490Sstevel@tonic-gate 
14500Sstevel@tonic-gate 	if (res == NULL || res->entry == NULL)
14510Sstevel@tonic-gate 		return;
14520Sstevel@tonic-gate 	for (i = 0; i < res->entry->attr_count; i++) {
14530Sstevel@tonic-gate 		attrptr = res->entry->attr_pair[i];
14540Sstevel@tonic-gate 		if (strcasecmp(attrptr->attrname, "cn") == 0)
14550Sstevel@tonic-gate 			cn = attrptr;
14560Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname, "ipNetworkNumber")
1457*6842Sth160488 		    == 0)
14580Sstevel@tonic-gate 			networknumber = attrptr;
14590Sstevel@tonic-gate 	}
14600Sstevel@tonic-gate 	/* sanity check */
14610Sstevel@tonic-gate 	if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
14620Sstevel@tonic-gate 	    networknumber == NULL || networknumber->attrvalue == NULL ||
14630Sstevel@tonic-gate 	    networknumber->attrvalue[0] == NULL)
14640Sstevel@tonic-gate 		return;
14650Sstevel@tonic-gate 
14660Sstevel@tonic-gate 	/*
14670Sstevel@tonic-gate 	 * cn can be a MUST attribute(RFC 2307) or MAY attribute(2307bis).
14680Sstevel@tonic-gate 	 * If the canonical name can not be found (2307bis), use the 1st
14690Sstevel@tonic-gate 	 * value as the official name.
14700Sstevel@tonic-gate 	 */
14710Sstevel@tonic-gate 
14720Sstevel@tonic-gate 	/* network name */
14730Sstevel@tonic-gate 	if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
14740Sstevel@tonic-gate 		name = cn->attrvalue[0];
14750Sstevel@tonic-gate 
14760Sstevel@tonic-gate 	if (strlen(name) < 8)
14770Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\t\t", name);
14780Sstevel@tonic-gate 	else
14790Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\t", name);
14800Sstevel@tonic-gate 
14810Sstevel@tonic-gate 	/* network number */
14820Sstevel@tonic-gate 	(void) fprintf(stdout, "%-16s", networknumber->attrvalue[0]);
14830Sstevel@tonic-gate 
14840Sstevel@tonic-gate 	/* aliases */
14850Sstevel@tonic-gate 	for (j = 0; j < cn->value_count; j++) {
14860Sstevel@tonic-gate 		if (cn->attrvalue[j]) {
14870Sstevel@tonic-gate 			if (strcasecmp(name, cn->attrvalue[j]) == 0)
14880Sstevel@tonic-gate 				/* skip name */
14890Sstevel@tonic-gate 				continue;
14900Sstevel@tonic-gate 			(void) fprintf(stdout, "%s ", cn->attrvalue[j]);
14910Sstevel@tonic-gate 		}
14920Sstevel@tonic-gate 	}
14930Sstevel@tonic-gate 
14940Sstevel@tonic-gate 	/* end of line */
14950Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
14960Sstevel@tonic-gate 
14970Sstevel@tonic-gate }
14980Sstevel@tonic-gate 
14990Sstevel@tonic-gate 
15000Sstevel@tonic-gate 
15010Sstevel@tonic-gate 
15020Sstevel@tonic-gate /*
15030Sstevel@tonic-gate  * /etc/services
15040Sstevel@tonic-gate  *
15050Sstevel@tonic-gate  */
15060Sstevel@tonic-gate 
15070Sstevel@tonic-gate static int
15080Sstevel@tonic-gate genent_services(char *line, int (*cback)())
15090Sstevel@tonic-gate {
15100Sstevel@tonic-gate 	char buf[BUFSIZ+1];
15110Sstevel@tonic-gate 	char *t, *p;
15120Sstevel@tonic-gate 	entry_col ecol[5];
15130Sstevel@tonic-gate 	char *cname;
15140Sstevel@tonic-gate 
15150Sstevel@tonic-gate 	struct servent	data;
15160Sstevel@tonic-gate 	char *alias;
15170Sstevel@tonic-gate 	int ctr = 0;
15180Sstevel@tonic-gate 	int retval = 1;
15190Sstevel@tonic-gate 	int rc = GENENT_OK;
15200Sstevel@tonic-gate 
15210Sstevel@tonic-gate 	/*
15220Sstevel@tonic-gate 	 * don't clobber our argument
15230Sstevel@tonic-gate 	 */
15240Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
1525*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
1526*6842Sth160488 		    PARSE_ERR_MSG_LEN);
15270Sstevel@tonic-gate 		return (GENENT_PARSEERR);
15280Sstevel@tonic-gate 	}
15290Sstevel@tonic-gate 	(void) strcpy(buf, line);
15300Sstevel@tonic-gate 
15310Sstevel@tonic-gate 	/*
15320Sstevel@tonic-gate 	 * clear column data
15330Sstevel@tonic-gate 	 */
15340Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
15350Sstevel@tonic-gate 
15360Sstevel@tonic-gate 	/*
15370Sstevel@tonic-gate 	 * comment (col 4)
15380Sstevel@tonic-gate 	 */
15390Sstevel@tonic-gate 	t = strchr(buf, '#');
15400Sstevel@tonic-gate 	if (t) {
15410Sstevel@tonic-gate 		*t++ = 0;
15420Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_val = t;
15430Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_len = strlen(t)+1;
15440Sstevel@tonic-gate 	} else {
15450Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_val = 0;
15460Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_len = 0;
15470Sstevel@tonic-gate 	}
15480Sstevel@tonic-gate 
15490Sstevel@tonic-gate 	/*
15500Sstevel@tonic-gate 	 * cname(col 0)
15510Sstevel@tonic-gate 	 */
15520Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
1553*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no port"),
1554*6842Sth160488 		    PARSE_ERR_MSG_LEN);
15550Sstevel@tonic-gate 		return (GENENT_PARSEERR);
15560Sstevel@tonic-gate 	}
15570Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
15580Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
15590Sstevel@tonic-gate 	cname = t;
15600Sstevel@tonic-gate 
15610Sstevel@tonic-gate 	/*
15620Sstevel@tonic-gate 	 * port (col 3)
15630Sstevel@tonic-gate 	 */
15640Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
1565*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no protocol"),
1566*6842Sth160488 		    PARSE_ERR_MSG_LEN);
15670Sstevel@tonic-gate 		return (GENENT_PARSEERR);
15680Sstevel@tonic-gate 	}
15690Sstevel@tonic-gate 	if ((p = strchr(t, '/')) == 0) {
1570*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("bad port/proto"),
1571*6842Sth160488 		    PARSE_ERR_MSG_LEN);
15720Sstevel@tonic-gate 		return (GENENT_PARSEERR);
15730Sstevel@tonic-gate 	}
15740Sstevel@tonic-gate 	*(p++) = 0;
15750Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_val = t;
15760Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_len = strlen(t)+1;
15770Sstevel@tonic-gate 
15780Sstevel@tonic-gate 	/*
15790Sstevel@tonic-gate 	 * proto (col 2)
15800Sstevel@tonic-gate 	 */
15810Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = p;
15820Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(p)+1;
15830Sstevel@tonic-gate 
15840Sstevel@tonic-gate 
15850Sstevel@tonic-gate 	/*
15860Sstevel@tonic-gate 	 * build entry
15870Sstevel@tonic-gate 	 */
15880Sstevel@tonic-gate 
15890Sstevel@tonic-gate 	data.s_name = strdup(ecol[0].ec_value.ec_value_val);
15900Sstevel@tonic-gate 	data.s_proto = strdup(ecol[2].ec_value.ec_value_val);
15910Sstevel@tonic-gate 
15920Sstevel@tonic-gate 	if (ecol[3].ec_value.ec_value_val != NULL &&
1593*6842Sth160488 	    ecol[3].ec_value.ec_value_val[0] != '\0') {
15940Sstevel@tonic-gate 
15950Sstevel@tonic-gate 		data.s_port = ascii_to_int(ecol[3].ec_value.ec_value_val);
15960Sstevel@tonic-gate 		if (data.s_port == -1) {
15970Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1598*6842Sth160488 			    gettext("invalid port number: %s"),
15990Sstevel@tonic-gate 			    ecol[3].ec_value.ec_value_val);
16000Sstevel@tonic-gate 		return (GENENT_PARSEERR);
16010Sstevel@tonic-gate 		}
16020Sstevel@tonic-gate 	} else
16030Sstevel@tonic-gate 		data.s_port = -1;
16040Sstevel@tonic-gate 
16050Sstevel@tonic-gate 	/*
16060Sstevel@tonic-gate 	 * name (col 1)
16070Sstevel@tonic-gate 	 */
16080Sstevel@tonic-gate 	t = cname;
16090Sstevel@tonic-gate 	data.s_aliases = NULL;
16100Sstevel@tonic-gate 
16110Sstevel@tonic-gate 	do {
16120Sstevel@tonic-gate 		/*
16130Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
16140Sstevel@tonic-gate 		 */
16150Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
16160Sstevel@tonic-gate 			continue;
16170Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
16180Sstevel@tonic-gate 			continue;
16190Sstevel@tonic-gate 
16200Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
16210Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
16220Sstevel@tonic-gate 
16230Sstevel@tonic-gate 		ctr++;
16240Sstevel@tonic-gate 		alias = strdup(ecol[1].ec_value.ec_value_val);
16250Sstevel@tonic-gate 		if ((data.s_aliases = (char **)realloc(data.s_aliases,
1626*6842Sth160488 		    ctr * sizeof (char **))) == NULL) {
16270Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
16280Sstevel@tonic-gate 			exit(1);
16290Sstevel@tonic-gate 		}
16300Sstevel@tonic-gate 		data.s_aliases[ctr-1] = alias;
16310Sstevel@tonic-gate 
16320Sstevel@tonic-gate 		/*
16330Sstevel@tonic-gate 		 * only put comment in canonical entry
16340Sstevel@tonic-gate 		 */
16350Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_val = 0;
16360Sstevel@tonic-gate 		ecol[4].ec_value.ec_value_len = 0;
16370Sstevel@tonic-gate 
16380Sstevel@tonic-gate 	} while (t = strtok(NULL, " \t"));
16390Sstevel@tonic-gate 
16400Sstevel@tonic-gate 	/* End the list of all the aliases by NULL */
16410Sstevel@tonic-gate 	if ((data.s_aliases = (char **)realloc(data.s_aliases,
1642*6842Sth160488 	    (ctr + 1) * sizeof (char **))) == NULL) {
16430Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
16440Sstevel@tonic-gate 		exit(1);
16450Sstevel@tonic-gate 	}
16460Sstevel@tonic-gate 	data.s_aliases[ctr] = NULL;
16470Sstevel@tonic-gate 
16480Sstevel@tonic-gate 	if (flags & F_VERBOSE)
16490Sstevel@tonic-gate 		(void) fprintf(stdout,
16500Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), line);
16510Sstevel@tonic-gate 
16520Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
16530Sstevel@tonic-gate 
16540Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
16550Sstevel@tonic-gate 		if (continue_onerror)
16560Sstevel@tonic-gate 			(void) fprintf(stderr, gettext(
1657*6842Sth160488 			    "Entry: cn=%s+ipServiceProtocol=%s"
1658*6842Sth160488 			    " already Exists, skipping it.\n"),
1659*6842Sth160488 			    data.s_name, data.s_proto);
16600Sstevel@tonic-gate 		else {
16610Sstevel@tonic-gate 			rc = GENENT_CBERR;
16620Sstevel@tonic-gate 			(void) fprintf(stderr,
1663*6842Sth160488 			    gettext("Entry: cn=%s+ipServiceProtocol=%s"
1664*6842Sth160488 			    " - already Exists\n"),
1665*6842Sth160488 			    data.s_name, data.s_proto);
16660Sstevel@tonic-gate 		}
16670Sstevel@tonic-gate 	} else if (retval)
16680Sstevel@tonic-gate 		rc = GENENT_CBERR;
16690Sstevel@tonic-gate 
16700Sstevel@tonic-gate 	free(data.s_name);
16710Sstevel@tonic-gate 	free(data.s_proto);
16720Sstevel@tonic-gate 	free(data.s_aliases);
16730Sstevel@tonic-gate 
16740Sstevel@tonic-gate 	return (rc);
16750Sstevel@tonic-gate }
16760Sstevel@tonic-gate 
16770Sstevel@tonic-gate 
16780Sstevel@tonic-gate 
16790Sstevel@tonic-gate static void
16800Sstevel@tonic-gate dump_services(ns_ldap_result_t *res)
16810Sstevel@tonic-gate {
16820Sstevel@tonic-gate 	ns_ldap_attr_t	*attrptr = NULL, *cn = NULL, *port = NULL;
16830Sstevel@tonic-gate 	ns_ldap_attr_t	*protocol = NULL;
16840Sstevel@tonic-gate 	int		i, j, len;
16850Sstevel@tonic-gate 	char		*name; /* service name */
16860Sstevel@tonic-gate 
16870Sstevel@tonic-gate 	/*
16880Sstevel@tonic-gate 	 * cn can have multiple values.(service name and its aliases)
16890Sstevel@tonic-gate 	 * In order to support RFC 2307, section 5.5, ipserviceprotocol  can
16900Sstevel@tonic-gate 	 * have multiple values too.
16910Sstevel@tonic-gate 	 * The output format should look like
16920Sstevel@tonic-gate 	 *
16930Sstevel@tonic-gate 	 * test		2345/udp mytest
16940Sstevel@tonic-gate 	 * test		2345/tcp mytest
16950Sstevel@tonic-gate 	 */
16960Sstevel@tonic-gate 	if (res == NULL || res->entry == NULL)
16970Sstevel@tonic-gate 		return;
16980Sstevel@tonic-gate 	for (i = 0; i < res->entry->attr_count; i++) {
16990Sstevel@tonic-gate 		attrptr = res->entry->attr_pair[i];
17000Sstevel@tonic-gate 		if (strcasecmp(attrptr->attrname, "cn") == 0)
17010Sstevel@tonic-gate 			cn = attrptr;
17020Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname, "ipServicePort") == 0)
17030Sstevel@tonic-gate 			port = attrptr;
17040Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname,
1705*6842Sth160488 		    "ipServiceProtocol") == 0)
17060Sstevel@tonic-gate 			protocol = attrptr;
17070Sstevel@tonic-gate 	}
17080Sstevel@tonic-gate 	/* sanity check */
17090Sstevel@tonic-gate 	if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
17100Sstevel@tonic-gate 	    port == NULL || port->attrvalue == NULL ||
17110Sstevel@tonic-gate 	    port->attrvalue[0] == NULL || protocol == NULL ||
17120Sstevel@tonic-gate 	    protocol->attrvalue == NULL || protocol->attrvalue[0] == NULL)
17130Sstevel@tonic-gate 		return;
17140Sstevel@tonic-gate 
17150Sstevel@tonic-gate 	if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
17160Sstevel@tonic-gate 		return;
17170Sstevel@tonic-gate 	for (i = 0; i < protocol->value_count; i++) {
17180Sstevel@tonic-gate 		if (protocol->attrvalue[i] == NULL)
17190Sstevel@tonic-gate 			return;
17200Sstevel@tonic-gate 		/* service name */
17210Sstevel@tonic-gate 		(void) fprintf(stdout, "%-16s", name);
17220Sstevel@tonic-gate 
17230Sstevel@tonic-gate 		/* port & protocol */
17240Sstevel@tonic-gate 		(void) fprintf(stdout, "%s/%s%n", port->attrvalue[0],
1725*6842Sth160488 		    protocol->attrvalue[i], &len);
17260Sstevel@tonic-gate 
17270Sstevel@tonic-gate 		if (len < 8)
17280Sstevel@tonic-gate 			(void) fprintf(stdout, "\t\t");
17290Sstevel@tonic-gate 		else
17300Sstevel@tonic-gate 			(void) fprintf(stdout, "\t");
17310Sstevel@tonic-gate 
17320Sstevel@tonic-gate 		/* aliases */
17330Sstevel@tonic-gate 		for (j = 0; j < cn->value_count; j++) {
17340Sstevel@tonic-gate 			if (cn->attrvalue[j]) {
17350Sstevel@tonic-gate 				if (strcasecmp(name, cn->attrvalue[j]) == 0)
17360Sstevel@tonic-gate 					/* skip service name */
17370Sstevel@tonic-gate 					continue;
17380Sstevel@tonic-gate 				(void) fprintf(stdout, "%s ", cn->attrvalue[j]);
17390Sstevel@tonic-gate 			}
17400Sstevel@tonic-gate 		}
17410Sstevel@tonic-gate 
17420Sstevel@tonic-gate 		/* end of line */
17430Sstevel@tonic-gate 		(void) fprintf(stdout, "\n");
17440Sstevel@tonic-gate 	}
17450Sstevel@tonic-gate }
17460Sstevel@tonic-gate 
17470Sstevel@tonic-gate 
17480Sstevel@tonic-gate /*
17490Sstevel@tonic-gate  * /etc/group
17500Sstevel@tonic-gate  */
17510Sstevel@tonic-gate 
17520Sstevel@tonic-gate static int
17530Sstevel@tonic-gate genent_group(char *line, int (*cback)())
17540Sstevel@tonic-gate {
17550Sstevel@tonic-gate 	char buf[BIGBUF+1];
17560Sstevel@tonic-gate 	char *s, *t;
17570Sstevel@tonic-gate 	entry_col ecol[5];
17580Sstevel@tonic-gate 
17590Sstevel@tonic-gate 	struct group	data;
17600Sstevel@tonic-gate 	int ctr = 0;
17610Sstevel@tonic-gate 	int retval = 1;
17620Sstevel@tonic-gate 	int rc = GENENT_OK;
17630Sstevel@tonic-gate 
17640Sstevel@tonic-gate 	/*
17650Sstevel@tonic-gate 	 * don't clobber our argument
17660Sstevel@tonic-gate 	 */
17670Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
1768*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
1769*6842Sth160488 		    PARSE_ERR_MSG_LEN);
17700Sstevel@tonic-gate 		return (GENENT_PARSEERR);
17710Sstevel@tonic-gate 	}
17720Sstevel@tonic-gate 	(void) strcpy(buf, line);
17730Sstevel@tonic-gate 	t = buf;
17740Sstevel@tonic-gate 
17750Sstevel@tonic-gate 	/* ignore empty entries */
17760Sstevel@tonic-gate 	if (*t == '\0')
17770Sstevel@tonic-gate 		return (GENENT_OK);
17780Sstevel@tonic-gate 
17790Sstevel@tonic-gate 	/*
17800Sstevel@tonic-gate 	 * clear column data
17810Sstevel@tonic-gate 	 */
17820Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
17830Sstevel@tonic-gate 
17840Sstevel@tonic-gate 	/*
17850Sstevel@tonic-gate 	 * name (col 0)
17860Sstevel@tonic-gate 	 */
17870Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
1788*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no passwd"),
1789*6842Sth160488 		    PARSE_ERR_MSG_LEN);
17900Sstevel@tonic-gate 		return (GENENT_PARSEERR);
17910Sstevel@tonic-gate 	}
17920Sstevel@tonic-gate 	*s++ = 0;
17930Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
17940Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
17950Sstevel@tonic-gate 	t = s;
17960Sstevel@tonic-gate 
17970Sstevel@tonic-gate 	/*
17980Sstevel@tonic-gate 	 * passwd (col 1)
17990Sstevel@tonic-gate 	 */
18000Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
1801*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no gid"),
1802*6842Sth160488 		    PARSE_ERR_MSG_LEN);
18030Sstevel@tonic-gate 		return (GENENT_PARSEERR);
18040Sstevel@tonic-gate 	}
18050Sstevel@tonic-gate 	*s++ = 0;
18060Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = t;
18070Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_len = strlen(t)+1;
18080Sstevel@tonic-gate 	t = s;
18090Sstevel@tonic-gate 
18100Sstevel@tonic-gate 
18110Sstevel@tonic-gate 	/*
18120Sstevel@tonic-gate 	 * gid (col 2)
18130Sstevel@tonic-gate 	 */
18140Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0 || s == t) {
1815*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no members"),
1816*6842Sth160488 		    PARSE_ERR_MSG_LEN);
18170Sstevel@tonic-gate 		return (GENENT_PARSEERR);
18180Sstevel@tonic-gate 	}
18190Sstevel@tonic-gate 	*s++ = 0;
18200Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
18210Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
18220Sstevel@tonic-gate 	t = s;
18230Sstevel@tonic-gate 
18240Sstevel@tonic-gate 	/*
18250Sstevel@tonic-gate 	 * members (col 3)
18260Sstevel@tonic-gate 	 */
18270Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_val = t;
18280Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_len = strlen(t)+1;
18290Sstevel@tonic-gate 
18300Sstevel@tonic-gate 
18310Sstevel@tonic-gate 	/*
18320Sstevel@tonic-gate 	 * build entry
18330Sstevel@tonic-gate 	 */
18340Sstevel@tonic-gate 	data.gr_name = strdup(ecol[0].ec_value.ec_value_val);
18350Sstevel@tonic-gate 	data.gr_passwd = strdup(ecol[1].ec_value.ec_value_val);
18360Sstevel@tonic-gate 	if (ecol[2].ec_value.ec_value_val != NULL &&
1837*6842Sth160488 	    ecol[2].ec_value.ec_value_val[0] != '\0') {
18380Sstevel@tonic-gate 
18390Sstevel@tonic-gate 		data.gr_gid = ascii_to_int(ecol[2].ec_value.ec_value_val);
1840*6842Sth160488 		if (data.gr_gid == (uid_t)-1) {
18410Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1842*6842Sth160488 			    gettext("invalid group id: %s"),
18430Sstevel@tonic-gate 			    ecol[2].ec_value.ec_value_val);
18440Sstevel@tonic-gate 		return (GENENT_PARSEERR);
18450Sstevel@tonic-gate 		}
18460Sstevel@tonic-gate 	} else
1847*6842Sth160488 		data.gr_gid = (uid_t)-1;
18480Sstevel@tonic-gate 
18490Sstevel@tonic-gate 	data.gr_mem = NULL;
18500Sstevel@tonic-gate 
1851839Smj162486 	/* Compute maximum amount of members */
1852839Smj162486 	s = t;
1853839Smj162486 	while (s = strchr(s, ',')) {
1854839Smj162486 		s++;
1855839Smj162486 		ctr++;
1856839Smj162486 	}
1857839Smj162486 
1858839Smj162486 	/* Allocate memory for all members */
1859839Smj162486 	data.gr_mem = calloc(ctr + 2, sizeof (char **));
1860839Smj162486 	if (data.gr_mem == NULL) {
1861839Smj162486 		(void) fprintf(stderr, gettext("out of memory\n"));
1862839Smj162486 		exit(1);
1863839Smj162486 	}
1864839Smj162486 
1865839Smj162486 	ctr = 0;
18660Sstevel@tonic-gate 	while (s = strchr(t, ',')) {
18670Sstevel@tonic-gate 
18680Sstevel@tonic-gate 		*s++ = 0;
18690Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = t;
18700Sstevel@tonic-gate 		t = s;
1871839Smj162486 		/* Send to server only non empty member names */
1872839Smj162486 		if (strlen(ecol[3].ec_value.ec_value_val) != 0)
1873839Smj162486 			data.gr_mem[ctr++] = ecol[3].ec_value.ec_value_val;
18740Sstevel@tonic-gate 	}
18750Sstevel@tonic-gate 
1876839Smj162486 	/* Send to server only non empty member names */
1877839Smj162486 	if (strlen(t) != 0)
1878839Smj162486 		data.gr_mem[ctr++] = t;
1879839Smj162486 
1880839Smj162486 	/* Array of members completed, finished by NULL, see calloc() */
18810Sstevel@tonic-gate 
18820Sstevel@tonic-gate 	if (flags & F_VERBOSE)
18830Sstevel@tonic-gate 		(void) fprintf(stdout,
18840Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.gr_name);
18850Sstevel@tonic-gate 
18860Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
18870Sstevel@tonic-gate 
18880Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
18890Sstevel@tonic-gate 		if (continue_onerror)
18900Sstevel@tonic-gate 			(void) fprintf(stderr,
1891*6842Sth160488 			    gettext("Entry: %s - already Exists,"
1892*6842Sth160488 			    " skipping it.\n"), data.gr_name);
18930Sstevel@tonic-gate 		else {
18940Sstevel@tonic-gate 			rc = GENENT_CBERR;
18950Sstevel@tonic-gate 			(void) fprintf(stderr,
1896*6842Sth160488 			    gettext("Entry: %s - already Exists\n"),
1897*6842Sth160488 			    data.gr_name);
18980Sstevel@tonic-gate 		}
18990Sstevel@tonic-gate 	} else if (retval)
19000Sstevel@tonic-gate 		rc = GENENT_CBERR;
19010Sstevel@tonic-gate 
19020Sstevel@tonic-gate 	free(data.gr_name);
19030Sstevel@tonic-gate 	free(data.gr_passwd);
19040Sstevel@tonic-gate 	free(data.gr_mem);
19050Sstevel@tonic-gate 
19060Sstevel@tonic-gate 	return (rc);
19070Sstevel@tonic-gate }
19080Sstevel@tonic-gate 
19090Sstevel@tonic-gate static void
19100Sstevel@tonic-gate dump_group(ns_ldap_result_t *res)
19110Sstevel@tonic-gate {
19120Sstevel@tonic-gate 	char    **value = NULL;
19130Sstevel@tonic-gate 	char	pnam[256];
19140Sstevel@tonic-gate 	int	attr_count = 0;
19150Sstevel@tonic-gate 
19160Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "cn");
19170Sstevel@tonic-gate 	if (value && value[0])
19180Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
19190Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "userPassword");
19200Sstevel@tonic-gate 	if (value == NULL || value[0] == NULL)
19210Sstevel@tonic-gate 		(void) fprintf(stdout, "*:");
19220Sstevel@tonic-gate 	else {
19230Sstevel@tonic-gate 		(void) strcpy(pnam, value[0]);
19240Sstevel@tonic-gate 		if (strncasecmp(value[0], "{crypt}", 7) == 0)
19250Sstevel@tonic-gate 			(void) fprintf(stdout, "%s:", (pnam+7));
19260Sstevel@tonic-gate 		else
19270Sstevel@tonic-gate 			(void) fprintf(stdout, "*:");
19280Sstevel@tonic-gate 	}
19290Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "gidNumber");
19300Sstevel@tonic-gate 	if (value && value[0])
19310Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
19320Sstevel@tonic-gate 
19330Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "memberUid");
19340Sstevel@tonic-gate 	if (value != NULL && value[0] != NULL) {
19350Sstevel@tonic-gate 		while (value[attr_count] != NULL) {
19360Sstevel@tonic-gate 			if (value[attr_count+1] == NULL)
19370Sstevel@tonic-gate 				(void) fprintf(stdout, "%s", value[attr_count]);
19380Sstevel@tonic-gate 			else
19390Sstevel@tonic-gate 				(void) fprintf(stdout, "%s,",
1940*6842Sth160488 				    value[attr_count]);
19410Sstevel@tonic-gate 			attr_count++;
19420Sstevel@tonic-gate 		}
19430Sstevel@tonic-gate 		(void) fprintf(stdout, "\n");
19440Sstevel@tonic-gate 	}
19450Sstevel@tonic-gate 	else
19460Sstevel@tonic-gate 		(void) fprintf(stdout, "\n");
19470Sstevel@tonic-gate }
19480Sstevel@tonic-gate 
19490Sstevel@tonic-gate 
19500Sstevel@tonic-gate 
19510Sstevel@tonic-gate 
19520Sstevel@tonic-gate 
19530Sstevel@tonic-gate /*
19540Sstevel@tonic-gate  * /etc/ethers
19550Sstevel@tonic-gate  */
19560Sstevel@tonic-gate 
19570Sstevel@tonic-gate static int
19580Sstevel@tonic-gate genent_ethers(char *line, int (*cback)())
19590Sstevel@tonic-gate {
19600Sstevel@tonic-gate 	char buf[BUFSIZ+1];
19610Sstevel@tonic-gate 	char *t;
19620Sstevel@tonic-gate 	entry_col ecol[3];
19630Sstevel@tonic-gate 	int retval = 1;
19640Sstevel@tonic-gate 	struct _ns_ethers	data;
19650Sstevel@tonic-gate 	int rc = GENENT_OK;
19660Sstevel@tonic-gate 
19670Sstevel@tonic-gate 	/*
19680Sstevel@tonic-gate 	 * don't clobber our argument
19690Sstevel@tonic-gate 	 */
19700Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
1971*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
1972*6842Sth160488 		    PARSE_ERR_MSG_LEN);
19730Sstevel@tonic-gate 		return (GENENT_PARSEERR);
19740Sstevel@tonic-gate 	}
19750Sstevel@tonic-gate 	(void) strcpy(buf, line);
19760Sstevel@tonic-gate 
19770Sstevel@tonic-gate 	/*
19780Sstevel@tonic-gate 	 * clear column data
19790Sstevel@tonic-gate 	 */
19800Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
19810Sstevel@tonic-gate 
19820Sstevel@tonic-gate 	/*
19830Sstevel@tonic-gate 	 * comment (col 2)
19840Sstevel@tonic-gate 	 */
19850Sstevel@tonic-gate 	t = strchr(buf, '#');
19860Sstevel@tonic-gate 	if (t) {
19870Sstevel@tonic-gate 		*t++ = 0;
19880Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val = t;
19890Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_len = strlen(t)+1;
19900Sstevel@tonic-gate 	} else {
19910Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val = 0;
19920Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_len = 0;
19930Sstevel@tonic-gate 	}
19940Sstevel@tonic-gate 
19950Sstevel@tonic-gate 	/*
19960Sstevel@tonic-gate 	 * addr(col 0)
19970Sstevel@tonic-gate 	 */
19980Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
1999*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no name"),
2000*6842Sth160488 		    PARSE_ERR_MSG_LEN);
20010Sstevel@tonic-gate 		return (GENENT_PARSEERR);
20020Sstevel@tonic-gate 	}
20030Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
20040Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
20050Sstevel@tonic-gate 
20060Sstevel@tonic-gate 	/*
20070Sstevel@tonic-gate 	 * name(col 1)
20080Sstevel@tonic-gate 	 */
20090Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
2010*6842Sth160488 		(void) strlcpy(parse_err_msg,
2011*6842Sth160488 		    gettext("no white space allowed in name"),
2012*6842Sth160488 		    PARSE_ERR_MSG_LEN);
20130Sstevel@tonic-gate 		return (GENENT_PARSEERR);
20140Sstevel@tonic-gate 	}
20150Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = t;
20160Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_len = strlen(t)+1;
20170Sstevel@tonic-gate 
20180Sstevel@tonic-gate 
20190Sstevel@tonic-gate 	/*
20200Sstevel@tonic-gate 	 * build entry
20210Sstevel@tonic-gate 	 */
20220Sstevel@tonic-gate 
20230Sstevel@tonic-gate 	data.ether = strdup(ecol[0].ec_value.ec_value_val);
20240Sstevel@tonic-gate 	data.name  = strdup(ecol[1].ec_value.ec_value_val);
20250Sstevel@tonic-gate 
20260Sstevel@tonic-gate 
20270Sstevel@tonic-gate 	if (flags & F_VERBOSE)
20280Sstevel@tonic-gate 		(void) fprintf(stdout,
20290Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.name);
20300Sstevel@tonic-gate 
20310Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
20320Sstevel@tonic-gate 
20330Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
20340Sstevel@tonic-gate 		if (continue_onerror)
20350Sstevel@tonic-gate 			(void) fprintf(stderr,
2036*6842Sth160488 			    gettext("Entry: %s - already Exists,"
2037*6842Sth160488 			    " skipping it.\n"), data.name);
20380Sstevel@tonic-gate 		else {
20390Sstevel@tonic-gate 			rc = GENENT_CBERR;
20400Sstevel@tonic-gate 			(void) fprintf(stderr,
2041*6842Sth160488 			    gettext("Entry: %s - already Exists\n"),
2042*6842Sth160488 			    data.name);
20430Sstevel@tonic-gate 		}
20440Sstevel@tonic-gate 	} else if (retval)
20450Sstevel@tonic-gate 		rc = GENENT_CBERR;
20460Sstevel@tonic-gate 
20470Sstevel@tonic-gate 	free(data.ether);
20480Sstevel@tonic-gate 	free(data.name);
20490Sstevel@tonic-gate 
20500Sstevel@tonic-gate 	return (rc);
20510Sstevel@tonic-gate }
20520Sstevel@tonic-gate 
20530Sstevel@tonic-gate 
20540Sstevel@tonic-gate static void
20550Sstevel@tonic-gate dump_ethers(ns_ldap_result_t *res)
20560Sstevel@tonic-gate {
20570Sstevel@tonic-gate 	char	**value = NULL;
20580Sstevel@tonic-gate 
20590Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "macAddress");
20600Sstevel@tonic-gate 	if (value && value[0])
20610Sstevel@tonic-gate 		(void) fprintf(stdout, "%s", value[0]);
20620Sstevel@tonic-gate 	else
20630Sstevel@tonic-gate 		return;
20640Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "cn");
20650Sstevel@tonic-gate 	if (value && value[0])
20660Sstevel@tonic-gate 		(void) fprintf(stdout, "	%s\n", value[0]);
20670Sstevel@tonic-gate }
20680Sstevel@tonic-gate 
20690Sstevel@tonic-gate static int
20700Sstevel@tonic-gate genent_aliases(char *line, int (*cback)())
20710Sstevel@tonic-gate {
20720Sstevel@tonic-gate 	char buf[BUFSIZ+1];
20730Sstevel@tonic-gate 	char *t, *aliases;
20740Sstevel@tonic-gate 	char *cname;
20750Sstevel@tonic-gate 	int ctr = 0;
20760Sstevel@tonic-gate 	int retval = 1;
20770Sstevel@tonic-gate 	int i;
20780Sstevel@tonic-gate 
20790Sstevel@tonic-gate 	struct _ns_alias data;
20800Sstevel@tonic-gate 	char *alias;
20810Sstevel@tonic-gate 	int rc = GENENT_OK;
20820Sstevel@tonic-gate 
20830Sstevel@tonic-gate 	/*
20840Sstevel@tonic-gate 	 * don't clobber our argument
20850Sstevel@tonic-gate 	 */
20860Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
2087*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
2088*6842Sth160488 		    PARSE_ERR_MSG_LEN);
20890Sstevel@tonic-gate 		return (GENENT_PARSEERR);
20900Sstevel@tonic-gate 	}
20910Sstevel@tonic-gate 
20920Sstevel@tonic-gate 	(void) strcpy(buf, line);
20930Sstevel@tonic-gate 
20940Sstevel@tonic-gate 	if ((t = strchr(buf, ':')) == 0) {
2095*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no alias name"),
2096*6842Sth160488 		    PARSE_ERR_MSG_LEN);
20970Sstevel@tonic-gate 		return (GENENT_PARSEERR);
20980Sstevel@tonic-gate 	}
20990Sstevel@tonic-gate 
21000Sstevel@tonic-gate 	t[0] = '\0';
21010Sstevel@tonic-gate 	if (++t == '\0') {
2102*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no alias value"),
2103*6842Sth160488 		    PARSE_ERR_MSG_LEN);
21040Sstevel@tonic-gate 		return (GENENT_PARSEERR);
21050Sstevel@tonic-gate 	}
21060Sstevel@tonic-gate 
21070Sstevel@tonic-gate 	cname = buf;
21080Sstevel@tonic-gate 	aliases = t;
21090Sstevel@tonic-gate 
21100Sstevel@tonic-gate 	/* build entry */
21110Sstevel@tonic-gate 	data.alias = strdup(cname);
21120Sstevel@tonic-gate 	if (!data.alias) {
21130Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
21140Sstevel@tonic-gate 		exit(1);
21150Sstevel@tonic-gate 	}
21160Sstevel@tonic-gate 
21170Sstevel@tonic-gate 	data.member = NULL;
21180Sstevel@tonic-gate 	t = strtok(aliases, ",");
21190Sstevel@tonic-gate 	do {
21200Sstevel@tonic-gate 		ctr++;
21210Sstevel@tonic-gate 		while (t[0] == ' ')
21220Sstevel@tonic-gate 			t++;
21230Sstevel@tonic-gate 		alias = strdup(t);
21240Sstevel@tonic-gate 		if ((alias == NULL) ||
2125*6842Sth160488 		    ((data.member = (char **)realloc(data.member,
2126*6842Sth160488 		    (ctr + 1) * sizeof (char **))) == NULL)) {
21270Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
21280Sstevel@tonic-gate 			exit(1);
21290Sstevel@tonic-gate 		}
21300Sstevel@tonic-gate 		data.member[ctr-1] = alias;
21310Sstevel@tonic-gate 
21320Sstevel@tonic-gate 	} while (t = strtok(NULL, ","));
21330Sstevel@tonic-gate 
21340Sstevel@tonic-gate 	data.member[ctr] = NULL;
21350Sstevel@tonic-gate 
21360Sstevel@tonic-gate 	if (flags & F_VERBOSE)
21370Sstevel@tonic-gate 		(void) fprintf(stdout,
21380Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.alias);
21390Sstevel@tonic-gate 
21400Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
21410Sstevel@tonic-gate 
21420Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
21430Sstevel@tonic-gate 		if (continue_onerror)
21440Sstevel@tonic-gate 			(void) fprintf(stderr,
2145*6842Sth160488 			    gettext("Entry: %s - already Exists,"
2146*6842Sth160488 			    " skipping it.\n"), data.alias);
21470Sstevel@tonic-gate 		else {
21480Sstevel@tonic-gate 			rc = GENENT_CBERR;
21490Sstevel@tonic-gate 			(void) fprintf(stderr,
2150*6842Sth160488 			    gettext("Entry: %s - already Exists\n"),
2151*6842Sth160488 			    data.alias);
21520Sstevel@tonic-gate 		}
21530Sstevel@tonic-gate 	} else if (retval)
21540Sstevel@tonic-gate 		rc = GENENT_CBERR;
21550Sstevel@tonic-gate 
21560Sstevel@tonic-gate 	free(data.alias);
21570Sstevel@tonic-gate 	i = 0;
21580Sstevel@tonic-gate 	while (data.member[i])
21590Sstevel@tonic-gate 		free(data.member[i++]);
21600Sstevel@tonic-gate 	free(data.member);
21610Sstevel@tonic-gate 
21620Sstevel@tonic-gate 	return (rc);
21630Sstevel@tonic-gate }
21640Sstevel@tonic-gate 
21650Sstevel@tonic-gate 
21660Sstevel@tonic-gate static void
21670Sstevel@tonic-gate dump_aliases(ns_ldap_result_t *res)
21680Sstevel@tonic-gate {
21690Sstevel@tonic-gate 
21700Sstevel@tonic-gate 	char	**value = NULL;
21710Sstevel@tonic-gate 	int 		attr_count = 0;
21720Sstevel@tonic-gate 
21730Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "mail");
21740Sstevel@tonic-gate 	if (value && value[0])
21750Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
21760Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "mgrpRFC822MailMember");
21770Sstevel@tonic-gate 	if (value != NULL)
21780Sstevel@tonic-gate 		while (value[attr_count] != NULL) {
21790Sstevel@tonic-gate 			(void) fprintf(stdout, "%s,", value[attr_count]);
21800Sstevel@tonic-gate 			attr_count++;
21810Sstevel@tonic-gate 		}
21820Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
21830Sstevel@tonic-gate 
21840Sstevel@tonic-gate }
21850Sstevel@tonic-gate 
21860Sstevel@tonic-gate /*
21870Sstevel@tonic-gate  * /etc/publickey
21880Sstevel@tonic-gate  */
21890Sstevel@tonic-gate 
21902830Sdjl static char *h_errno2str(int h_errno);
21912830Sdjl 
21920Sstevel@tonic-gate static int
21930Sstevel@tonic-gate genent_publickey(char *line, int (*cback)())
21940Sstevel@tonic-gate {
21950Sstevel@tonic-gate 	char buf[BUFSIZ+1], tmpbuf[BUFSIZ+1], cname[BUFSIZ+1];
21960Sstevel@tonic-gate 	char *t, *p, *tmppubkey, *tmpprivkey;
21970Sstevel@tonic-gate 	entry_col ecol[3];
21982830Sdjl 	int buflen, uid, retval = 1, errnum = 0;
21990Sstevel@tonic-gate 	struct passwd *pwd;
22002830Sdjl 	char auth_type[BUFSIZ+1], *dot;
22010Sstevel@tonic-gate 	keylen_t keylen;
22020Sstevel@tonic-gate 	algtype_t algtype;
22030Sstevel@tonic-gate 	struct _ns_pubkey data;
22040Sstevel@tonic-gate 	struct hostent *hp;
22050Sstevel@tonic-gate 	struct in_addr in;
22062830Sdjl 	struct in6_addr in6;
22072830Sdjl 	char abuf[INET6_ADDRSTRLEN];
22080Sstevel@tonic-gate 
22090Sstevel@tonic-gate 	/*
22100Sstevel@tonic-gate 	 * don't clobber our argument
22110Sstevel@tonic-gate 	 */
22120Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
2213*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
2214*6842Sth160488 		    PARSE_ERR_MSG_LEN);
22150Sstevel@tonic-gate 		return (GENENT_PARSEERR);
22160Sstevel@tonic-gate 	}
22170Sstevel@tonic-gate 	(void) strcpy(buf, line);
22180Sstevel@tonic-gate 
22190Sstevel@tonic-gate 	/*
22200Sstevel@tonic-gate 	 * clear column data
22210Sstevel@tonic-gate 	 */
22220Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
22230Sstevel@tonic-gate 
22240Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
2225*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no cname"),
2226*6842Sth160488 		    PARSE_ERR_MSG_LEN);
22270Sstevel@tonic-gate 		return (GENENT_PARSEERR);
22280Sstevel@tonic-gate 	}
22290Sstevel@tonic-gate 
22300Sstevel@tonic-gate 	/*
22310Sstevel@tonic-gate 	 * Special case:  /etc/publickey usually has an entry
22320Sstevel@tonic-gate 	 * for principal "nobody".  We skip it.
22330Sstevel@tonic-gate 	 */
22340Sstevel@tonic-gate 	if (strcmp(t, "nobody") == 0)
22350Sstevel@tonic-gate 		return (GENENT_OK);
22360Sstevel@tonic-gate 
22370Sstevel@tonic-gate 	/*
22380Sstevel@tonic-gate 	 * cname (col 0)
22390Sstevel@tonic-gate 	 */
22400Sstevel@tonic-gate 	if (strncmp(t, "unix.", 5)) {
2241*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("bad cname"),
2242*6842Sth160488 		    PARSE_ERR_MSG_LEN);
22430Sstevel@tonic-gate 		return (GENENT_PARSEERR);
22440Sstevel@tonic-gate 	}
22450Sstevel@tonic-gate 	(void) strcpy(tmpbuf, &(t[5]));
22460Sstevel@tonic-gate 	if ((p = strchr(tmpbuf, '@')) == 0) {
2247*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("bad cname"),
2248*6842Sth160488 		    PARSE_ERR_MSG_LEN);
22490Sstevel@tonic-gate 		return (GENENT_PARSEERR);
22500Sstevel@tonic-gate 	}
22510Sstevel@tonic-gate 	*(p++) = 0;
22520Sstevel@tonic-gate 	if (isdigit(*tmpbuf)) {
22530Sstevel@tonic-gate 
22540Sstevel@tonic-gate 		uid = atoi(tmpbuf);
22550Sstevel@tonic-gate 		/*
22560Sstevel@tonic-gate 		 * don't generate entries for uids without passwd entries
22570Sstevel@tonic-gate 		 */
22580Sstevel@tonic-gate 		if ((pwd = getpwuid(uid)) == 0) {
22590Sstevel@tonic-gate 			(void) fprintf(stderr,
22600Sstevel@tonic-gate 			gettext("can't map uid %d to username, skipping\n"),
2261*6842Sth160488 			    uid);
22620Sstevel@tonic-gate 			return (GENENT_OK);
22630Sstevel@tonic-gate 		}
22640Sstevel@tonic-gate 		(void) strcpy(cname, pwd->pw_name);
22650Sstevel@tonic-gate 		data.hostcred = NS_HOSTCRED_FALSE;
22660Sstevel@tonic-gate 	} else {
22672830Sdjl 		if ((hp = getipnodebyname(tmpbuf, AF_INET6,
2268*6842Sth160488 		    AI_ALL | AI_V4MAPPED, &errnum)) == NULL) {
22690Sstevel@tonic-gate 			(void) fprintf(stderr,
2270*6842Sth160488 			    gettext("can't map hostname %s to hostaddress, "
2271*6842Sth160488 			    "errnum %d %s skipping\n"), tmpbuf, errnum,
2272*6842Sth160488 			    h_errno2str(errnum));
22730Sstevel@tonic-gate 			return (GENENT_OK);
22740Sstevel@tonic-gate 		}
22752830Sdjl 		(void) memcpy((char *)&in6.s6_addr, hp->h_addr_list[0],
2276*6842Sth160488 		    hp->h_length);
22772830Sdjl 		if (IN6_IS_ADDR_V4MAPPED(&in6) ||
2278*6842Sth160488 		    IN6_IS_ADDR_V4COMPAT(&in6)) {
22792830Sdjl 			IN6_V4MAPPED_TO_INADDR(&in6, &in);
22802830Sdjl 			if (inet_ntop(AF_INET, (const void *)&in, abuf,
2281*6842Sth160488 			    INET6_ADDRSTRLEN) == NULL) {
22822830Sdjl 				(void) fprintf(stderr,
2283*6842Sth160488 				    gettext("can't convert IPV4 address of"
2284*6842Sth160488 				    " hostname %s to string, "
2285*6842Sth160488 				    "skipping\n"), tmpbuf);
22862830Sdjl 					return (GENENT_OK);
22872830Sdjl 			}
22882830Sdjl 		} else {
22892830Sdjl 			if (inet_ntop(AF_INET6, (const void *)&in6, abuf,
2290*6842Sth160488 			    INET6_ADDRSTRLEN) == NULL) {
22912830Sdjl 				(void) fprintf(stderr,
2292*6842Sth160488 				    gettext("can't convert IPV6 address of"
2293*6842Sth160488 				    " hostname %s to string, "
2294*6842Sth160488 				    "skipping\n"), tmpbuf);
22952830Sdjl 					return (GENENT_OK);
22962830Sdjl 			}
22972830Sdjl 		}
22980Sstevel@tonic-gate 		data.hostcred = NS_HOSTCRED_TRUE;
22992830Sdjl 		/*
23002830Sdjl 		 * tmpbuf could be an alias, use hp->h_name instead.
23012830Sdjl 		 * hp->h_name is in FQDN format, so extract 1st field.
23022830Sdjl 		 */
23032830Sdjl 		if ((dot = strchr(hp->h_name, '.')) != NULL)
23042830Sdjl 			*dot = '\0';
23050Sstevel@tonic-gate 		(void) snprintf(cname, sizeof (cname),
23062830Sdjl 		    "%s+ipHostNumber=%s", hp->h_name, abuf);
23072830Sdjl 		if (dot)
23082830Sdjl 			*dot = '.';
23090Sstevel@tonic-gate 	}
23100Sstevel@tonic-gate 
23110Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = cname;
23120Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(cname)+1;
23130Sstevel@tonic-gate 
23140Sstevel@tonic-gate 	/*
23150Sstevel@tonic-gate 	 * public_data (col 1)
23160Sstevel@tonic-gate 	 */
23170Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
2318*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no private_data"),
2319*6842Sth160488 		    PARSE_ERR_MSG_LEN);
23200Sstevel@tonic-gate 		return (GENENT_PARSEERR);
23210Sstevel@tonic-gate 	}
23220Sstevel@tonic-gate 	if ((p = strchr(t, ':')) == 0) {
2323*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("bad public_data"),
2324*6842Sth160488 		    PARSE_ERR_MSG_LEN);
23250Sstevel@tonic-gate 		return (GENENT_PARSEERR);
23260Sstevel@tonic-gate 	}
23270Sstevel@tonic-gate 	*(p++) = 0;
23280Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = t;
23290Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_len = strlen(t)+1;
23300Sstevel@tonic-gate 	keylen = (strlen(t) / 2) * 8;
23310Sstevel@tonic-gate 
23320Sstevel@tonic-gate 	/*
23330Sstevel@tonic-gate 	 * private_data (col 2) and algtype extraction
23340Sstevel@tonic-gate 	 */
23350Sstevel@tonic-gate 	if (*p == ':')
23360Sstevel@tonic-gate 		p++;
23370Sstevel@tonic-gate 	t = p;
23380Sstevel@tonic-gate 	if (!(t = strchr(t, ':'))) {
23390Sstevel@tonic-gate 		(void) fprintf(stderr,
2340*6842Sth160488 		    gettext("WARNING: No algorithm type data found "
2341*6842Sth160488 		    "in publickey file, assuming 0\n"));
23420Sstevel@tonic-gate 		algtype = 0;
23430Sstevel@tonic-gate 	} else {
23440Sstevel@tonic-gate 		*t = '\0';
23450Sstevel@tonic-gate 		t++;
23460Sstevel@tonic-gate 		algtype = atoi(t);
23470Sstevel@tonic-gate 	}
23480Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = p;
23490Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(p)+1;
23500Sstevel@tonic-gate 
23510Sstevel@tonic-gate 	/*
23520Sstevel@tonic-gate 	 * auth_type (col 1)
23530Sstevel@tonic-gate 	 */
23542830Sdjl 	if (AUTH_DES_KEY(keylen, algtype))
23552830Sdjl 		/*
23562830Sdjl 		 * {DES} and {DH192-0} means same thing.
23572830Sdjl 		 * However, nisplus uses "DES" and ldap uses "DH192-0"
23582830Sdjl 		 * internally.
23592830Sdjl 		 * See newkey(1M), __nis_mechalias2authtype() which is
23602830Sdjl 		 * called by __nis_keyalg2authtype() and getkey_ldap_g()
23612830Sdjl 		 */
23622830Sdjl 		(void) strlcpy(auth_type, "DH192-0", BUFSIZ+1);
23632830Sdjl 	else if (!(__nis_keyalg2authtype(keylen, algtype, auth_type,
2364*6842Sth160488 	    MECH_MAXATNAME))) {
23650Sstevel@tonic-gate 		(void) fprintf(stderr,
2366*6842Sth160488 		    gettext("Could not convert algorithm type to "
2367*6842Sth160488 		    "corresponding auth type string\n"));
23680Sstevel@tonic-gate 		return (GENENT_ERR);
23690Sstevel@tonic-gate 	}
23700Sstevel@tonic-gate 
23710Sstevel@tonic-gate 	/*
23720Sstevel@tonic-gate 	 * build entry
23730Sstevel@tonic-gate 	 */
23740Sstevel@tonic-gate 	data.name = strdup(ecol[0].ec_value.ec_value_val);
23750Sstevel@tonic-gate 	if (data.name == NULL) {
23760Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
23770Sstevel@tonic-gate 		exit(1);
23780Sstevel@tonic-gate 	}
23790Sstevel@tonic-gate 
23800Sstevel@tonic-gate 	buflen = sizeof (auth_type) + strlen(ecol[1].ec_value.ec_value_val) + 3;
23810Sstevel@tonic-gate 	if ((tmppubkey = (char *)malloc(buflen)) == NULL) {
23820Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
23830Sstevel@tonic-gate 		exit(1);
23840Sstevel@tonic-gate 	}
23850Sstevel@tonic-gate 	(void) snprintf(tmppubkey, buflen, "{%s}%s", auth_type,
23860Sstevel@tonic-gate 	    ecol[1].ec_value.ec_value_val);
23870Sstevel@tonic-gate 	data.pubkey = tmppubkey;
23880Sstevel@tonic-gate 
23890Sstevel@tonic-gate 	buflen = sizeof (auth_type) + strlen(ecol[2].ec_value.ec_value_val) + 3;
23900Sstevel@tonic-gate 	if ((tmpprivkey = (char *)malloc(buflen)) == NULL) {
23910Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
23920Sstevel@tonic-gate 		exit(1);
23930Sstevel@tonic-gate 	}
23940Sstevel@tonic-gate 
23950Sstevel@tonic-gate 	(void) snprintf(tmpprivkey, buflen, "{%s}%s", auth_type,
23960Sstevel@tonic-gate 	    ecol[2].ec_value.ec_value_val);
23970Sstevel@tonic-gate 	data.privkey = tmpprivkey;
23980Sstevel@tonic-gate 
23990Sstevel@tonic-gate 	retval = (*cback)(&data, 1);
24002277Sjs198686 	if (retval != NS_LDAP_SUCCESS) {
24012277Sjs198686 		if (retval == LDAP_NO_SUCH_OBJECT) {
24022277Sjs198686 			if (data.hostcred == NS_HOSTCRED_TRUE)
24032277Sjs198686 				(void) fprintf(stdout,
2404*6842Sth160488 				    gettext("Cannot add publickey entry"" (%s),"
2405*6842Sth160488 				    " add host entry first\n"),
2406*6842Sth160488 				    tmpbuf);
24072277Sjs198686 			else
24082277Sjs198686 				(void) fprintf(stdout,
2409*6842Sth160488 				    gettext("Cannot add publickey entry (%s), "
2410*6842Sth160488 				    "add passwd entry first\n"),
2411*6842Sth160488 				    data.name);
24122277Sjs198686 		}
24132277Sjs198686 		if (continue_onerror == 0)
24142277Sjs198686 			return (GENENT_CBERR);
24150Sstevel@tonic-gate 	}
24162277Sjs198686 
24172277Sjs198686 	free(data.name);
24182277Sjs198686 	free(data.pubkey);
24192277Sjs198686 	free(data.privkey);
24202277Sjs198686 	return (GENENT_OK);
24210Sstevel@tonic-gate }
24220Sstevel@tonic-gate 
24230Sstevel@tonic-gate static void
24240Sstevel@tonic-gate dump_publickey(ns_ldap_result_t *res, char *container)
24250Sstevel@tonic-gate {
24260Sstevel@tonic-gate 	char	**value = NULL;
24270Sstevel@tonic-gate 	char	buf[BUFSIZ];
24280Sstevel@tonic-gate 	char	domainname[BUFSIZ];
24290Sstevel@tonic-gate 	char	*pubptr, *prvptr;
24300Sstevel@tonic-gate 
24310Sstevel@tonic-gate 	if (res == NULL)
24320Sstevel@tonic-gate 		return;
24330Sstevel@tonic-gate 
24340Sstevel@tonic-gate 	if (sysinfo(SI_SRPC_DOMAIN, domainname, BUFSIZ) < 0) {
24350Sstevel@tonic-gate 		(void) fprintf(stderr,
2436*6842Sth160488 		    gettext("could not obtain domainname\n"));
24370Sstevel@tonic-gate 		exit(1);
24380Sstevel@tonic-gate 	}
24390Sstevel@tonic-gate 
24400Sstevel@tonic-gate 	/*
24410Sstevel@tonic-gate 	 * Retrieve all the attributes, but don't print
24420Sstevel@tonic-gate 	 * until we have all the required ones.
24430Sstevel@tonic-gate 	 */
24440Sstevel@tonic-gate 
24450Sstevel@tonic-gate 	if (strcmp(container, "passwd") == 0)
24460Sstevel@tonic-gate 		value = __ns_ldap_getAttr(res->entry, "uidNumber");
24470Sstevel@tonic-gate 	else
24480Sstevel@tonic-gate 		value = __ns_ldap_getAttr(res->entry, "cn");
24490Sstevel@tonic-gate 
24500Sstevel@tonic-gate 	if (value && value[0])
24510Sstevel@tonic-gate 		(void) snprintf(buf, sizeof (buf), "unix.%s@%s",
24520Sstevel@tonic-gate 		    value[0], domainname);
24530Sstevel@tonic-gate 	else
24540Sstevel@tonic-gate 		return;
24550Sstevel@tonic-gate 
24560Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "nisPublickey");
24570Sstevel@tonic-gate 	if (value != NULL && value[0] != NULL) {
24580Sstevel@tonic-gate 		if ((pubptr = strchr(value[0], '}')) == NULL)
24590Sstevel@tonic-gate 			return;
24600Sstevel@tonic-gate 	}
24610Sstevel@tonic-gate 
24620Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "nisSecretkey");
24630Sstevel@tonic-gate 	if (value != NULL && value[0] != NULL)
24640Sstevel@tonic-gate 		if ((prvptr = strchr(value[0], '}')) == NULL)
24650Sstevel@tonic-gate 			return;
24660Sstevel@tonic-gate 
24670Sstevel@tonic-gate 	/* print the attributes, algorithm type is always 0 */
24680Sstevel@tonic-gate 	(void) fprintf(stdout, "%s	%s:%s:0\n", buf, ++pubptr, ++prvptr);
24690Sstevel@tonic-gate }
24700Sstevel@tonic-gate 
24710Sstevel@tonic-gate 
24720Sstevel@tonic-gate 
24730Sstevel@tonic-gate /*
24740Sstevel@tonic-gate  * /etc/netmasks
24750Sstevel@tonic-gate  */
24760Sstevel@tonic-gate 
24770Sstevel@tonic-gate static int
24780Sstevel@tonic-gate genent_netmasks(char *line, int (*cback)())
24790Sstevel@tonic-gate {
24800Sstevel@tonic-gate 	char buf[BUFSIZ+1];
24810Sstevel@tonic-gate 	char *t;
24820Sstevel@tonic-gate 	entry_col ecol[3];
24832277Sjs198686 	int retval;
24840Sstevel@tonic-gate 
24850Sstevel@tonic-gate 	struct _ns_netmasks data;
24860Sstevel@tonic-gate 
24870Sstevel@tonic-gate 
24880Sstevel@tonic-gate 	/*
24890Sstevel@tonic-gate 	 * don't clobber our argument
24900Sstevel@tonic-gate 	 */
24910Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
2492*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
2493*6842Sth160488 		    PARSE_ERR_MSG_LEN);
24940Sstevel@tonic-gate 		return (GENENT_PARSEERR);
24950Sstevel@tonic-gate 	}
24960Sstevel@tonic-gate 	(void) strcpy(buf, line);
24970Sstevel@tonic-gate 
24980Sstevel@tonic-gate 	/*
24990Sstevel@tonic-gate 	 * clear column data
25000Sstevel@tonic-gate 	 */
25010Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
25020Sstevel@tonic-gate 
25030Sstevel@tonic-gate 	/*
25040Sstevel@tonic-gate 	 * comment (col 2)
25050Sstevel@tonic-gate 	 */
25060Sstevel@tonic-gate 	t = strchr(buf, '#');
25070Sstevel@tonic-gate 	if (t) {
25080Sstevel@tonic-gate 		*t++ = 0;
25090Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val = t;
25100Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_len = strlen(t)+1;
25110Sstevel@tonic-gate 	} else {
25120Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val = 0;
25130Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_len = 0;
25140Sstevel@tonic-gate 	}
25150Sstevel@tonic-gate 
25160Sstevel@tonic-gate 	/*
25170Sstevel@tonic-gate 	 * addr(col 0)
25180Sstevel@tonic-gate 	 */
25190Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
2520*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no mask"),
2521*6842Sth160488 		    PARSE_ERR_MSG_LEN);
25220Sstevel@tonic-gate 		return (GENENT_PARSEERR);
25230Sstevel@tonic-gate 	}
25240Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
25250Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
25260Sstevel@tonic-gate 
25270Sstevel@tonic-gate 	/*
25280Sstevel@tonic-gate 	 * mask (col 1)
25290Sstevel@tonic-gate 	 */
25300Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
2531*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no mask"),
2532*6842Sth160488 		    PARSE_ERR_MSG_LEN);
25330Sstevel@tonic-gate 		return (GENENT_PARSEERR);
25340Sstevel@tonic-gate 	}
25350Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = t;
25360Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_len = strlen(t)+1;
25370Sstevel@tonic-gate 
25380Sstevel@tonic-gate 	/* build entry */
25390Sstevel@tonic-gate 	data.netnumber = ecol[0].ec_value.ec_value_val;
25400Sstevel@tonic-gate 	data.netmask = ecol[1].ec_value.ec_value_val;
25410Sstevel@tonic-gate 
25420Sstevel@tonic-gate 	if (flags & F_VERBOSE)
25430Sstevel@tonic-gate 		(void) fprintf(stdout,
25440Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.netnumber);
25450Sstevel@tonic-gate 
25462277Sjs198686 	retval = (*cback)(&data, 1);
25472277Sjs198686 	if (retval != NS_LDAP_SUCCESS) {
25482277Sjs198686 		if (retval == LDAP_NO_SUCH_OBJECT)
25492277Sjs198686 			(void) fprintf(stdout,
2550*6842Sth160488 			    gettext("Cannot add netmask entry (%s), "
2551*6842Sth160488 			    "add network entry first\n"), data.netnumber);
25522277Sjs198686 		if (continue_onerror == 0)
25532277Sjs198686 			return (GENENT_CBERR);
25542277Sjs198686 	}
25550Sstevel@tonic-gate 
25560Sstevel@tonic-gate 	return (GENENT_OK);
25570Sstevel@tonic-gate }
25580Sstevel@tonic-gate 
25590Sstevel@tonic-gate static void
25600Sstevel@tonic-gate dump_netmasks(ns_ldap_result_t *res)
25610Sstevel@tonic-gate {
25620Sstevel@tonic-gate 	char	**value = NULL;
25630Sstevel@tonic-gate 
25640Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "ipNetworkNumber");
25650Sstevel@tonic-gate 	if (value && value[0])
25660Sstevel@tonic-gate 		(void) fprintf(stdout, "%s", value[0]);
25670Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "ipNetmaskNumber");
25680Sstevel@tonic-gate 	if (value && value[0])
25690Sstevel@tonic-gate 		(void) fprintf(stdout, "	%s\n", value[0]);
25700Sstevel@tonic-gate }
25710Sstevel@tonic-gate 
25720Sstevel@tonic-gate 
25730Sstevel@tonic-gate /*
25740Sstevel@tonic-gate  * /etc/netgroup
25750Sstevel@tonic-gate  * column data format is:
25760Sstevel@tonic-gate  *    col 0: netgroup name (or cname)
25770Sstevel@tonic-gate  *    col 1: netgroup member, if this is a triplet
25780Sstevel@tonic-gate  *    col 2: netgroup member, if not a triplet
25790Sstevel@tonic-gate  *    col 3: comment
25800Sstevel@tonic-gate  */
25810Sstevel@tonic-gate 
25820Sstevel@tonic-gate static int
25830Sstevel@tonic-gate genent_netgroup(char *line, int (*cback)())
25840Sstevel@tonic-gate {
25850Sstevel@tonic-gate 	char buf[BIGBUF+1];    /* netgroup entries tend to be big */
25860Sstevel@tonic-gate 	char *t;
25870Sstevel@tonic-gate 	char *cname = NULL;
25880Sstevel@tonic-gate 	entry_col ecol[4];
25890Sstevel@tonic-gate 	char *netg_tmp = NULL, *triplet_tmp = NULL;
25901603Svl199446 	int netgcount = 0, tripletcount = 0, retval = 1, i;
25910Sstevel@tonic-gate 	struct _ns_netgroups data;
25920Sstevel@tonic-gate 	int rc = GENENT_OK;
25930Sstevel@tonic-gate 
25940Sstevel@tonic-gate 	/* don't clobber our argument */
25950Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
2596*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
2597*6842Sth160488 		    PARSE_ERR_MSG_LEN);
25980Sstevel@tonic-gate 		return (GENENT_PARSEERR);
25990Sstevel@tonic-gate 	}
26000Sstevel@tonic-gate 	(void) strcpy(buf, line);
26010Sstevel@tonic-gate 
26020Sstevel@tonic-gate 	/* clear column data */
26030Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
26040Sstevel@tonic-gate 
26050Sstevel@tonic-gate 	/*
26060Sstevel@tonic-gate 	 * process 1st minimal entry, to validate that there is no
26070Sstevel@tonic-gate 	 * parsing error.
26080Sstevel@tonic-gate 	 * start with comment(col 3)
26090Sstevel@tonic-gate 	 */
26100Sstevel@tonic-gate 	t = strchr(buf, '#');
26110Sstevel@tonic-gate 	if (t) {
26120Sstevel@tonic-gate 		*t++ = 0;
26130Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = t;
26140Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = strlen(t)+1;
26150Sstevel@tonic-gate 	} else {
26160Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = "";
26170Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
26180Sstevel@tonic-gate 	}
26190Sstevel@tonic-gate 
26200Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = NULL;
26210Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = NULL;
26220Sstevel@tonic-gate 
26230Sstevel@tonic-gate 	/* cname (col 0) */
26240Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
2625*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no cname"),
2626*6842Sth160488 		    PARSE_ERR_MSG_LEN);
26270Sstevel@tonic-gate 		return (GENENT_PARSEERR);
26280Sstevel@tonic-gate 	}
26291603Svl199446 
26300Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
26310Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
26320Sstevel@tonic-gate 	cname = t;
26330Sstevel@tonic-gate 
26340Sstevel@tonic-gate 	/* addr(col 1 and 2) */
26350Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
2636*6842Sth160488 		(void) strlcpy(parse_err_msg,
2637*6842Sth160488 		    gettext("no members for netgroup"), PARSE_ERR_MSG_LEN);
26380Sstevel@tonic-gate 		return (GENENT_PARSEERR);
26390Sstevel@tonic-gate 	}
26400Sstevel@tonic-gate 
26410Sstevel@tonic-gate 	if (*t == '(') {
26421603Svl199446 		/* if token starts with '(' it must be a valid triplet */
26431603Svl199446 		if (is_triplet(t)) {
26441603Svl199446 			ecol[1].ec_value.ec_value_val = t;
26451603Svl199446 			ecol[1].ec_value.ec_value_len = strlen(t)+1;
26461603Svl199446 		} else {
2647*6842Sth160488 			(void) strlcpy(parse_err_msg,
2648*6842Sth160488 			    gettext("invalid triplet"), PARSE_ERR_MSG_LEN);
26491603Svl199446 			return (GENENT_PARSEERR);
26501603Svl199446 		}
26510Sstevel@tonic-gate 	} else {
26520Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_val = t;
26530Sstevel@tonic-gate 		ecol[2].ec_value.ec_value_len = strlen(t)+1;
26540Sstevel@tonic-gate 	}
26550Sstevel@tonic-gate 
26560Sstevel@tonic-gate 	/*
26570Sstevel@tonic-gate 	 * now build entry.
26580Sstevel@tonic-gate 	 * start by clearing entry data
26590Sstevel@tonic-gate 	 */
26600Sstevel@tonic-gate 	(void) memset((struct _ns_netgroups *)&data, 0, sizeof (data));
26610Sstevel@tonic-gate 
26620Sstevel@tonic-gate 	data.name = strdup(ecol[0].ec_value.ec_value_val);
26630Sstevel@tonic-gate 
26640Sstevel@tonic-gate 	if (ecol[1].ec_value.ec_value_val != NULL) {
26650Sstevel@tonic-gate 		if ((data.triplet = calloc(1, sizeof (char **))) == NULL) {
26660Sstevel@tonic-gate 				(void) fprintf(stderr,
2667*6842Sth160488 				    gettext("out of memory\n"));
26680Sstevel@tonic-gate 				exit(1);
26690Sstevel@tonic-gate 		}
26700Sstevel@tonic-gate 		data.triplet[tripletcount++] =
26710Sstevel@tonic-gate 		    strdup(ecol[1].ec_value.ec_value_val);
26720Sstevel@tonic-gate 	} else if (ecol[2].ec_value.ec_value_val != NULL) {
26730Sstevel@tonic-gate 			if ((data.netgroup = calloc(1, sizeof (char **)))
26740Sstevel@tonic-gate 			    == NULL) {
26750Sstevel@tonic-gate 					(void) fprintf(stderr,
26760Sstevel@tonic-gate 				    gettext("out of memory\n"));
26770Sstevel@tonic-gate 					exit(1);
26780Sstevel@tonic-gate 			}
26790Sstevel@tonic-gate 			data.netgroup[netgcount++] =
26800Sstevel@tonic-gate 			    strdup(ecol[2].ec_value.ec_value_val);
26810Sstevel@tonic-gate 	}
26820Sstevel@tonic-gate 
26830Sstevel@tonic-gate 	/*
26840Sstevel@tonic-gate 	 * we now have a valid entry (at least 1 netgroup name and
26850Sstevel@tonic-gate 	 * 1 netgroup member), proceed with the rest of the line
26860Sstevel@tonic-gate 	 */
26871603Svl199446 	while (rc == GENENT_OK && (t = strtok(NULL, " \t"))) {
26880Sstevel@tonic-gate 
26890Sstevel@tonic-gate 		/* if next token is equal to netgroup name, ignore */
26900Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
26910Sstevel@tonic-gate 			continue;
26920Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
26930Sstevel@tonic-gate 			continue;
26940Sstevel@tonic-gate 
26950Sstevel@tonic-gate 		if (*t == '(') {
26961603Svl199446 			if (is_triplet(t)) {
26971603Svl199446 				/* skip a triplet if it is added already */
26981603Svl199446 				for (i = 0; i < tripletcount &&
2699*6842Sth160488 				    strcmp(t, data.triplet[i]); i++)
27001603Svl199446 					;
27011603Svl199446 				if (i < tripletcount)
27021603Svl199446 					continue;
27031603Svl199446 
27041603Svl199446 				tripletcount++;
27051603Svl199446 				triplet_tmp = strdup(t);
27061603Svl199446 				if ((data.triplet = (char **)realloc(
2707*6842Sth160488 				    data.triplet,
2708*6842Sth160488 				    tripletcount * sizeof (char **))) == NULL) {
27091603Svl199446 					(void) fprintf(stderr,
2710*6842Sth160488 					    gettext("out of memory\n"));
27111603Svl199446 					exit(1);
27121603Svl199446 				}
27131603Svl199446 				data.triplet[tripletcount-1] = triplet_tmp;
27141603Svl199446 			} else {
2715*6842Sth160488 				(void) strlcpy(parse_err_msg,
2716*6842Sth160488 				    gettext("invalid triplet"),
2717*6842Sth160488 				    PARSE_ERR_MSG_LEN);
27181603Svl199446 				rc = GENENT_PARSEERR;
27190Sstevel@tonic-gate 			}
27200Sstevel@tonic-gate 		} else {
27211603Svl199446 			/* skip a netgroup if it is added already */
27221603Svl199446 			for (i = 0; i < netgcount &&
2723*6842Sth160488 			    strcmp(t, data.netgroup[i]); i++)
27241603Svl199446 				;
27251603Svl199446 			if (i < netgcount)
27261603Svl199446 				continue;
27271603Svl199446 
27280Sstevel@tonic-gate 			netgcount++;
27290Sstevel@tonic-gate 			netg_tmp = strdup(t);
27300Sstevel@tonic-gate 			if ((data.netgroup = (char **)realloc(data.netgroup,
2731*6842Sth160488 			    netgcount * sizeof (char **))) == NULL) {
27320Sstevel@tonic-gate 				(void) fprintf(stderr,
27330Sstevel@tonic-gate 				gettext("out of memory\n"));
27340Sstevel@tonic-gate 				exit(1);
27350Sstevel@tonic-gate 			}
27360Sstevel@tonic-gate 			data.netgroup[netgcount-1] = netg_tmp;
27370Sstevel@tonic-gate 		}
27380Sstevel@tonic-gate 	}
27390Sstevel@tonic-gate 
27400Sstevel@tonic-gate 	/* End the list with NULL */
27410Sstevel@tonic-gate 	if ((data.triplet = (char **)realloc(data.triplet,
2742*6842Sth160488 	    (tripletcount + 1) * sizeof (char **))) == NULL) {
27430Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
27440Sstevel@tonic-gate 		exit(1);
27450Sstevel@tonic-gate 	}
27460Sstevel@tonic-gate 	data.triplet[tripletcount] = NULL;
27470Sstevel@tonic-gate 	if ((data.netgroup = (char **)realloc(data.netgroup,
2748*6842Sth160488 	    (netgcount + 1) * sizeof (char **))) == NULL) {
27490Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
27500Sstevel@tonic-gate 		exit(1);
27510Sstevel@tonic-gate 	}
27520Sstevel@tonic-gate 	data.netgroup[netgcount] = NULL;
27530Sstevel@tonic-gate 
27541603Svl199446 	if (rc == GENENT_OK) {
27551603Svl199446 		if (flags & F_VERBOSE)
27561603Svl199446 			(void) fprintf(stdout,
27571603Svl199446 			    gettext("Adding entry : %s\n"), data.name);
27581603Svl199446 
27591603Svl199446 		retval = (*cback)(&data, 0);
27601603Svl199446 
27611603Svl199446 		if (retval == LDAP_ALREADY_EXISTS) {
27621603Svl199446 			if (continue_onerror)
27631603Svl199446 				(void) fprintf(stderr, gettext(
2764*6842Sth160488 				    "Entry: %s - already Exists,"
2765*6842Sth160488 				    " skipping it.\n"), data.name);
27661603Svl199446 			else {
27671603Svl199446 				rc = GENENT_CBERR;
27681603Svl199446 				(void) fprintf(stderr,
2769*6842Sth160488 				    gettext("Entry: %s - already Exists\n"),
2770*6842Sth160488 				    data.name);
27711603Svl199446 			}
27721603Svl199446 		} else if (retval)
27730Sstevel@tonic-gate 			rc = GENENT_CBERR;
27741603Svl199446 	}
27751603Svl199446 
27761603Svl199446 	/* release memory allocated by strdup() */
27771603Svl199446 	for (i = 0; i < tripletcount; i++) {
27781603Svl199446 		free(data.triplet[i]);
27791603Svl199446 	}
27801603Svl199446 	for (i = 0; i < netgcount; i++) {
27811603Svl199446 		free(data.netgroup[i]);
27821603Svl199446 	}
27830Sstevel@tonic-gate 
27840Sstevel@tonic-gate 	free(data.name);
27850Sstevel@tonic-gate 	free(data.triplet);
27860Sstevel@tonic-gate 	free(data.netgroup);
27870Sstevel@tonic-gate 
27880Sstevel@tonic-gate 	return (rc);
27890Sstevel@tonic-gate }
27900Sstevel@tonic-gate 
27910Sstevel@tonic-gate static void
27920Sstevel@tonic-gate dump_netgroup(ns_ldap_result_t *res)
27930Sstevel@tonic-gate {
27940Sstevel@tonic-gate 	char	**value = NULL;
27950Sstevel@tonic-gate 	int	attr_count = 0;
27960Sstevel@tonic-gate 
27970Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "cn");
27980Sstevel@tonic-gate 	if ((value != NULL) && (value[0] != NULL))
27990Sstevel@tonic-gate 		(void) fprintf(stdout, "%s", value[0]);
28000Sstevel@tonic-gate 	else
28010Sstevel@tonic-gate 		return;
28020Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "nisNetgroupTriple");
28030Sstevel@tonic-gate 	if (value != NULL)
28040Sstevel@tonic-gate 		while (value[attr_count] != NULL) {
28050Sstevel@tonic-gate 			(void) fprintf(stdout, " %s", value[attr_count]);
28060Sstevel@tonic-gate 			attr_count++;
28070Sstevel@tonic-gate 		}
28082300Sjs198686 	attr_count = 0;
28090Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "memberNisNetgroup");
28100Sstevel@tonic-gate 	if (value != NULL)
28110Sstevel@tonic-gate 		while (value[attr_count] != NULL) {
28120Sstevel@tonic-gate 			(void) fprintf(stdout, " %s", value[attr_count]);
28130Sstevel@tonic-gate 			attr_count++;
28140Sstevel@tonic-gate 		}
28150Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
28160Sstevel@tonic-gate 
28170Sstevel@tonic-gate }
28180Sstevel@tonic-gate 
28190Sstevel@tonic-gate static int
28200Sstevel@tonic-gate genent_automount(char *line, int (*cback)())
28210Sstevel@tonic-gate {
28220Sstevel@tonic-gate 	char buf[BUFSIZ+1];
28230Sstevel@tonic-gate 	char *t, *s;
28240Sstevel@tonic-gate 	entry_col ecol[2];
28250Sstevel@tonic-gate 	struct _ns_automount data;
28260Sstevel@tonic-gate 	int retval = 1;
28270Sstevel@tonic-gate 	int rc = GENENT_OK;
28280Sstevel@tonic-gate 
28290Sstevel@tonic-gate 	/*
28300Sstevel@tonic-gate 	 * don't clobber our argument
28310Sstevel@tonic-gate 	 */
28320Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
2833*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
2834*6842Sth160488 		    PARSE_ERR_MSG_LEN);
28350Sstevel@tonic-gate 		return (GENENT_PARSEERR);
2836*6842Sth160488 	}
28370Sstevel@tonic-gate 
28380Sstevel@tonic-gate 	/* replace every tabspace with single space */
28390Sstevel@tonic-gate 	replace_tab2space(line);
28400Sstevel@tonic-gate 	(void) strcpy(buf, line);
28410Sstevel@tonic-gate 
28420Sstevel@tonic-gate 	/*
28430Sstevel@tonic-gate 	 * clear column data
28440Sstevel@tonic-gate 	 */
28450Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
28460Sstevel@tonic-gate 
28470Sstevel@tonic-gate 	/*
28480Sstevel@tonic-gate 	 * key (col 0)
28490Sstevel@tonic-gate 	 */
28500Sstevel@tonic-gate 	t = buf;
28510Sstevel@tonic-gate 	while (t[0] == ' ')
28520Sstevel@tonic-gate 		t++;
28530Sstevel@tonic-gate 
28540Sstevel@tonic-gate 	if ((s = strchr(t, ' ')) == 0) {
28550Sstevel@tonic-gate 		return (GENENT_PARSEERR);
28560Sstevel@tonic-gate 	}
28570Sstevel@tonic-gate 	*s++ = 0;
28580Sstevel@tonic-gate 
28590Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
28600Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
28610Sstevel@tonic-gate 	t = s;
28620Sstevel@tonic-gate 
28630Sstevel@tonic-gate 	while (t[0] == ' ')
28640Sstevel@tonic-gate 		t++;
28650Sstevel@tonic-gate 
28660Sstevel@tonic-gate 	/*
28670Sstevel@tonic-gate 	 * mapentry (col 1)
28680Sstevel@tonic-gate 	 */
28690Sstevel@tonic-gate 
28700Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = t;
28710Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_len = strlen(t)+1;
28720Sstevel@tonic-gate 
28730Sstevel@tonic-gate 	data.mapname = strdup(databasetype);
28740Sstevel@tonic-gate 	data.key = strdup(ecol[0].ec_value.ec_value_val);
28750Sstevel@tonic-gate 	data.value = strdup(ecol[1].ec_value.ec_value_val);
28760Sstevel@tonic-gate 
28770Sstevel@tonic-gate 	if (flags & F_VERBOSE)
28780Sstevel@tonic-gate 		(void) fprintf(stdout,
28790Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.key);
28800Sstevel@tonic-gate 
28810Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
28820Sstevel@tonic-gate 
28830Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
28840Sstevel@tonic-gate 		if (continue_onerror)
28850Sstevel@tonic-gate 			(void) fprintf(stderr,
2886*6842Sth160488 			    gettext("Entry: %s - already Exists,"
2887*6842Sth160488 			    " skipping it.\n"), data.key);
28880Sstevel@tonic-gate 		else {
28890Sstevel@tonic-gate 			rc = GENENT_CBERR;
28900Sstevel@tonic-gate 			(void) fprintf(stderr,
2891*6842Sth160488 			    gettext("Entry: %s - already Exists\n"),
2892*6842Sth160488 			    data.key);
28930Sstevel@tonic-gate 		}
28940Sstevel@tonic-gate 	} else if (retval)
28950Sstevel@tonic-gate 		rc = GENENT_CBERR;
28960Sstevel@tonic-gate 
28970Sstevel@tonic-gate 	free(data.mapname);
28980Sstevel@tonic-gate 	free(data.key);
28990Sstevel@tonic-gate 	free(data.value);
29000Sstevel@tonic-gate 	return (rc);
29010Sstevel@tonic-gate }
29020Sstevel@tonic-gate 
29030Sstevel@tonic-gate static void
29040Sstevel@tonic-gate dump_automount(ns_ldap_result_t *res)
29050Sstevel@tonic-gate {
29060Sstevel@tonic-gate 	char	**value = NULL;
29070Sstevel@tonic-gate 
29080Sstevel@tonic-gate 	if (res == NULL)
29090Sstevel@tonic-gate 		return;
29100Sstevel@tonic-gate 
29110Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "automountKey");
29120Sstevel@tonic-gate 	if (value != NULL) {
29130Sstevel@tonic-gate 		(void) fprintf(stdout, "%s", value[0]);
29140Sstevel@tonic-gate 		value = __ns_ldap_getAttr(res->entry, "automountInformation");
29150Sstevel@tonic-gate 		if (value != NULL)
29160Sstevel@tonic-gate 			(void) fprintf(stdout, "	%s\n", value[0]);
29170Sstevel@tonic-gate 		else
29180Sstevel@tonic-gate 			(void) fprintf(stdout, "\n");
29190Sstevel@tonic-gate 	}
29200Sstevel@tonic-gate }
29210Sstevel@tonic-gate 
29220Sstevel@tonic-gate 
29230Sstevel@tonic-gate /*
29240Sstevel@tonic-gate  * /etc/passwd
29250Sstevel@tonic-gate  *
29260Sstevel@tonic-gate  */
29270Sstevel@tonic-gate 
29280Sstevel@tonic-gate static int
29290Sstevel@tonic-gate genent_passwd(char *line, int (*cback)())
29300Sstevel@tonic-gate {
29310Sstevel@tonic-gate 	char buf[BUFSIZ+1];
29320Sstevel@tonic-gate 	char *s, *t;
29330Sstevel@tonic-gate 	entry_col ecol[8];
29340Sstevel@tonic-gate 	int retval = 1;
29350Sstevel@tonic-gate 	char pname[BUFSIZ];
29360Sstevel@tonic-gate 
29370Sstevel@tonic-gate 	struct passwd	data;
29380Sstevel@tonic-gate 	int rc = GENENT_OK;
29390Sstevel@tonic-gate 
29400Sstevel@tonic-gate 
29410Sstevel@tonic-gate 	/*
29420Sstevel@tonic-gate 	 * don't clobber our argument
29430Sstevel@tonic-gate 	 */
29440Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
2945*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
2946*6842Sth160488 		    PARSE_ERR_MSG_LEN);
29470Sstevel@tonic-gate 		return (GENENT_PARSEERR);
29480Sstevel@tonic-gate 	}
29490Sstevel@tonic-gate 	(void) strcpy(buf, line);
29500Sstevel@tonic-gate 	t = buf;
29510Sstevel@tonic-gate 
29520Sstevel@tonic-gate 	/* ignore empty entries */
29530Sstevel@tonic-gate 	if (*t == '\0')
29540Sstevel@tonic-gate 		return (GENENT_OK);
29550Sstevel@tonic-gate 
29560Sstevel@tonic-gate 	/*
29570Sstevel@tonic-gate 	 * clear column data
29580Sstevel@tonic-gate 	 */
29590Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
29600Sstevel@tonic-gate 
29610Sstevel@tonic-gate 	/*
29620Sstevel@tonic-gate 	 * name (col 0)
29630Sstevel@tonic-gate 	 */
29640Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
2965*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no password"),
2966*6842Sth160488 		    PARSE_ERR_MSG_LEN);
29670Sstevel@tonic-gate 		return (GENENT_PARSEERR);
29680Sstevel@tonic-gate 	}
29690Sstevel@tonic-gate 	*s++ = 0;
29700Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
29710Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
29720Sstevel@tonic-gate 	t = s;
29730Sstevel@tonic-gate 
29740Sstevel@tonic-gate 	/*
29750Sstevel@tonic-gate 	 * passwd (col 1)
29760Sstevel@tonic-gate 	 */
29770Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
2978*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no uid"),
2979*6842Sth160488 		    PARSE_ERR_MSG_LEN);
29800Sstevel@tonic-gate 		return (GENENT_PARSEERR);
29810Sstevel@tonic-gate 	}
29820Sstevel@tonic-gate 	*s++ = 0;
29830Sstevel@tonic-gate 
29840Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_val = t;
29850Sstevel@tonic-gate 	ecol[1].ec_value.ec_value_len = strlen(t)+1;
29860Sstevel@tonic-gate 
29870Sstevel@tonic-gate 	t = s;
29880Sstevel@tonic-gate 
29890Sstevel@tonic-gate 	/*
29900Sstevel@tonic-gate 	 * uid (col 2)
29910Sstevel@tonic-gate 	 */
29920Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0 || s == t) {
2993*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no gid"),
2994*6842Sth160488 		    PARSE_ERR_MSG_LEN);
29950Sstevel@tonic-gate 		return (GENENT_PARSEERR);
29960Sstevel@tonic-gate 	}
29970Sstevel@tonic-gate 	*s++ = 0;
29980Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
29990Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
30000Sstevel@tonic-gate 	t = s;
30010Sstevel@tonic-gate 
30020Sstevel@tonic-gate 	/*
30030Sstevel@tonic-gate 	 * gid (col 3)
30040Sstevel@tonic-gate 	 */
30050Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0 || s == t) {
3006*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no gcos"),
3007*6842Sth160488 		    PARSE_ERR_MSG_LEN);
30080Sstevel@tonic-gate 		return (GENENT_PARSEERR);
30090Sstevel@tonic-gate 	}
30100Sstevel@tonic-gate 	*s++ = 0;
30110Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_val = t;
30120Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_len = strlen(t)+1;
30130Sstevel@tonic-gate 	t = s;
30140Sstevel@tonic-gate 
30150Sstevel@tonic-gate 	/*
30160Sstevel@tonic-gate 	 * gcos (col 4)
30170Sstevel@tonic-gate 	 */
30180Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
3019*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no home"),
3020*6842Sth160488 		    PARSE_ERR_MSG_LEN);
30210Sstevel@tonic-gate 		return (GENENT_PARSEERR);
30220Sstevel@tonic-gate 	}
30230Sstevel@tonic-gate 	*s++ = 0;
30240Sstevel@tonic-gate 	ecol[4].ec_value.ec_value_val = t;
30250Sstevel@tonic-gate 	ecol[4].ec_value.ec_value_len = strlen(t)+1;
30260Sstevel@tonic-gate 	t = s;
30270Sstevel@tonic-gate 
30280Sstevel@tonic-gate 	/*
30290Sstevel@tonic-gate 	 * home (col 5)
30300Sstevel@tonic-gate 	 */
30310Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
3032*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no shell"),
3033*6842Sth160488 		    PARSE_ERR_MSG_LEN);
30340Sstevel@tonic-gate 		return (GENENT_PARSEERR);
30350Sstevel@tonic-gate 	}
30360Sstevel@tonic-gate 	*s++ = 0;
30370Sstevel@tonic-gate 	ecol[5].ec_value.ec_value_val = t;
30380Sstevel@tonic-gate 	ecol[5].ec_value.ec_value_len = strlen(t)+1;
30390Sstevel@tonic-gate 	t = s;
30400Sstevel@tonic-gate 
30410Sstevel@tonic-gate 	/*
30420Sstevel@tonic-gate 	 * shell (col 6)
30430Sstevel@tonic-gate 	 */
30440Sstevel@tonic-gate 	ecol[6].ec_value.ec_value_val = t;
30450Sstevel@tonic-gate 	ecol[6].ec_value.ec_value_len = strlen(t)+1;
30460Sstevel@tonic-gate 
30470Sstevel@tonic-gate 	/*
30480Sstevel@tonic-gate 	 * build entry
30490Sstevel@tonic-gate 	 */
30500Sstevel@tonic-gate 	data.pw_name = strdup(ecol[0].ec_value.ec_value_val);
30510Sstevel@tonic-gate 
30520Sstevel@tonic-gate 	if (flags & F_PASSWD) {
30530Sstevel@tonic-gate 		/* Add {crypt} before passwd entry */
30540Sstevel@tonic-gate 		(void) snprintf(pname, sizeof (pname), "{crypt}%s",
30550Sstevel@tonic-gate 		    ecol[1].ec_value.ec_value_val);
30560Sstevel@tonic-gate 		data.pw_passwd = strdup(pname);
30570Sstevel@tonic-gate 	}
30580Sstevel@tonic-gate 	else
30590Sstevel@tonic-gate 		data.pw_passwd = NULL;
30600Sstevel@tonic-gate 
30610Sstevel@tonic-gate 	if (ecol[2].ec_value.ec_value_val != NULL &&
30620Sstevel@tonic-gate 	    ecol[2].ec_value.ec_value_val[0] != '\0') {
30630Sstevel@tonic-gate 		data.pw_uid = ascii_to_int(ecol[2].ec_value.ec_value_val);
3064*6842Sth160488 		if (data.pw_uid == (uid_t)-1) {
30650Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3066*6842Sth160488 			    gettext("invalid uid : %s"),
3067*6842Sth160488 			    ecol[2].ec_value.ec_value_val);
30680Sstevel@tonic-gate 		return (GENENT_PARSEERR);
30690Sstevel@tonic-gate 		}
30700Sstevel@tonic-gate 	} else
3071*6842Sth160488 		data.pw_uid = (uid_t)-1;
30720Sstevel@tonic-gate 
30730Sstevel@tonic-gate 	if (ecol[3].ec_value.ec_value_val != NULL &&
3074*6842Sth160488 	    ecol[3].ec_value.ec_value_val[0] != '\0') {
30750Sstevel@tonic-gate 
30760Sstevel@tonic-gate 		data.pw_gid = ascii_to_int(ecol[3].ec_value.ec_value_val);
3077*6842Sth160488 		if (data.pw_gid == (uid_t)-1) {
30780Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3079*6842Sth160488 			    gettext("invalid gid : %s"),
3080*6842Sth160488 			    ecol[3].ec_value.ec_value_val);
30810Sstevel@tonic-gate 		return (GENENT_PARSEERR);
30820Sstevel@tonic-gate 		}
30830Sstevel@tonic-gate 	} else
3084*6842Sth160488 		data.pw_gid = (uid_t)-1;
30850Sstevel@tonic-gate 
30860Sstevel@tonic-gate 	data.pw_age = NULL;
30870Sstevel@tonic-gate 	data.pw_comment = NULL;
30880Sstevel@tonic-gate 	data.pw_gecos = strdup(ecol[4].ec_value.ec_value_val);
30890Sstevel@tonic-gate 	data.pw_dir = strdup(ecol[5].ec_value.ec_value_val);
30900Sstevel@tonic-gate 	data.pw_shell = strdup(ecol[6].ec_value.ec_value_val);
30910Sstevel@tonic-gate 
30920Sstevel@tonic-gate 	if (flags & F_VERBOSE)
30930Sstevel@tonic-gate 		(void) fprintf(stdout,
30940Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.pw_name);
30950Sstevel@tonic-gate 
30960Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
30970Sstevel@tonic-gate 
30980Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
30990Sstevel@tonic-gate 		if (continue_onerror)
31000Sstevel@tonic-gate 			(void) fprintf(stderr,
3101*6842Sth160488 			    gettext("Entry: %s - already Exists,"
3102*6842Sth160488 			    " skipping it.\n"), data.pw_name);
31030Sstevel@tonic-gate 		else {
31040Sstevel@tonic-gate 			rc = GENENT_CBERR;
31050Sstevel@tonic-gate 			(void) fprintf(stderr,
3106*6842Sth160488 			    gettext("Entry: %s - already Exists\n"),
3107*6842Sth160488 			    data.pw_name);
31080Sstevel@tonic-gate 		}
31090Sstevel@tonic-gate 	} else if (retval)
31100Sstevel@tonic-gate 		rc = GENENT_CBERR;
31110Sstevel@tonic-gate 
31120Sstevel@tonic-gate 	free(data.pw_name);
31130Sstevel@tonic-gate 	free(data.pw_gecos);
31140Sstevel@tonic-gate 	free(data.pw_dir);
31150Sstevel@tonic-gate 	free(data.pw_shell);
31160Sstevel@tonic-gate 	return (rc);
31170Sstevel@tonic-gate }
31180Sstevel@tonic-gate 
31190Sstevel@tonic-gate 
31200Sstevel@tonic-gate static void
31210Sstevel@tonic-gate dump_passwd(ns_ldap_result_t *res)
31220Sstevel@tonic-gate {
31230Sstevel@tonic-gate 	char    **value = NULL;
31240Sstevel@tonic-gate 	char	pnam[256];
31250Sstevel@tonic-gate 
31260Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "uid");
31270Sstevel@tonic-gate 	if (value == NULL)
31280Sstevel@tonic-gate 		return;
31290Sstevel@tonic-gate 	else
31300Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
31310Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "userPassword");
31320Sstevel@tonic-gate 	if (value == NULL)
31330Sstevel@tonic-gate 		(void) fprintf(stdout, "*:");
31340Sstevel@tonic-gate 	else {
31350Sstevel@tonic-gate 		(void) strcpy(pnam, value[0]);
31360Sstevel@tonic-gate 		if (strncasecmp(value[0], "{crypt}", 7) == 0)
31370Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", (pnam+7));
31380Sstevel@tonic-gate 		else
31390Sstevel@tonic-gate 			(void) fprintf(stdout, "*:");
31400Sstevel@tonic-gate 	}
31410Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "uidNumber");
31420Sstevel@tonic-gate 	if (value && value[0])
31430Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
31440Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "gidNumber");
31450Sstevel@tonic-gate 	if (value && value[0])
31460Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
31470Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "gecos");
31480Sstevel@tonic-gate 	if (value == NULL)
31490Sstevel@tonic-gate 		(void) fprintf(stdout, ":");
31500Sstevel@tonic-gate 	else
31510Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
31520Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "homeDirectory");
31530Sstevel@tonic-gate 	if (value == NULL)
31540Sstevel@tonic-gate 		(void) fprintf(stdout, ":");
31550Sstevel@tonic-gate 	else
31560Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
31570Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "loginShell");
31580Sstevel@tonic-gate 	if (value == NULL)
31590Sstevel@tonic-gate 		(void) fprintf(stdout, "\n");
31600Sstevel@tonic-gate 	else
31610Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\n", value[0]);
31620Sstevel@tonic-gate 
31630Sstevel@tonic-gate }
31640Sstevel@tonic-gate 
31650Sstevel@tonic-gate /*
31660Sstevel@tonic-gate  * /etc/shadow
31670Sstevel@tonic-gate  */
31680Sstevel@tonic-gate 
31690Sstevel@tonic-gate static int
31700Sstevel@tonic-gate genent_shadow(char *line, int (*cback)())
31710Sstevel@tonic-gate {
31720Sstevel@tonic-gate 	char buf[BUFSIZ+1];
31730Sstevel@tonic-gate 	char *s, *t;
31740Sstevel@tonic-gate 	entry_col ecol[9];
31750Sstevel@tonic-gate 	char pname[BUFSIZ];
31760Sstevel@tonic-gate 
31770Sstevel@tonic-gate 	struct spwd	data;
31780Sstevel@tonic-gate 	int spflag;
31792277Sjs198686 	int retval;
31800Sstevel@tonic-gate 
31810Sstevel@tonic-gate 
31820Sstevel@tonic-gate 	/*
31830Sstevel@tonic-gate 	 * don't clobber our argument
31840Sstevel@tonic-gate 	 */
31850Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
3186*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
3187*6842Sth160488 		    PARSE_ERR_MSG_LEN);
31880Sstevel@tonic-gate 		return (GENENT_PARSEERR);
31890Sstevel@tonic-gate 	}
31900Sstevel@tonic-gate 	(void) strcpy(buf, line);
31910Sstevel@tonic-gate 	t = buf;
31920Sstevel@tonic-gate 
31930Sstevel@tonic-gate 	/* ignore empty entries */
31940Sstevel@tonic-gate 	if (*t == '\0')
31950Sstevel@tonic-gate 		return (GENENT_OK);
31960Sstevel@tonic-gate 
31970Sstevel@tonic-gate 	/*
31980Sstevel@tonic-gate 	 * clear column data
31990Sstevel@tonic-gate 	 */
32000Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
32010Sstevel@tonic-gate 
32020Sstevel@tonic-gate 	/*
32030Sstevel@tonic-gate 	 * name (col 0)
32040Sstevel@tonic-gate 	 */
32050Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
3206*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no uid"),
3207*6842Sth160488 		    PARSE_ERR_MSG_LEN);
32080Sstevel@tonic-gate 		return (GENENT_PARSEERR);
32090Sstevel@tonic-gate 	}
32100Sstevel@tonic-gate 	*s++ = 0;
32110Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
32120Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
32130Sstevel@tonic-gate 	t = s;
32140Sstevel@tonic-gate 
32150Sstevel@tonic-gate 	/*
32160Sstevel@tonic-gate 	 * passwd (col 1)
32170Sstevel@tonic-gate 	 */
32180Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
3219*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("Improper format"),
3220*6842Sth160488 		    PARSE_ERR_MSG_LEN);
32210Sstevel@tonic-gate 		return (GENENT_PARSEERR);
32220Sstevel@tonic-gate 	}
32230Sstevel@tonic-gate 	*s++ = 0;
32240Sstevel@tonic-gate 
32250Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
32260Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
32270Sstevel@tonic-gate 
32280Sstevel@tonic-gate 	t = s;
32290Sstevel@tonic-gate 
32300Sstevel@tonic-gate 	/*
32310Sstevel@tonic-gate 	 * shadow last change (col 2)
32320Sstevel@tonic-gate 	 */
32330Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
3234*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("Improper format"),
3235*6842Sth160488 		    PARSE_ERR_MSG_LEN);
32360Sstevel@tonic-gate 		return (GENENT_PARSEERR);
32370Sstevel@tonic-gate 	}
32380Sstevel@tonic-gate 	*s++ = 0;
32390Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
32400Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
32410Sstevel@tonic-gate 	t = s;
32420Sstevel@tonic-gate 
32430Sstevel@tonic-gate 	/*
32440Sstevel@tonic-gate 	 * shadow min (col 3)
32450Sstevel@tonic-gate 	 */
32460Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
3247*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("Improper format"),
3248*6842Sth160488 		    PARSE_ERR_MSG_LEN);
32490Sstevel@tonic-gate 		return (GENENT_PARSEERR);
32500Sstevel@tonic-gate 	}
32510Sstevel@tonic-gate 	*s++ = 0;
32520Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_val = t;
32530Sstevel@tonic-gate 	ecol[3].ec_value.ec_value_len = strlen(t)+1;
32540Sstevel@tonic-gate 	t = s;
32550Sstevel@tonic-gate 
32560Sstevel@tonic-gate 	/*
32570Sstevel@tonic-gate 	 * shadow max (col 4)
32580Sstevel@tonic-gate 	 */
32590Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
3260*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("Improper format"),
3261*6842Sth160488 		    PARSE_ERR_MSG_LEN);
32620Sstevel@tonic-gate 		return (GENENT_PARSEERR);
32630Sstevel@tonic-gate 	}
32640Sstevel@tonic-gate 	*s++ = 0;
32650Sstevel@tonic-gate 	ecol[4].ec_value.ec_value_val = t;
32660Sstevel@tonic-gate 	ecol[4].ec_value.ec_value_len = strlen(t)+1;
32670Sstevel@tonic-gate 	t = s;
32680Sstevel@tonic-gate 
32690Sstevel@tonic-gate 	/*
32700Sstevel@tonic-gate 	 * shadow warn (col 5)
32710Sstevel@tonic-gate 	 */
32720Sstevel@tonic-gate 	if ((s = strchr(t, ':')) == 0) {
3273*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("Improper format"),
3274*6842Sth160488 		    PARSE_ERR_MSG_LEN);
32750Sstevel@tonic-gate 		return (GENENT_PARSEERR);
32760Sstevel@tonic-gate 	}
32770Sstevel@tonic-gate 	*s++ = 0;
32780Sstevel@tonic-gate 	ecol[5].ec_value.ec_value_val = t;
32790Sstevel@tonic-gate 	ecol[5].ec_value.ec_value_len = strlen(t)+1;
32800Sstevel@tonic-gate 	t = s;
32810Sstevel@tonic-gate 
32820Sstevel@tonic-gate 	/*
32830Sstevel@tonic-gate 	 * shadow inactive (col 6)
32840Sstevel@tonic-gate 	 */
32850Sstevel@tonic-gate 	if ((s = strchr(t, ':')) != 0) {
32860Sstevel@tonic-gate 	*s++ = 0;
32870Sstevel@tonic-gate 	ecol[6].ec_value.ec_value_val = t;
32880Sstevel@tonic-gate 	ecol[6].ec_value.ec_value_len = strlen(t)+1;
32890Sstevel@tonic-gate 	t = s;
32900Sstevel@tonic-gate 	}
32910Sstevel@tonic-gate 
32920Sstevel@tonic-gate 	/*
32930Sstevel@tonic-gate 	 * shadow expire  (col 7)
32940Sstevel@tonic-gate 	 */
32950Sstevel@tonic-gate 	if ((s = strchr(t, ':')) != 0) {
32960Sstevel@tonic-gate 	*s++ = 0;
32970Sstevel@tonic-gate 	ecol[7].ec_value.ec_value_val = t;
32980Sstevel@tonic-gate 	ecol[7].ec_value.ec_value_len = strlen(t)+1;
32990Sstevel@tonic-gate 	t = s;
33000Sstevel@tonic-gate 
33010Sstevel@tonic-gate 	/*
33020Sstevel@tonic-gate 	 * flag (col 8)
33030Sstevel@tonic-gate 	 */
33040Sstevel@tonic-gate 	ecol[8].ec_value.ec_value_val = t;
33050Sstevel@tonic-gate 	ecol[8].ec_value.ec_value_len = strlen(t)+1;
33060Sstevel@tonic-gate 	}
33070Sstevel@tonic-gate 
33080Sstevel@tonic-gate 	/*
33090Sstevel@tonic-gate 	 * build entry
33100Sstevel@tonic-gate 	 */
33110Sstevel@tonic-gate 
33120Sstevel@tonic-gate 	data.sp_namp = strdup(ecol[0].ec_value.ec_value_val);
33130Sstevel@tonic-gate 
33140Sstevel@tonic-gate 	if (ecol[1].ec_value.ec_value_val != NULL &&
3315*6842Sth160488 	    ecol[1].ec_value.ec_value_val[0] != '\0') {
33160Sstevel@tonic-gate 		/* Add {crypt} before passwd entry */
33170Sstevel@tonic-gate 		(void) snprintf(pname, sizeof (pname), "{crypt}%s",
33180Sstevel@tonic-gate 		    ecol[1].ec_value.ec_value_val);
33190Sstevel@tonic-gate 		data.sp_pwdp = strdup(pname);
33200Sstevel@tonic-gate 	} else
33210Sstevel@tonic-gate 		data.sp_pwdp = NULL;
33220Sstevel@tonic-gate 
33230Sstevel@tonic-gate 	if (ecol[2].ec_value.ec_value_val != NULL &&
3324*6842Sth160488 	    ecol[2].ec_value.ec_value_val[0] != '\0') {
33250Sstevel@tonic-gate 
33260Sstevel@tonic-gate 		data.sp_lstchg = ascii_to_int(ecol[2].ec_value.ec_value_val);
33270Sstevel@tonic-gate 		if (data.sp_lstchg < -1) {
33280Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3329*6842Sth160488 			    gettext("invalid last changed date: %s"),
33300Sstevel@tonic-gate 			    ecol[2].ec_value.ec_value_val);
33310Sstevel@tonic-gate 		return (GENENT_PARSEERR);
33320Sstevel@tonic-gate 		}
33330Sstevel@tonic-gate 	} else
33340Sstevel@tonic-gate 		data.sp_lstchg = -1;
33350Sstevel@tonic-gate 
33360Sstevel@tonic-gate 	if (ecol[3].ec_value.ec_value_val != NULL &&
3337*6842Sth160488 	    ecol[3].ec_value.ec_value_val[0] != '\0') {
33380Sstevel@tonic-gate 
33390Sstevel@tonic-gate 		data.sp_min = ascii_to_int(ecol[3].ec_value.ec_value_val);
33400Sstevel@tonic-gate 		if (data.sp_min < -1) {
33410Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3342*6842Sth160488 			    gettext("invalid sp_min : %s"),
33430Sstevel@tonic-gate 			    ecol[3].ec_value.ec_value_val);
33440Sstevel@tonic-gate 		return (GENENT_PARSEERR);
33450Sstevel@tonic-gate 		}
33460Sstevel@tonic-gate 	} else
33470Sstevel@tonic-gate 		data.sp_min = -1;
33480Sstevel@tonic-gate 
33490Sstevel@tonic-gate 	if (ecol[4].ec_value.ec_value_val != NULL &&
3350*6842Sth160488 	    ecol[4].ec_value.ec_value_val[0] != '\0') {
33510Sstevel@tonic-gate 
33520Sstevel@tonic-gate 		data.sp_max = ascii_to_int(ecol[4].ec_value.ec_value_val);
33530Sstevel@tonic-gate 		if (data.sp_max < -1) {
33540Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3355*6842Sth160488 			    gettext("invalid sp_max : %s"),
33560Sstevel@tonic-gate 			    ecol[4].ec_value.ec_value_val);
33570Sstevel@tonic-gate 		return (GENENT_PARSEERR);
33580Sstevel@tonic-gate 		}
33590Sstevel@tonic-gate 	} else
33600Sstevel@tonic-gate 		data.sp_max = -1;
33610Sstevel@tonic-gate 
33620Sstevel@tonic-gate 	if (ecol[5].ec_value.ec_value_val != NULL &&
3363*6842Sth160488 	    ecol[5].ec_value.ec_value_val[0] != '\0') {
33640Sstevel@tonic-gate 
33650Sstevel@tonic-gate 		data.sp_warn = ascii_to_int(ecol[5].ec_value.ec_value_val);
33660Sstevel@tonic-gate 		if (data.sp_warn < -1) {
33670Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3368*6842Sth160488 			    gettext("invalid sp_warn : %s"),
33690Sstevel@tonic-gate 			    ecol[5].ec_value.ec_value_val);
33700Sstevel@tonic-gate 		return (GENENT_PARSEERR);
33710Sstevel@tonic-gate 		}
33720Sstevel@tonic-gate 	} else
33730Sstevel@tonic-gate 		data.sp_warn = -1;
33740Sstevel@tonic-gate 
33750Sstevel@tonic-gate 	if (ecol[6].ec_value.ec_value_val != NULL &&
3376*6842Sth160488 	    ecol[6].ec_value.ec_value_val[0] != '\0') {
33770Sstevel@tonic-gate 
33780Sstevel@tonic-gate 		data.sp_inact = ascii_to_int(ecol[6].ec_value.ec_value_val);
33790Sstevel@tonic-gate 		if (data.sp_inact < -1) {
33800Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3381*6842Sth160488 			    gettext("invalid sp_inact : %s"),
33820Sstevel@tonic-gate 			    ecol[6].ec_value.ec_value_val);
33830Sstevel@tonic-gate 		return (GENENT_PARSEERR);
33840Sstevel@tonic-gate 		}
33850Sstevel@tonic-gate 	} else
33860Sstevel@tonic-gate 		data.sp_inact = -1;
33870Sstevel@tonic-gate 
33880Sstevel@tonic-gate 	if (ecol[7].ec_value.ec_value_val != NULL &&
3389*6842Sth160488 	    ecol[7].ec_value.ec_value_val[0] != '\0') {
33900Sstevel@tonic-gate 
33910Sstevel@tonic-gate 		data.sp_expire = ascii_to_int(ecol[7].ec_value.ec_value_val);
33920Sstevel@tonic-gate 		if (data.sp_expire < -1) {
33930Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3394*6842Sth160488 			    gettext("invalid login expiry date : %s"),
33950Sstevel@tonic-gate 			    ecol[7].ec_value.ec_value_val);
33960Sstevel@tonic-gate 		return (GENENT_PARSEERR);
33970Sstevel@tonic-gate 		}
33980Sstevel@tonic-gate 	} else
33990Sstevel@tonic-gate 		data.sp_expire = -1;
34000Sstevel@tonic-gate 
34010Sstevel@tonic-gate 	if (ecol[8].ec_value.ec_value_val != NULL &&
3402*6842Sth160488 	    ecol[8].ec_value.ec_value_val[0] != '\0') {
34030Sstevel@tonic-gate 
34040Sstevel@tonic-gate 		/*
34050Sstevel@tonic-gate 		 * data.sp_flag is an unsigned int,
34060Sstevel@tonic-gate 		 * assign -1 to it, make no sense.
34070Sstevel@tonic-gate 		 * Use spflag here to avoid lint warning.
34080Sstevel@tonic-gate 		 */
34090Sstevel@tonic-gate 		spflag = ascii_to_int(ecol[8].ec_value.ec_value_val);
34100Sstevel@tonic-gate 		if (spflag < 0) {
34110Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3412*6842Sth160488 			    gettext("invalid flag value: %s"),
34130Sstevel@tonic-gate 			    ecol[8].ec_value.ec_value_val);
34140Sstevel@tonic-gate 		return (GENENT_PARSEERR);
34150Sstevel@tonic-gate 		} else
34160Sstevel@tonic-gate 			data.sp_flag = spflag;
34170Sstevel@tonic-gate 	} else
34180Sstevel@tonic-gate 		data.sp_flag = 0;
34190Sstevel@tonic-gate 
34200Sstevel@tonic-gate 	if (flags & F_VERBOSE)
34210Sstevel@tonic-gate 		(void) fprintf(stdout,
34220Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.sp_namp);
34230Sstevel@tonic-gate 
34242277Sjs198686 	retval = (*cback)(&data, 1);
34252277Sjs198686 	if (retval != NS_LDAP_SUCCESS) {
34262277Sjs198686 		if (retval == LDAP_NO_SUCH_OBJECT)
34272277Sjs198686 			(void) fprintf(stdout,
3428*6842Sth160488 			    gettext("Cannot add shadow entry (%s), "
3429*6842Sth160488 			    "add passwd entry first\n"), data.sp_namp);
34302277Sjs198686 		if (continue_onerror == 0)
34312277Sjs198686 			return (GENENT_CBERR);
34322277Sjs198686 	}
34330Sstevel@tonic-gate 
34340Sstevel@tonic-gate 	free(data.sp_namp);
34350Sstevel@tonic-gate 	free(data.sp_pwdp);
34360Sstevel@tonic-gate 	return (GENENT_OK);
34370Sstevel@tonic-gate }
34380Sstevel@tonic-gate 
34390Sstevel@tonic-gate static void
34400Sstevel@tonic-gate dump_shadow(ns_ldap_result_t *res)
34410Sstevel@tonic-gate {
34420Sstevel@tonic-gate 	char    **value = NULL;
34430Sstevel@tonic-gate 	char   pnam[256];
34440Sstevel@tonic-gate 
34450Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "uid");
34460Sstevel@tonic-gate 	if (value == NULL)
34470Sstevel@tonic-gate 		return;
34480Sstevel@tonic-gate 	else
34490Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
34500Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "userPassword");
34510Sstevel@tonic-gate 	if (value == NULL)
34520Sstevel@tonic-gate 		(void) fprintf(stdout, "*:");
34530Sstevel@tonic-gate 	else {
34540Sstevel@tonic-gate 		(void) strcpy(pnam, value[0]);
34550Sstevel@tonic-gate 		if (strncasecmp(value[0], "{crypt}", 7) == 0)
34560Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", (pnam+7));
34570Sstevel@tonic-gate 		else
34580Sstevel@tonic-gate 			(void) fprintf(stdout, "*:");
34590Sstevel@tonic-gate 	}
34600Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "shadowLastChange");
34610Sstevel@tonic-gate 	if (value == NULL)
34620Sstevel@tonic-gate 		(void) fprintf(stdout, ":");
34630Sstevel@tonic-gate 	else
34640Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
34650Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "shadowMin");
34660Sstevel@tonic-gate 	if (value == NULL)
34670Sstevel@tonic-gate 		(void) fprintf(stdout, ":");
34680Sstevel@tonic-gate 	else
34690Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
34700Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "shadowMax");
34710Sstevel@tonic-gate 	if (value == NULL)
34720Sstevel@tonic-gate 		(void) fprintf(stdout, ":");
34730Sstevel@tonic-gate 	else
34740Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", value[0]);
34750Sstevel@tonic-gate 
34760Sstevel@tonic-gate 	/* ignore shadowWarning, shadowInactive, shadowExpire, shadowFlag */
34770Sstevel@tonic-gate 	(void) fprintf(stdout, ":::\n");
34780Sstevel@tonic-gate 
34790Sstevel@tonic-gate }
34800Sstevel@tonic-gate 
34810Sstevel@tonic-gate 
34820Sstevel@tonic-gate static int
34830Sstevel@tonic-gate genent_bootparams(char *line, int (*cback)())
34840Sstevel@tonic-gate {
34850Sstevel@tonic-gate 	char buf[BUFSIZ+1];
34860Sstevel@tonic-gate 	char *t;
34870Sstevel@tonic-gate 	entry_col ecol[2];
34880Sstevel@tonic-gate 	int ctr = 0, retval = 1;
34890Sstevel@tonic-gate 
34900Sstevel@tonic-gate 	struct _ns_bootp data;
34910Sstevel@tonic-gate 	char *parameter;
34920Sstevel@tonic-gate 	int rc = GENENT_OK;
34930Sstevel@tonic-gate 
34940Sstevel@tonic-gate 	/*
34950Sstevel@tonic-gate 	 * don't clobber our argument
34960Sstevel@tonic-gate 	 */
34970Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
3498*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
3499*6842Sth160488 		    PARSE_ERR_MSG_LEN);
35000Sstevel@tonic-gate 		return (GENENT_PARSEERR);
35010Sstevel@tonic-gate 	}
35020Sstevel@tonic-gate 	(void) strcpy(buf, line);
35030Sstevel@tonic-gate 
35040Sstevel@tonic-gate 	/*
35050Sstevel@tonic-gate 	 * clear column data
35060Sstevel@tonic-gate 	 */
35070Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
35080Sstevel@tonic-gate 
35090Sstevel@tonic-gate 
35100Sstevel@tonic-gate 	/*
35110Sstevel@tonic-gate 	 * cname (col 0)
35120Sstevel@tonic-gate 	 */
35130Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
3514*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("no cname"),
3515*6842Sth160488 		    PARSE_ERR_MSG_LEN);
35160Sstevel@tonic-gate 		return (GENENT_PARSEERR);
35170Sstevel@tonic-gate 	}
35180Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
35190Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
35200Sstevel@tonic-gate 
35210Sstevel@tonic-gate 
35220Sstevel@tonic-gate 
35230Sstevel@tonic-gate 	/* build entry */
35240Sstevel@tonic-gate 	data.name = strdup(ecol[0].ec_value.ec_value_val);
35250Sstevel@tonic-gate 
35260Sstevel@tonic-gate 	/*
35270Sstevel@tonic-gate 	 * name (col 1)
35280Sstevel@tonic-gate 	 */
35290Sstevel@tonic-gate 
35300Sstevel@tonic-gate 	data.param = NULL;
35310Sstevel@tonic-gate 
35321831Sdm199847 	while (t = strtok(NULL, " \t"))  {
35330Sstevel@tonic-gate 
35340Sstevel@tonic-gate 		/*
35350Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
35360Sstevel@tonic-gate 		 */
35370Sstevel@tonic-gate 
35380Sstevel@tonic-gate 
35390Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
35400Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
35410Sstevel@tonic-gate 
35420Sstevel@tonic-gate 		ctr++;
35430Sstevel@tonic-gate 		parameter = strdup(ecol[1].ec_value.ec_value_val);
35440Sstevel@tonic-gate 		if ((data.param = (char **)realloc(data.param,
3545*6842Sth160488 		    (ctr + 1) * sizeof (char **))) == NULL) {
35460Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
35470Sstevel@tonic-gate 			exit(1);
35480Sstevel@tonic-gate 		}
35490Sstevel@tonic-gate 		data.param[ctr-1] = parameter;
35500Sstevel@tonic-gate 
35511831Sdm199847 	}
35520Sstevel@tonic-gate 
35530Sstevel@tonic-gate 
35540Sstevel@tonic-gate 	/* End the list of all the aliases by NULL */
35550Sstevel@tonic-gate 	if ((data.param = (char **)realloc(data.param,
3556*6842Sth160488 	    (ctr + 1) * sizeof (char **))) == NULL) {
35570Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
35580Sstevel@tonic-gate 		exit(1);
35590Sstevel@tonic-gate 	}
35600Sstevel@tonic-gate 	data.param[ctr] = NULL;
35610Sstevel@tonic-gate 
35620Sstevel@tonic-gate 	if (flags & F_VERBOSE)
35630Sstevel@tonic-gate 		(void) fprintf(stdout,
35640Sstevel@tonic-gate 		    gettext("Adding entry : %s\n"), data.name);
35650Sstevel@tonic-gate 
35660Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
35670Sstevel@tonic-gate 
35680Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
35690Sstevel@tonic-gate 		if (continue_onerror)
35700Sstevel@tonic-gate 			(void) fprintf(stderr,
3571*6842Sth160488 			    gettext("Entry: %s - already Exists,"
3572*6842Sth160488 			    " skipping it.\n"), data.name);
35730Sstevel@tonic-gate 		else {
35740Sstevel@tonic-gate 			rc = GENENT_CBERR;
35750Sstevel@tonic-gate 			(void) fprintf(stderr,
3576*6842Sth160488 			    gettext("Entry: %s - already Exists\n"),
3577*6842Sth160488 			    data.name);
35780Sstevel@tonic-gate 		}
35790Sstevel@tonic-gate 	} else if (retval)
35800Sstevel@tonic-gate 		rc = GENENT_CBERR;
35810Sstevel@tonic-gate 
35820Sstevel@tonic-gate 	free(data.name);
35830Sstevel@tonic-gate 	free(data.param);
35840Sstevel@tonic-gate 
35850Sstevel@tonic-gate 	return (rc);
35860Sstevel@tonic-gate 
35870Sstevel@tonic-gate }
35880Sstevel@tonic-gate 
3589*6842Sth160488 /*
3590*6842Sth160488  * Count number of tokens in string which has tokens separated by colons.
3591*6842Sth160488  *
3592*6842Sth160488  * NULL or "" - 0 tokens
3593*6842Sth160488  * "foo" - 1 token
3594*6842Sth160488  * "foo:bar" - 2 tokens
3595*6842Sth160488  * ":bar" - 2 tokens, first empty
3596*6842Sth160488  * "::" - 3 tokens, all empty
3597*6842Sth160488  */
3598*6842Sth160488 static int
3599*6842Sth160488 count_tokens(char *string, char delim)
3600*6842Sth160488 {
3601*6842Sth160488 	int i = 0;
3602*6842Sth160488 	char *s = string;
3603*6842Sth160488 
3604*6842Sth160488 	if (string == NULL || *string == '\0')
3605*6842Sth160488 		return (0);
3606*6842Sth160488 
3607*6842Sth160488 	/* Count delimiters */
3608*6842Sth160488 	while ((s = strchr(s, delim)) != NULL && *s != '\0') {
3609*6842Sth160488 		i++;
3610*6842Sth160488 		s++;
3611*6842Sth160488 	}
3612*6842Sth160488 
3613*6842Sth160488 	return (i + 1);
3614*6842Sth160488 }
3615*6842Sth160488 
3616*6842Sth160488 /*
3617*6842Sth160488  * strsep
3618*6842Sth160488  *
3619*6842Sth160488  * The strsep() function locates, in the string referenced by *stringp, the
3620*6842Sth160488  * first occurrence of any character in the string delim (or the terminating
3621*6842Sth160488  * `\0' character) and replaces it with a `\0'.  The location of the next
3622*6842Sth160488  * character after the delimiter character (or NULL, if the end of the
3623*6842Sth160488  * string was reached) is stored in *stringp.  The original value of
3624*6842Sth160488  * *stringp is returned.
3625*6842Sth160488  *
3626*6842Sth160488  * If *stringp is initially NULL, strsep() returns NULL.
3627*6842Sth160488  */
3628*6842Sth160488 static char *
3629*6842Sth160488 strsep(char **stringp, const char *delim)
3630*6842Sth160488 {
3631*6842Sth160488 	char *s;
3632*6842Sth160488 	const char *spanp;
3633*6842Sth160488 	int c, sc;
3634*6842Sth160488 	char *tok;
3635*6842Sth160488 
3636*6842Sth160488 	if ((s = *stringp) == NULL)
3637*6842Sth160488 		return (NULL);
3638*6842Sth160488 
3639*6842Sth160488 	for (tok = s; ; ) {
3640*6842Sth160488 		c = *s++;
3641*6842Sth160488 		spanp = delim;
3642*6842Sth160488 		do {
3643*6842Sth160488 			if ((sc = *spanp++) == c) {
3644*6842Sth160488 				if (c == 0)
3645*6842Sth160488 					s = NULL;
3646*6842Sth160488 				else
3647*6842Sth160488 					s[-1] = 0;
3648*6842Sth160488 				*stringp = s;
3649*6842Sth160488 				return (tok);
3650*6842Sth160488 			}
3651*6842Sth160488 		} while (sc != 0);
3652*6842Sth160488 	}
3653*6842Sth160488 	/* NOTREACHED */
3654*6842Sth160488 }
3655*6842Sth160488 
3656*6842Sth160488 static int
3657*6842Sth160488 genent_project(char *line, int (*cback)())
3658*6842Sth160488 {
3659*6842Sth160488 	char buf[BUFSIZ+1];
3660*6842Sth160488 	char *b = buf;
3661*6842Sth160488 	char *s;
3662*6842Sth160488 	int rc = GENENT_OK, retval;
3663*6842Sth160488 	int index = 0;
3664*6842Sth160488 	struct project data;
3665*6842Sth160488 
3666*6842Sth160488 	(void) memset(&data, 0, sizeof (struct project));
3667*6842Sth160488 
3668*6842Sth160488 	/*
3669*6842Sth160488 	 * don't clobber our argument
3670*6842Sth160488 	 */
3671*6842Sth160488 	if (strlen(line) >= sizeof (buf)) {
3672*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("line too long"),
3673*6842Sth160488 		    PARSE_ERR_MSG_LEN);
3674*6842Sth160488 		return (GENENT_PARSEERR);
3675*6842Sth160488 	}
3676*6842Sth160488 
3677*6842Sth160488 	if (count_tokens(line, ':') != 6) {
3678*6842Sth160488 		(void) strlcpy(parse_err_msg, gettext("Improper format"),
3679*6842Sth160488 		    PARSE_ERR_MSG_LEN);
3680*6842Sth160488 		return (GENENT_PARSEERR);
3681*6842Sth160488 	}
3682*6842Sth160488 
3683*6842Sth160488 	(void) strcpy(buf, line);
3684*6842Sth160488 
3685*6842Sth160488 	s = strsep(&b, ":");
3686*6842Sth160488 	while (s != NULL) {
3687*6842Sth160488 		switch (index) {
3688*6842Sth160488 		/* Project name */
3689*6842Sth160488 		case 0:
3690*6842Sth160488 			if (check_projname(s) != 0) {
3691*6842Sth160488 				(void) strlcpy(parse_err_msg,
3692*6842Sth160488 				    gettext("invalid project name"),
3693*6842Sth160488 				    PARSE_ERR_MSG_LEN);
3694*6842Sth160488 				return (GENENT_PARSEERR);
3695*6842Sth160488 			} else {
3696*6842Sth160488 				data.pj_name = strdup(s);
3697*6842Sth160488 			}
3698*6842Sth160488 			break;
3699*6842Sth160488 
3700*6842Sth160488 		/* Project ID */
3701*6842Sth160488 		case 1:
3702*6842Sth160488 		{
3703*6842Sth160488 			char *endptr = NULL;
3704*6842Sth160488 			int projid = strtoul(s, &endptr, 10);
3705*6842Sth160488 
3706*6842Sth160488 			if (*s == '\0' || strlen(endptr) != 0 || projid < 0 ||
3707*6842Sth160488 			    projid > MAXPROJID) {
3708*6842Sth160488 				(void) strlcpy(parse_err_msg,
3709*6842Sth160488 				    gettext("invalid project id"),
3710*6842Sth160488 				    PARSE_ERR_MSG_LEN);
3711*6842Sth160488 				return (GENENT_PARSEERR);
3712*6842Sth160488 			} else {
3713*6842Sth160488 				data.pj_projid = projid;
3714*6842Sth160488 			}
3715*6842Sth160488 			break;
3716*6842Sth160488 		}
3717*6842Sth160488 
3718*6842Sth160488 		/* Project description */
3719*6842Sth160488 		case 2:
3720*6842Sth160488 			if (*s != '\0')
3721*6842Sth160488 				data.pj_comment = strdup(s);
3722*6842Sth160488 			break;
3723*6842Sth160488 
3724*6842Sth160488 		/* Project users */
3725*6842Sth160488 		case 3:
3726*6842Sth160488 		{
3727*6842Sth160488 			if (*s == '\0')
3728*6842Sth160488 				break;
3729*6842Sth160488 
3730*6842Sth160488 			char *usrlist = strdup(s);
3731*6842Sth160488 			int   i = 0;
3732*6842Sth160488 			int   usr_count = count_tokens(usrlist, ',');
3733*6842Sth160488 			char *u = strsep(&usrlist, ",");
3734*6842Sth160488 
3735*6842Sth160488 			if (usr_count == 0) {
3736*6842Sth160488 				free(usrlist);
3737*6842Sth160488 				break;
3738*6842Sth160488 			}
3739*6842Sth160488 
3740*6842Sth160488 			/* +1 to NULL-terminate the array */
3741*6842Sth160488 			data.pj_users = (char **)calloc(usr_count + 1,
3742*6842Sth160488 			    sizeof (char *));
3743*6842Sth160488 
3744*6842Sth160488 			while (u != NULL) {
3745*6842Sth160488 				data.pj_users[i++] = strdup(u);
3746*6842Sth160488 				u = strsep(&usrlist, ",");
3747*6842Sth160488 			}
3748*6842Sth160488 
3749*6842Sth160488 			free(usrlist);
3750*6842Sth160488 			break;
3751*6842Sth160488 		}
3752*6842Sth160488 
3753*6842Sth160488 		/* Project groups */
3754*6842Sth160488 		case 4:
3755*6842Sth160488 		{
3756*6842Sth160488 			if (*s == '\0')
3757*6842Sth160488 				break;
3758*6842Sth160488 
3759*6842Sth160488 			char *grouplist = strdup(s);
3760*6842Sth160488 			int   i = 0;
3761*6842Sth160488 			int   grp_count = count_tokens(grouplist, ',');
3762*6842Sth160488 			char *g = strsep(&grouplist, ",");
3763*6842Sth160488 
3764*6842Sth160488 			if (grp_count == 0) {
3765*6842Sth160488 				free(grouplist);
3766*6842Sth160488 				break;
3767*6842Sth160488 			}
3768*6842Sth160488 
3769*6842Sth160488 			/* +1 to NULL-terminate the array */
3770*6842Sth160488 			data.pj_groups = (char **)calloc(grp_count + 1,
3771*6842Sth160488 			    sizeof (char *));
3772*6842Sth160488 
3773*6842Sth160488 			while (g != NULL) {
3774*6842Sth160488 				data.pj_groups[i++] = strdup(g);
3775*6842Sth160488 				g = strsep(&grouplist, ",");
3776*6842Sth160488 			}
3777*6842Sth160488 
3778*6842Sth160488 			free(grouplist);
3779*6842Sth160488 			break;
3780*6842Sth160488 		}
3781*6842Sth160488 
3782*6842Sth160488 		/* Attributes */
3783*6842Sth160488 		case 5:
3784*6842Sth160488 			if (*s != '\0')
3785*6842Sth160488 				data.pj_attr = strdup(s);
3786*6842Sth160488 
3787*6842Sth160488 			break;
3788*6842Sth160488 		}
3789*6842Sth160488 
3790*6842Sth160488 		/* Next token */
3791*6842Sth160488 		s = strsep(&b, ":");
3792*6842Sth160488 		index++;
3793*6842Sth160488 	}
3794*6842Sth160488 
3795*6842Sth160488 	if (flags & F_VERBOSE)
3796*6842Sth160488 		(void) fprintf(stdout,
3797*6842Sth160488 		    gettext("Adding entry : %s\n"), data.pj_name);
3798*6842Sth160488 
3799*6842Sth160488 	retval = (*cback)(&data, 0);
3800*6842Sth160488 
3801*6842Sth160488 	if (retval == LDAP_ALREADY_EXISTS) {
3802*6842Sth160488 		if (continue_onerror)
3803*6842Sth160488 			(void) fprintf(stderr,
3804*6842Sth160488 			    gettext("Entry: %s - already Exists,"
3805*6842Sth160488 			    " skipping it.\n"), data.pj_name);
3806*6842Sth160488 		else {
3807*6842Sth160488 			rc = GENENT_CBERR;
3808*6842Sth160488 			(void) fprintf(stderr,
3809*6842Sth160488 			    gettext("Entry: %s - already Exists\n"),
3810*6842Sth160488 			    data.pj_name);
3811*6842Sth160488 		}
3812*6842Sth160488 	} else if (retval)
3813*6842Sth160488 		rc = GENENT_CBERR;
3814*6842Sth160488 
3815*6842Sth160488 	/* Clean up */
3816*6842Sth160488 	free(data.pj_name);
3817*6842Sth160488 	free(data.pj_attr);
3818*6842Sth160488 	if (data.pj_users != NULL) {
3819*6842Sth160488 		for (index = 0; data.pj_users[index] != NULL; index++)
3820*6842Sth160488 			free(data.pj_users[index]);
3821*6842Sth160488 		free(data.pj_users);
3822*6842Sth160488 	}
3823*6842Sth160488 	if (data.pj_groups != NULL) {
3824*6842Sth160488 		for (index = 0; data.pj_groups[index] != NULL; index++)
3825*6842Sth160488 			free(data.pj_groups[index]);
3826*6842Sth160488 		free(data.pj_groups);
3827*6842Sth160488 	}
3828*6842Sth160488 
3829*6842Sth160488 	return (rc);
3830*6842Sth160488 }
3831*6842Sth160488 
3832*6842Sth160488 static void
3833*6842Sth160488 dump_project(ns_ldap_result_t *res)
3834*6842Sth160488 {
3835*6842Sth160488 	char    **value = NULL;
3836*6842Sth160488 	char 	*endptr = NULL;
3837*6842Sth160488 	int 	projid;
3838*6842Sth160488 
3839*6842Sth160488 	if (res == NULL || res->entry == NULL)
3840*6842Sth160488 		return;
3841*6842Sth160488 
3842*6842Sth160488 	/* Sanity checking */
3843*6842Sth160488 	value = __ns_ldap_getAttr(res->entry, "SolarisProjectID");
3844*6842Sth160488 
3845*6842Sth160488 	if (value[0] == NULL)
3846*6842Sth160488 		return;
3847*6842Sth160488 
3848*6842Sth160488 	projid = strtoul(value[0], &endptr, 10);
3849*6842Sth160488 	if (*value[0] == '\0' || strlen(endptr) != 0 || projid < 0 ||
3850*6842Sth160488 	    projid > MAXPROJID)
3851*6842Sth160488 		return;
3852*6842Sth160488 
3853*6842Sth160488 	value = __ns_ldap_getAttr(res->entry, "SolarisProjectName");
3854*6842Sth160488 	if (value && value[0] && check_projname(value[0]) == 0)
3855*6842Sth160488 		(void) fprintf(stdout, "%s:", value[0]);
3856*6842Sth160488 	else
3857*6842Sth160488 		return;
3858*6842Sth160488 
3859*6842Sth160488 	(void) fprintf(stdout, "%d:", projid);
3860*6842Sth160488 
3861*6842Sth160488 	value = __ns_ldap_getAttr(res->entry, "description");
3862*6842Sth160488 	if (value && value[0])
3863*6842Sth160488 		(void) fprintf(stdout, "%s:", value[0]);
3864*6842Sth160488 	else
3865*6842Sth160488 		(void) fprintf(stdout, ":");
3866*6842Sth160488 
3867*6842Sth160488 	value = __ns_ldap_getAttr(res->entry, "memberUid");
3868*6842Sth160488 	if (value) {
3869*6842Sth160488 		int i;
3870*6842Sth160488 		for (i = 0; value[i] != NULL; i++)
3871*6842Sth160488 			if (value[i+1] != NULL)
3872*6842Sth160488 				(void) fprintf(stdout, "%s,", value[i]);
3873*6842Sth160488 			else
3874*6842Sth160488 				(void) fprintf(stdout, "%s:", value[i]);
3875*6842Sth160488 	} else {
3876*6842Sth160488 		(void) fprintf(stdout, ":");
3877*6842Sth160488 	}
3878*6842Sth160488 
3879*6842Sth160488 	value = __ns_ldap_getAttr(res->entry, "memberGid");
3880*6842Sth160488 	if (value) {
3881*6842Sth160488 		int i;
3882*6842Sth160488 		for (i = 0; value[i] != NULL; i++)
3883*6842Sth160488 			if (value[i+1] != NULL)
3884*6842Sth160488 				(void) fprintf(stdout, "%s,", value[i]);
3885*6842Sth160488 			else
3886*6842Sth160488 				(void) fprintf(stdout, "%s:", value[i]);
3887*6842Sth160488 	} else {
3888*6842Sth160488 		(void) fprintf(stdout, ":");
3889*6842Sth160488 	}
3890*6842Sth160488 
3891*6842Sth160488 	value = __ns_ldap_getAttr(res->entry, "SolarisProjectAttr");
3892*6842Sth160488 	if (value && value[0])
3893*6842Sth160488 		(void) fprintf(stdout, "%s\n", value[0]);
3894*6842Sth160488 	else
3895*6842Sth160488 		(void) fprintf(stdout, "\n");
3896*6842Sth160488 
3897*6842Sth160488 }
38980Sstevel@tonic-gate 
38990Sstevel@tonic-gate static void
39000Sstevel@tonic-gate dump_bootparams(ns_ldap_result_t *res)
39010Sstevel@tonic-gate {
39020Sstevel@tonic-gate 	char	**value = NULL;
39030Sstevel@tonic-gate 	int		attr_count = 0;
39040Sstevel@tonic-gate 
39050Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "cn");
39060Sstevel@tonic-gate 	if (value[0] != NULL)
39070Sstevel@tonic-gate 		(void) fprintf(stdout, "%s", value[0]);
39080Sstevel@tonic-gate 	value = __ns_ldap_getAttr(res->entry, "bootParameter");
39090Sstevel@tonic-gate 	if (value != NULL)
39100Sstevel@tonic-gate 		while (value[attr_count] != NULL) {
39110Sstevel@tonic-gate 		(void) fprintf(stdout, "\t%s", value[attr_count]);
39120Sstevel@tonic-gate 			attr_count++;
39130Sstevel@tonic-gate 		}
39140Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
39150Sstevel@tonic-gate 
39160Sstevel@tonic-gate 
39170Sstevel@tonic-gate }
39180Sstevel@tonic-gate 
39190Sstevel@tonic-gate static char *
39200Sstevel@tonic-gate fget_line_at(struct line_buf *line, int n, FILE *fp)
39210Sstevel@tonic-gate {
39220Sstevel@tonic-gate 	int c;
39230Sstevel@tonic-gate 
39240Sstevel@tonic-gate 	line->len = n;
39250Sstevel@tonic-gate 
39260Sstevel@tonic-gate 	for (;;) {
39270Sstevel@tonic-gate 		c = fgetc(fp);
39280Sstevel@tonic-gate 		if (c == -1)
39290Sstevel@tonic-gate 			break;
39300Sstevel@tonic-gate 		if (line->len >= line->alloc)
39310Sstevel@tonic-gate 			line_buf_expand(line);
39320Sstevel@tonic-gate 		line->str[line->len++] = c;
39330Sstevel@tonic-gate 
39340Sstevel@tonic-gate 		if (c == '\n')
39350Sstevel@tonic-gate 			break;
39360Sstevel@tonic-gate 	}
39370Sstevel@tonic-gate 
39380Sstevel@tonic-gate 	/* Null Terminate */
39390Sstevel@tonic-gate 	if (line->len >= line->alloc)
39400Sstevel@tonic-gate 		line_buf_expand(line);
39410Sstevel@tonic-gate 	line->str[line->len++] = 0;
39420Sstevel@tonic-gate 
39430Sstevel@tonic-gate 	/* if no characters are read, return NULL to indicate EOF */
39440Sstevel@tonic-gate 	if (line->str[0] == '\0')
39450Sstevel@tonic-gate 		return (0);
39460Sstevel@tonic-gate 
39470Sstevel@tonic-gate 	return (line->str);
39480Sstevel@tonic-gate }
39490Sstevel@tonic-gate 
39500Sstevel@tonic-gate /*
39510Sstevel@tonic-gate  * return a line from the file, discarding comments and blank lines
39520Sstevel@tonic-gate  */
39530Sstevel@tonic-gate static int
39540Sstevel@tonic-gate filedbmline_comment(struct line_buf *line, FILE *etcf, int *lineno,
39550Sstevel@tonic-gate     struct file_loc *loc)
39560Sstevel@tonic-gate {
39570Sstevel@tonic-gate 	int i, len = 0;
39580Sstevel@tonic-gate 
39590Sstevel@tonic-gate 	loc->offset = ftell(etcf);
39600Sstevel@tonic-gate 	for (;;) {
39610Sstevel@tonic-gate 		if (fget_line_at(line, len, etcf) == 0)
39620Sstevel@tonic-gate 			return (0);
39630Sstevel@tonic-gate 
39640Sstevel@tonic-gate 		if (lineno)
39650Sstevel@tonic-gate 			(*lineno)++;
39660Sstevel@tonic-gate 
39670Sstevel@tonic-gate 		len = strlen(line->str);
39680Sstevel@tonic-gate 		if (len >= 2 &&
39690Sstevel@tonic-gate 		    line->str[0] != '#' &&
39700Sstevel@tonic-gate 		    line->str[len-2] == '\\' && line->str[len-1] == '\n') {
39710Sstevel@tonic-gate 			line->str[len-2] = 0;
39720Sstevel@tonic-gate 			len -= 2;
39730Sstevel@tonic-gate 			continue;    /* append next line at end */
39740Sstevel@tonic-gate 		}
39750Sstevel@tonic-gate 
39760Sstevel@tonic-gate 		if (line->str[len-1] == '\n') {
39770Sstevel@tonic-gate 			line->str[len-1] = 0;
39780Sstevel@tonic-gate 			len -= 1;
39790Sstevel@tonic-gate 		}
39800Sstevel@tonic-gate 
39810Sstevel@tonic-gate 		/*
39820Sstevel@tonic-gate 		 * Skip lines where '#' is the first non-blank character.
39830Sstevel@tonic-gate 		 */
39840Sstevel@tonic-gate 		for (i = 0; i < len; i++) {
39850Sstevel@tonic-gate 			if (line->str[i] == '#') {
39860Sstevel@tonic-gate 				line->str[i] = '\0';
39870Sstevel@tonic-gate 				len = i;
39880Sstevel@tonic-gate 				break;
39890Sstevel@tonic-gate 			}
39900Sstevel@tonic-gate 			if (line->str[i] != ' ' && line->str[i] != '\t')
39910Sstevel@tonic-gate 				break;
39920Sstevel@tonic-gate 		}
39930Sstevel@tonic-gate 
39940Sstevel@tonic-gate 		/*
39950Sstevel@tonic-gate 		 * A line with one or more white space characters followed
39960Sstevel@tonic-gate 		 * by a comment will now be blank. The special case of a
39970Sstevel@tonic-gate 		 * line with '#' in the first byte will have len == 0.
39980Sstevel@tonic-gate 		 */
39990Sstevel@tonic-gate 		if (len > 0 && !blankline(line->str))
40000Sstevel@tonic-gate 			break;
40010Sstevel@tonic-gate 
40020Sstevel@tonic-gate 		len = 0;
40030Sstevel@tonic-gate 		loc->offset = ftell(etcf);
40040Sstevel@tonic-gate 	}
40050Sstevel@tonic-gate 
40060Sstevel@tonic-gate 	loc->size = len;
40070Sstevel@tonic-gate 	return (1);
40080Sstevel@tonic-gate }
40090Sstevel@tonic-gate 
40100Sstevel@tonic-gate /*
40110Sstevel@tonic-gate  * return a line from the file, discarding comments, blanks, and '+' lines
40120Sstevel@tonic-gate  */
40130Sstevel@tonic-gate static int
40140Sstevel@tonic-gate filedbmline_plus(struct line_buf *line, FILE *etcf, int *lineno,
40150Sstevel@tonic-gate     struct file_loc *loc)
40160Sstevel@tonic-gate {
40170Sstevel@tonic-gate 	int len = 0;
40180Sstevel@tonic-gate 
40190Sstevel@tonic-gate 	loc->offset = ftell(etcf);
40200Sstevel@tonic-gate 	for (;;) {
40210Sstevel@tonic-gate 		if (fget_line_at(line, len, etcf) == 0)
40220Sstevel@tonic-gate 			return (0);
40230Sstevel@tonic-gate 
40240Sstevel@tonic-gate 		if (lineno)
40250Sstevel@tonic-gate 			(*lineno)++;
40260Sstevel@tonic-gate 
40270Sstevel@tonic-gate 		len = strlen(line->str);
40280Sstevel@tonic-gate 		if (line->str[len-1] == '\n') {
40290Sstevel@tonic-gate 			line->str[len-1] = 0;
40300Sstevel@tonic-gate 			len -= 1;
40310Sstevel@tonic-gate 		}
40320Sstevel@tonic-gate 
40330Sstevel@tonic-gate 		if (!blankline(line->str) &&
4034*6842Sth160488 		    line->str[0] != '+' && line->str[0] != '-' &&
4035*6842Sth160488 		    line->str[0] != '#')
40360Sstevel@tonic-gate 			break;
40370Sstevel@tonic-gate 
40380Sstevel@tonic-gate 		len = 0;
40390Sstevel@tonic-gate 		loc->offset = ftell(etcf);
40400Sstevel@tonic-gate 	}
40410Sstevel@tonic-gate 
40420Sstevel@tonic-gate 	loc->size = len;
40430Sstevel@tonic-gate 	return (1);
40440Sstevel@tonic-gate }
40450Sstevel@tonic-gate 
40460Sstevel@tonic-gate 
40470Sstevel@tonic-gate /* Populating the ttypelist structure */
40480Sstevel@tonic-gate 
40490Sstevel@tonic-gate static struct ttypelist_t ttypelist[] = {
40500Sstevel@tonic-gate 	{ NS_LDAP_TYPE_HOSTS, genent_hosts, dump_hosts,
40510Sstevel@tonic-gate 		filedbmline_comment, "iphost" },
40520Sstevel@tonic-gate 	{ NS_LDAP_TYPE_IPNODES, genent_hosts, dump_hosts,
40530Sstevel@tonic-gate 		filedbmline_comment, "iphost" },
40540Sstevel@tonic-gate 	{ NS_LDAP_TYPE_RPC, genent_rpc, dump_rpc,
40550Sstevel@tonic-gate 		filedbmline_comment, "oncrpc" },
40560Sstevel@tonic-gate 	{ NS_LDAP_TYPE_PROTOCOLS, genent_protocols, dump_protocols,
40570Sstevel@tonic-gate 		filedbmline_comment, "ipprotocol" },
40580Sstevel@tonic-gate 	{ NS_LDAP_TYPE_NETWORKS, genent_networks, dump_networks,
40590Sstevel@tonic-gate 		filedbmline_comment, "ipnetwork"  },
40600Sstevel@tonic-gate 	{ NS_LDAP_TYPE_SERVICES, genent_services, dump_services,
40610Sstevel@tonic-gate 		filedbmline_comment, "ipservice" },
40620Sstevel@tonic-gate 	{ NS_LDAP_TYPE_GROUP, genent_group, dump_group,
40630Sstevel@tonic-gate 		filedbmline_plus, "posixgroup" },
40640Sstevel@tonic-gate 	{ NS_LDAP_TYPE_NETMASKS, genent_netmasks, dump_netmasks,
40650Sstevel@tonic-gate 		filedbmline_comment, "ipnetwork" },
40660Sstevel@tonic-gate 	{ NS_LDAP_TYPE_ETHERS, genent_ethers, dump_ethers,
40670Sstevel@tonic-gate 		filedbmline_comment, "ieee802Device" },
40680Sstevel@tonic-gate 	{ NS_LDAP_TYPE_NETGROUP, genent_netgroup, dump_netgroup,
40690Sstevel@tonic-gate 		filedbmline_comment, "nisnetgroup" },
40700Sstevel@tonic-gate 	{ NS_LDAP_TYPE_BOOTPARAMS, genent_bootparams, dump_bootparams,
40710Sstevel@tonic-gate 		filedbmline_comment, "bootableDevice" },
40720Sstevel@tonic-gate 	{ NS_LDAP_TYPE_PUBLICKEY, genent_publickey, NULL /* dump_publickey */,
40730Sstevel@tonic-gate 		filedbmline_comment, "niskeyobject" },
40740Sstevel@tonic-gate 	{ NS_LDAP_TYPE_PASSWD, genent_passwd, dump_passwd,
40750Sstevel@tonic-gate 		filedbmline_plus, "posixaccount" },
40760Sstevel@tonic-gate 	{ NS_LDAP_TYPE_SHADOW, genent_shadow, dump_shadow,
40770Sstevel@tonic-gate 		filedbmline_plus, "shadowaccount" },
40780Sstevel@tonic-gate 	{ NS_LDAP_TYPE_ALIASES, genent_aliases, dump_aliases,
40790Sstevel@tonic-gate 		filedbmline_plus, "mailGroup" },
40800Sstevel@tonic-gate 	{ NS_LDAP_TYPE_AUTOMOUNT, genent_automount, dump_automount,
40810Sstevel@tonic-gate 		filedbmline_comment, "automount" },
40820Sstevel@tonic-gate 	{ NS_LDAP_TYPE_USERATTR, genent_user_attr, dump_user_attr,
40830Sstevel@tonic-gate 		filedbmline_comment, "SolarisUserAttr" },
40840Sstevel@tonic-gate 	{ NS_LDAP_TYPE_PROFILE, genent_prof_attr, dump_prof_attr,
40850Sstevel@tonic-gate 		filedbmline_comment, "SolarisProfAttr" },
40860Sstevel@tonic-gate 	{ NS_LDAP_TYPE_EXECATTR, genent_exec_attr, dump_exec_attr,
40870Sstevel@tonic-gate 		filedbmline_comment, "SolarisExecAttr" },
40880Sstevel@tonic-gate 	{ NS_LDAP_TYPE_AUTHATTR, genent_auth_attr, dump_auth_attr,
40890Sstevel@tonic-gate 		filedbmline_comment, "SolarisAuthAttr" },
40900Sstevel@tonic-gate 	{ NS_LDAP_TYPE_AUUSER, genent_audit_user, dump_audit_user,
40910Sstevel@tonic-gate 		filedbmline_comment, "SolarisAuditUser" },
40921676Sjpk 	{ NS_LDAP_TYPE_TNRHDB, genent_tnrhdb, dump_tnrhdb,
40931676Sjpk 		filedbmline_comment, "ipTnetHost" },
40941676Sjpk 	{ NS_LDAP_TYPE_TNRHTP, genent_tnrhtp, dump_tnrhtp,
40951676Sjpk 		filedbmline_comment, "ipTnetTemplate" },
4096*6842Sth160488 	{ NS_LDAP_TYPE_PROJECT, genent_project, dump_project,
4097*6842Sth160488 		filedbmline_comment, "SolarisProject" },
40980Sstevel@tonic-gate 	{ 0, 0, 0, 0, 0 }
40990Sstevel@tonic-gate };
41000Sstevel@tonic-gate 
41010Sstevel@tonic-gate 
41020Sstevel@tonic-gate 
41030Sstevel@tonic-gate 
41040Sstevel@tonic-gate static int lineno = 0;
41050Sstevel@tonic-gate 
41060Sstevel@tonic-gate static	void
41070Sstevel@tonic-gate addfile()
41080Sstevel@tonic-gate {
41090Sstevel@tonic-gate 	struct line_buf line;
41100Sstevel@tonic-gate 	struct file_loc loc;
41110Sstevel@tonic-gate 
41120Sstevel@tonic-gate 	/* Initializing the Line Buffer */
41130Sstevel@tonic-gate 	line_buf_init(&line);
41140Sstevel@tonic-gate 
41150Sstevel@tonic-gate 	/* Loop through all the lines in the file */
41160Sstevel@tonic-gate 	while (tt->filedbmline(&line, etcf, &lineno, &loc)) {
41170Sstevel@tonic-gate 		switch ((*(tt->genent))(line.str, addentry)) {
41180Sstevel@tonic-gate 		case GENENT_OK:
41190Sstevel@tonic-gate 			break;
41200Sstevel@tonic-gate 		case GENENT_PARSEERR:
41210Sstevel@tonic-gate 			(void) fprintf(stderr,
41220Sstevel@tonic-gate 			    gettext("parse error: %s (line %d)\n"),
41230Sstevel@tonic-gate 			    parse_err_msg, lineno);
41240Sstevel@tonic-gate 			exit_val = 1;
41250Sstevel@tonic-gate 			break;
41260Sstevel@tonic-gate 		case GENENT_CBERR:
41270Sstevel@tonic-gate 			(void) fprintf(stderr,
41280Sstevel@tonic-gate 			    gettext("Error while adding line: %s\n"),
41290Sstevel@tonic-gate 			    line.str);
41300Sstevel@tonic-gate 			exit_val = 2;
41310Sstevel@tonic-gate 			free(line.str);
41320Sstevel@tonic-gate 			return;
41330Sstevel@tonic-gate 			break;
41340Sstevel@tonic-gate 		case GENENT_ERR:
41350Sstevel@tonic-gate 			(void) fprintf(stderr,
41360Sstevel@tonic-gate 			    gettext("Internal Error while adding line: %s\n"),
41370Sstevel@tonic-gate 			    line.str);
41380Sstevel@tonic-gate 			exit_val = 3;
41390Sstevel@tonic-gate 			free(line.str);
41400Sstevel@tonic-gate 			return;
41410Sstevel@tonic-gate 			break;
41420Sstevel@tonic-gate 		}
41430Sstevel@tonic-gate 	}
41440Sstevel@tonic-gate 	free(line.str);
41450Sstevel@tonic-gate }
41460Sstevel@tonic-gate 
41470Sstevel@tonic-gate static void
41480Sstevel@tonic-gate dumptable(char *service)
41490Sstevel@tonic-gate {
41500Sstevel@tonic-gate 
41510Sstevel@tonic-gate 	ns_ldap_result_t *eres = NULL;
41520Sstevel@tonic-gate 	ns_ldap_error_t *err = NULL;
41530Sstevel@tonic-gate 	int	rc = 0, success = 0;
41540Sstevel@tonic-gate 	char	filter[BUFSIZ];
41550Sstevel@tonic-gate 	int	done = 0;
41560Sstevel@tonic-gate 	void	*cookie = NULL;
41570Sstevel@tonic-gate 
41580Sstevel@tonic-gate 	/* set the appropriate filter */
41590Sstevel@tonic-gate 	if (strcmp(tt->ttype, NS_LDAP_TYPE_PROFILE) == 0) {
41600Sstevel@tonic-gate 		/*
41610Sstevel@tonic-gate 		 * prof_attr entries are SolarisProfAttr
41620Sstevel@tonic-gate 		 * without AUXILIARY SolarisExecAttr
41630Sstevel@tonic-gate 		 */
41640Sstevel@tonic-gate 		(void) snprintf(filter, sizeof (filter),
41650Sstevel@tonic-gate 		    "(&(objectclass=%s)(!(objectclass=SolarisExecAttr)))",
41660Sstevel@tonic-gate 		    tt->objclass);
41671676Sjpk 	} else if (strcmp(tt->ttype, NS_LDAP_TYPE_TNRHDB) == 0) {
41681676Sjpk 		/*
41691676Sjpk 		 * tnrhtp entries are ipTnet entries with SolarisAttrKeyValue
41701676Sjpk 		 */
41711676Sjpk 		(void) snprintf(filter, sizeof (filter),
41721676Sjpk 		    "(&(objectclass=%s)(SolarisAttrKeyValue=*)))",
41731676Sjpk 		    tt->objclass);
41741676Sjpk 	} else {
41750Sstevel@tonic-gate 		(void) snprintf(filter, sizeof (filter),
41760Sstevel@tonic-gate 		    "(objectclass=%s)", tt->objclass);
41771676Sjpk 	}
41780Sstevel@tonic-gate 
41790Sstevel@tonic-gate 	if (flags & F_VERBOSE)
41800Sstevel@tonic-gate 		(void) fprintf(stdout, gettext("FILTER = %s\n"), filter);
41810Sstevel@tonic-gate 
41820Sstevel@tonic-gate 	/* Pass cred only if supplied. Cred is not always needed for dump */
41830Sstevel@tonic-gate 	if (authority.cred.unix_cred.userID == NULL ||
41840Sstevel@tonic-gate 	    authority.cred.unix_cred.passwd == NULL)
41850Sstevel@tonic-gate 		rc = __ns_ldap_firstEntry(service, filter, NULL, NULL,
41860Sstevel@tonic-gate 		    NULL, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
41870Sstevel@tonic-gate 	else
41880Sstevel@tonic-gate 		rc = __ns_ldap_firstEntry(service, filter, NULL, NULL,
41890Sstevel@tonic-gate 		    &authority, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
41900Sstevel@tonic-gate 
41910Sstevel@tonic-gate 	switch (rc) {
41920Sstevel@tonic-gate 	case NS_LDAP_SUCCESS:
41930Sstevel@tonic-gate 		nent_add++;
41940Sstevel@tonic-gate 		success = 1;
41950Sstevel@tonic-gate 		if (eres != NULL) {
41960Sstevel@tonic-gate 			if (strcmp(databasetype, "publickey") == 0)
41970Sstevel@tonic-gate 				dump_publickey(eres, service);
41980Sstevel@tonic-gate 			else
41990Sstevel@tonic-gate 				(*(tt->dump))(eres);
42000Sstevel@tonic-gate 		}
42010Sstevel@tonic-gate 		else
42020Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("No entries found.\n"));
42030Sstevel@tonic-gate 		break;
42040Sstevel@tonic-gate 
42050Sstevel@tonic-gate 	case NS_LDAP_OP_FAILED:
42060Sstevel@tonic-gate 		exit_val = 2;
42070Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("operation failed.\n"));
42080Sstevel@tonic-gate 		break;
42090Sstevel@tonic-gate 
42100Sstevel@tonic-gate 	case NS_LDAP_INVALID_PARAM:
42110Sstevel@tonic-gate 		exit_val = 2;
42120Sstevel@tonic-gate 		(void) fprintf(stderr,
42130Sstevel@tonic-gate 		    gettext("invalid parameter(s) passed.\n"));
42140Sstevel@tonic-gate 		break;
42150Sstevel@tonic-gate 
42160Sstevel@tonic-gate 	case NS_LDAP_NOTFOUND:
42170Sstevel@tonic-gate 		exit_val = 2;
42180Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("entry not found.\n"));
42190Sstevel@tonic-gate 		break;
42200Sstevel@tonic-gate 
42210Sstevel@tonic-gate 	case NS_LDAP_MEMORY:
42220Sstevel@tonic-gate 		exit_val = 2;
42230Sstevel@tonic-gate 		(void) fprintf(stderr,
4224*6842Sth160488 		    gettext("internal memory allocation error.\n"));
42250Sstevel@tonic-gate 		break;
42260Sstevel@tonic-gate 
42270Sstevel@tonic-gate 	case NS_LDAP_CONFIG:
42280Sstevel@tonic-gate 		exit_val = 2;
42290Sstevel@tonic-gate 		(void) fprintf(stderr,
4230*6842Sth160488 		    gettext("LDAP Configuration problem.\n"));
42310Sstevel@tonic-gate 		perr(err);
42320Sstevel@tonic-gate 		break;
42330Sstevel@tonic-gate 
42340Sstevel@tonic-gate 	case NS_LDAP_PARTIAL:
42350Sstevel@tonic-gate 		exit_val = 2;
42360Sstevel@tonic-gate 		(void) fprintf(stderr,
4237*6842Sth160488 		    gettext("partial result returned\n"));
42380Sstevel@tonic-gate 		perr(err);
42390Sstevel@tonic-gate 		break;
42400Sstevel@tonic-gate 
42410Sstevel@tonic-gate 	case NS_LDAP_INTERNAL:
42420Sstevel@tonic-gate 		exit_val = 2;
42430Sstevel@tonic-gate 		(void) fprintf(stderr,
4244*6842Sth160488 		    gettext("internal LDAP error occured.\n"));
42450Sstevel@tonic-gate 		perr(err);
42460Sstevel@tonic-gate 		break;
42470Sstevel@tonic-gate 	}
42480Sstevel@tonic-gate 
42490Sstevel@tonic-gate 	if (eres != NULL) {
42500Sstevel@tonic-gate 		(void) __ns_ldap_freeResult(&eres);
42510Sstevel@tonic-gate 		eres = NULL;
42520Sstevel@tonic-gate 	}
42530Sstevel@tonic-gate 
42540Sstevel@tonic-gate 	if (success) {
42550Sstevel@tonic-gate 		while (!done) {
42560Sstevel@tonic-gate 			rc = __ns_ldap_nextEntry(cookie, &eres, &err);
42570Sstevel@tonic-gate 			if (rc != NS_LDAP_SUCCESS || eres  == NULL) {
42580Sstevel@tonic-gate 				done = 1;
42590Sstevel@tonic-gate 				continue;
42600Sstevel@tonic-gate 			}
42610Sstevel@tonic-gate 
42620Sstevel@tonic-gate 			/* Print the result */
42630Sstevel@tonic-gate 			if (eres != NULL) {
42640Sstevel@tonic-gate 				if (strcmp(databasetype, "publickey") == 0)
42650Sstevel@tonic-gate 					dump_publickey(eres, service);
42660Sstevel@tonic-gate 				else
42670Sstevel@tonic-gate 					(*(tt->dump))(eres);
42680Sstevel@tonic-gate 				(void) __ns_ldap_freeResult(&eres);
42690Sstevel@tonic-gate 				eres = NULL;
42700Sstevel@tonic-gate 			}
42710Sstevel@tonic-gate 		}
42720Sstevel@tonic-gate 	}
42730Sstevel@tonic-gate }
42740Sstevel@tonic-gate 
4275702Sth160488 int
42760Sstevel@tonic-gate main(int argc, char **argv)
42770Sstevel@tonic-gate {
4278*6842Sth160488 	char			*password;
4279*6842Sth160488 	ns_standalone_conf_t	standalone_cfg = standaloneDefaults;
4280*6842Sth160488 	int			c;
4281*6842Sth160488 	int			rc;
4282*6842Sth160488 	int			ldaprc;
4283*6842Sth160488 	int			authstried = 0;
4284*6842Sth160488 	int			op = OP_ADD;
4285*6842Sth160488 	char			*ttype, *authmech = 0, *etcfile = 0;
4286*6842Sth160488 	/* Temporary password variable */
4287*6842Sth160488 	char			ps[LDAP_MAXNAMELEN];
4288*6842Sth160488 	char			filter[BUFSIZ];
4289*6842Sth160488 	void			**paramVal = NULL;
4290*6842Sth160488 	ns_auth_t		**app;
4291*6842Sth160488 	ns_auth_t		**authpp = NULL;
4292*6842Sth160488 	ns_auth_t		*authp = NULL;
4293*6842Sth160488 	ns_ldap_error_t		*errorp = NULL;
4294*6842Sth160488 	ns_ldap_result_t	*resultp;
4295*6842Sth160488 	ns_ldap_entry_t		*e;
4296*6842Sth160488 	int			flag = 0;
4297*6842Sth160488 	int			version1 = 0;
42980Sstevel@tonic-gate 
42990Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
43000Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
43010Sstevel@tonic-gate 
43020Sstevel@tonic-gate 	openlog("ldapaddent", LOG_PID, LOG_USER);
43030Sstevel@tonic-gate 
43040Sstevel@tonic-gate 	inputbasedn = NULL;
43050Sstevel@tonic-gate 	authority.cred.unix_cred.passwd = NULL;
43060Sstevel@tonic-gate 	authority.cred.unix_cred.userID = NULL;
43070Sstevel@tonic-gate 	authority.auth.type = NS_LDAP_AUTH_SIMPLE;
43080Sstevel@tonic-gate 
4309*6842Sth160488 	while ((c = getopt(argc, argv, "cdh:N:M:vpf:D:w:j:b:a:P:r:")) != EOF) {
43100Sstevel@tonic-gate 		switch (c) {
43110Sstevel@tonic-gate 		case 'd':
43120Sstevel@tonic-gate 			if (op)
4313*6842Sth160488 				usage(gettext(
4314*6842Sth160488 				    "no other option should be specified"));
43150Sstevel@tonic-gate 			op = OP_DUMP;
43160Sstevel@tonic-gate 			break;
43170Sstevel@tonic-gate 		case 'c':
43180Sstevel@tonic-gate 			continue_onerror = 1;
43190Sstevel@tonic-gate 			break;
43200Sstevel@tonic-gate 		case 'v':
43210Sstevel@tonic-gate 			flags |= F_VERBOSE;
43220Sstevel@tonic-gate 			break;
43230Sstevel@tonic-gate 		case 'p':
43240Sstevel@tonic-gate 			flags |= F_PASSWD;
43250Sstevel@tonic-gate 			break;
4326*6842Sth160488 		case 'M':
4327*6842Sth160488 			standalone_cfg.type = NS_LDAP_SERVER;
4328*6842Sth160488 			standalone_cfg.SA_DOMAIN = optarg;
4329*6842Sth160488 			break;
4330*6842Sth160488 		case 'h':
4331*6842Sth160488 			standalone_cfg.type = NS_LDAP_SERVER;
4332*6842Sth160488 			if (separatePort(optarg,
4333*6842Sth160488 			    &standalone_cfg.SA_SERVER,
4334*6842Sth160488 			    &standalone_cfg.SA_PORT) > 0) {
4335*6842Sth160488 				exit(1);
4336*6842Sth160488 			}
4337*6842Sth160488 			break;
4338*6842Sth160488 		case 'P':
4339*6842Sth160488 			standalone_cfg.type = NS_LDAP_SERVER;
4340*6842Sth160488 			authority.hostcertpath = optarg;
4341*6842Sth160488 			break;
4342*6842Sth160488 		case 'N':
4343*6842Sth160488 			standalone_cfg.type = NS_LDAP_SERVER;
4344*6842Sth160488 			standalone_cfg.SA_PROFILE_NAME = optarg;
4345*6842Sth160488 			break;
43460Sstevel@tonic-gate 		case 'f':
43470Sstevel@tonic-gate 			etcfile = optarg;
43480Sstevel@tonic-gate 			break;
43490Sstevel@tonic-gate 		case 'D':
43500Sstevel@tonic-gate 			authority.cred.unix_cred.userID = strdup(optarg);
43510Sstevel@tonic-gate 			break;
43520Sstevel@tonic-gate 		case 'w':
4353*6842Sth160488 			if (authority.cred.unix_cred.passwd) {
4354*6842Sth160488 				(void) fprintf(stderr,
4355*6842Sth160488 				    gettext("Warning: The -w option is mutually"
4356*6842Sth160488 				    " exclusive of -j. -w is ignored.\n"));
4357*6842Sth160488 				break;
4358*6842Sth160488 			}
4359*6842Sth160488 
4360*6842Sth160488 			if (optarg != NULL &&
4361*6842Sth160488 			    optarg[0] == '-' && optarg[1] == '\0') {
4362*6842Sth160488 				/* Ask for a password later */
4363*6842Sth160488 				break;
4364*6842Sth160488 			}
4365*6842Sth160488 
43660Sstevel@tonic-gate 			authority.cred.unix_cred.passwd = strdup(optarg);
43670Sstevel@tonic-gate 			break;
4368*6842Sth160488 		case 'j':
4369*6842Sth160488 			if (authority.cred.unix_cred.passwd != NULL) {
4370*6842Sth160488 				(void) fprintf(stderr,
4371*6842Sth160488 				    gettext("The -w option is mutually "
4372*6842Sth160488 				    "exclusive of -j. -w is ignored.\n"));
4373*6842Sth160488 				free(authority.cred.unix_cred.passwd);
4374*6842Sth160488 			}
4375*6842Sth160488 			authority.cred.unix_cred.passwd = readPwd(optarg);
4376*6842Sth160488 			if (authority.cred.unix_cred.passwd == NULL) {
4377*6842Sth160488 				exit(1);
4378*6842Sth160488 			}
4379*6842Sth160488 			break;
43800Sstevel@tonic-gate 		case 'b':
43810Sstevel@tonic-gate 			inputbasedn = strdup(optarg);
43820Sstevel@tonic-gate 			break;
43830Sstevel@tonic-gate 		case 'a':
43840Sstevel@tonic-gate 			authmech = strdup(optarg);
43850Sstevel@tonic-gate 			break;
43860Sstevel@tonic-gate 		default:
43870Sstevel@tonic-gate 			usage(gettext("Invalid option"));
43880Sstevel@tonic-gate 		}
43890Sstevel@tonic-gate 	}
43900Sstevel@tonic-gate 
4391*6842Sth160488 	if (standalone_cfg.type == NS_LDAP_SERVER &&
4392*6842Sth160488 	    standalone_cfg.SA_SERVER == NULL) {
4393*6842Sth160488 		(void) fprintf(stderr,
4394*6842Sth160488 		    gettext("Please specify an LDAP server you want "
4395*6842Sth160488 		    "to connect to. \n"));
4396*6842Sth160488 		exit(1);
4397*6842Sth160488 	}
4398*6842Sth160488 
4399*6842Sth160488 	if (authmech != NULL) {
4400*6842Sth160488 		if (__ns_ldap_initAuth(authmech, &authority.auth, &errorp) !=
4401*6842Sth160488 		    NS_LDAP_SUCCESS) {
4402*6842Sth160488 			if (errorp) {
4403*6842Sth160488 				(void) fprintf(stderr, "%s", errorp->message);
4404*6842Sth160488 				(void) __ns_ldap_freeError(&errorp);
4405*6842Sth160488 			}
4406*6842Sth160488 			exit(1);
4407*6842Sth160488 		}
4408*6842Sth160488 	}
4409*6842Sth160488 
4410*6842Sth160488 	if (authority.auth.saslmech != NS_LDAP_SASL_GSSAPI &&
4411*6842Sth160488 	    authority.cred.unix_cred.userID == NULL &&
4412*6842Sth160488 	    op != OP_DUMP) {
44130Sstevel@tonic-gate 	    /* This is not an optional parameter. Exit */
44140Sstevel@tonic-gate 		(void) fprintf(stderr,
4415*6842Sth160488 		    gettext("DN must be specified unless SASL/GSSAPI is used."
4416*6842Sth160488 		    " Use option -D.\n"));
44170Sstevel@tonic-gate 		exit(1);
44180Sstevel@tonic-gate 	}
44190Sstevel@tonic-gate 
4420*6842Sth160488 	if (authority.auth.saslmech != NS_LDAP_SASL_GSSAPI &&
4421*6842Sth160488 	    authority.cred.unix_cred.passwd == NULL &&
4422*6842Sth160488 	    (op != OP_DUMP ||
4423*6842Sth160488 	    standalone_cfg.type != NS_CACHEMGR &&
4424*6842Sth160488 	    authority.cred.unix_cred.userID != NULL)) {
44250Sstevel@tonic-gate 		/* If password is not specified, then prompt user for it. */
44260Sstevel@tonic-gate 		password = getpassphrase("Enter password:");
44270Sstevel@tonic-gate 		(void) strcpy(ps, password);
44280Sstevel@tonic-gate 		authority.cred.unix_cred.passwd = strdup(ps);
44290Sstevel@tonic-gate 	}
44300Sstevel@tonic-gate 
4431*6842Sth160488 	standalone_cfg.SA_AUTH = authmech == NULL ? NULL : &authority.auth;
4432*6842Sth160488 	standalone_cfg.SA_CERT_PATH = authority.hostcertpath;
4433*6842Sth160488 	standalone_cfg.SA_BIND_DN = authority.cred.unix_cred.userID;
4434*6842Sth160488 	standalone_cfg.SA_BIND_PWD = authority.cred.unix_cred.passwd;
4435*6842Sth160488 
4436*6842Sth160488 	if (__ns_ldap_initStandalone(&standalone_cfg,
4437*6842Sth160488 	    &errorp) != NS_LDAP_SUCCESS) {
4438*6842Sth160488 		if (errorp) {
4439*6842Sth160488 			(void) fprintf(stderr, "%s", errorp->message);
44402830Sdjl 		}
44412830Sdjl 		exit(1);
44422830Sdjl 	}
44432830Sdjl 
44440Sstevel@tonic-gate 	if (authmech == NULL) {
44450Sstevel@tonic-gate 		ldaprc = __ns_ldap_getParam(NS_LDAP_AUTH_P, (void ***)&authpp,
4446*6842Sth160488 		    &errorp);
44470Sstevel@tonic-gate 		if (ldaprc != NS_LDAP_SUCCESS ||
44480Sstevel@tonic-gate 		    (authpp == NULL && op != OP_DUMP)) {
44490Sstevel@tonic-gate 			(void) fprintf(stderr,
44500Sstevel@tonic-gate 			    gettext("No legal authentication method "
44510Sstevel@tonic-gate 			    "configured.\n"));
44520Sstevel@tonic-gate 			(void) fprintf(stderr,
44530Sstevel@tonic-gate 			    gettext("Provide a legal authentication method "
44540Sstevel@tonic-gate 			    "using -a option\n"));
44550Sstevel@tonic-gate 			exit(1);
44560Sstevel@tonic-gate 		}
44570Sstevel@tonic-gate 
44580Sstevel@tonic-gate 		/* Use the first authentication method which is not none */
44590Sstevel@tonic-gate 		for (app = authpp; *app; app++) {
44600Sstevel@tonic-gate 			authp = *app;
44610Sstevel@tonic-gate 			if (authp->type != NS_LDAP_AUTH_NONE) {
44620Sstevel@tonic-gate 				authstried++;
44630Sstevel@tonic-gate 				authority.auth.type = authp->type;
44640Sstevel@tonic-gate 				authority.auth.tlstype = authp->tlstype;
44650Sstevel@tonic-gate 				authority.auth.saslmech = authp->saslmech;
44660Sstevel@tonic-gate 				authority.auth.saslopt = authp->saslopt;
44670Sstevel@tonic-gate 				break;
44680Sstevel@tonic-gate 			}
44690Sstevel@tonic-gate 		}
44700Sstevel@tonic-gate 		if (authstried == 0 && op != OP_DUMP) {
44710Sstevel@tonic-gate 			(void) fprintf(stderr,
4472*6842Sth160488 			    gettext("No legal authentication method configured."
4473*6842Sth160488 			    "\nProvide a legal authentication method using "
4474*6842Sth160488 			    "-a option"));
44750Sstevel@tonic-gate 			exit(1);
44760Sstevel@tonic-gate 		}
44772830Sdjl 		if (authority.auth.saslmech == NS_LDAP_SASL_GSSAPI &&
4478*6842Sth160488 		    authority.cred.unix_cred.passwd != NULL &&
4479*6842Sth160488 		    authority.cred.unix_cred.userID != NULL) {
44802830Sdjl 			/*
44812830Sdjl 			 * -a is not specified and the auth method sasl/GSSAPI
44822830Sdjl 			 * is defined in the configuration of the ldap profile.
44832830Sdjl 			 * Even -D and -w is provided it's not valid usage.
4484*6842Sth160488 			 * Drop them on the floor.
44852830Sdjl 			 */
44862830Sdjl 
44872830Sdjl 			(void) fprintf(stderr,
4488*6842Sth160488 			    gettext("The default authentication is "
4489*6842Sth160488 			    "sasl/GSSAPI.\n"
4490*6842Sth160488 			    "The bind DN and password will be ignored.\n"));
4491*6842Sth160488 			authority.cred.unix_cred.passwd = NULL;
4492*6842Sth160488 			authority.cred.unix_cred.userID = NULL;
44932830Sdjl 		}
44940Sstevel@tonic-gate 	}
44950Sstevel@tonic-gate 
44960Sstevel@tonic-gate 	ttype = argv[optind++];
44970Sstevel@tonic-gate 
44980Sstevel@tonic-gate 	if (ttype == NULL) {
44990Sstevel@tonic-gate 		usage(gettext("No database type specified"));
45000Sstevel@tonic-gate 		exit(1);
45010Sstevel@tonic-gate 	}
45020Sstevel@tonic-gate 
45030Sstevel@tonic-gate 	if (strncasecmp(ttype, "automount", 9) == 0) {
45040Sstevel@tonic-gate 		(void) fprintf(stderr,
45050Sstevel@tonic-gate 		    gettext("automount is not a valid service for ldapaddent.\n"
45060Sstevel@tonic-gate 		    "Please use auto_*.\n"
45070Sstevel@tonic-gate 		    "e.g.  auto_home, auto_ws etc.\n "));
45080Sstevel@tonic-gate 		exit(1);
45090Sstevel@tonic-gate 	}
45100Sstevel@tonic-gate 
45110Sstevel@tonic-gate 	for (tt = ttypelist; tt->ttype; tt++) {
45120Sstevel@tonic-gate 		if (strcmp(tt->ttype, ttype) == 0)
45130Sstevel@tonic-gate 			break;
45140Sstevel@tonic-gate 		if (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0 &&
45150Sstevel@tonic-gate 		    strncmp(ttype, NS_LDAP_TYPE_AUTOMOUNT,
45160Sstevel@tonic-gate 		    sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0)
45170Sstevel@tonic-gate 			break;
45180Sstevel@tonic-gate 	}
45190Sstevel@tonic-gate 
45200Sstevel@tonic-gate 	if (tt->ttype == 0) {
45210Sstevel@tonic-gate 		(void) fprintf(stderr,
45220Sstevel@tonic-gate 		    gettext("database %s not supported;"
45230Sstevel@tonic-gate 		    " supported databases are:\n"), ttype);
45240Sstevel@tonic-gate 		for (tt = ttypelist; tt->ttype; tt++)
45250Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("\t%s\n"), tt->ttype);
45260Sstevel@tonic-gate 		exit(1);
45270Sstevel@tonic-gate 	}
45280Sstevel@tonic-gate 
45290Sstevel@tonic-gate 	if (flags & F_VERBOSE)
45300Sstevel@tonic-gate 		(void) fprintf(stdout, gettext("SERVICE = %s\n"), tt->ttype);
45310Sstevel@tonic-gate 
45320Sstevel@tonic-gate 	databasetype = ttype;
45330Sstevel@tonic-gate 
45340Sstevel@tonic-gate 	if (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0) {
45350Sstevel@tonic-gate 		paramVal = NULL;
45360Sstevel@tonic-gate 		errorp = NULL;
45370Sstevel@tonic-gate 		rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, &paramVal,
4538*6842Sth160488 		    &errorp);
45390Sstevel@tonic-gate 		if (paramVal && *paramVal &&
4540*6842Sth160488 		    strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0)
45410Sstevel@tonic-gate 			version1 = 1;
45420Sstevel@tonic-gate 		if (paramVal)
45430Sstevel@tonic-gate 			(void) __ns_ldap_freeParam(&paramVal);
45440Sstevel@tonic-gate 		if (errorp)
45450Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&errorp);
45460Sstevel@tonic-gate 	}
45470Sstevel@tonic-gate 
45480Sstevel@tonic-gate 	/* Check if the container exists in first place */
45490Sstevel@tonic-gate 	(void) strcpy(&filter[0], "(objectclass=*)");
45500Sstevel@tonic-gate 
45510Sstevel@tonic-gate 	rc = __ns_ldap_list(databasetype, filter, NULL, (const char **)NULL,
45520Sstevel@tonic-gate 	    NULL, NS_LDAP_SCOPE_BASE, &resultp, &errorp, NULL, NULL);
45530Sstevel@tonic-gate 
45540Sstevel@tonic-gate 	/* create a container for auto_* if it does not exist already */
45550Sstevel@tonic-gate 	if ((rc == NS_LDAP_NOTFOUND) && (op == OP_ADD) &&
45560Sstevel@tonic-gate 	    (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0)) {
45570Sstevel@tonic-gate 		static	char *oclist[] = {NULL, "top", NULL};
45580Sstevel@tonic-gate 		if (version1)
45590Sstevel@tonic-gate 			oclist[0] = "nisMap";
45600Sstevel@tonic-gate 		else
45610Sstevel@tonic-gate 			oclist[0] = "automountMap";
45620Sstevel@tonic-gate 		e = __s_mk_entry(oclist, 3);
45630Sstevel@tonic-gate 		if (e == NULL) {
45640Sstevel@tonic-gate 			(void) fprintf(stderr,
45650Sstevel@tonic-gate 			    gettext("internal memory allocation error.\n"));
45660Sstevel@tonic-gate 			exit(1);
45670Sstevel@tonic-gate 		}
45680Sstevel@tonic-gate 		if (__s_add_attr(e,
45690Sstevel@tonic-gate 		    version1 ? "nisMapName" : "automountMapName",
45700Sstevel@tonic-gate 		    databasetype) != NS_LDAP_SUCCESS) {
45710Sstevel@tonic-gate 			(void) fprintf(stderr,
45720Sstevel@tonic-gate 			    gettext("internal memory allocation error.\n"));
45730Sstevel@tonic-gate 			ldap_freeEntry(e);
45740Sstevel@tonic-gate 			exit(1);
45750Sstevel@tonic-gate 		}
45760Sstevel@tonic-gate 
45770Sstevel@tonic-gate 		if (inputbasedn == NULL) {
45780Sstevel@tonic-gate 			if (get_basedn(databasetype, &inputbasedn) !=
45790Sstevel@tonic-gate 			    NS_LDAP_SUCCESS) {
45800Sstevel@tonic-gate 				(void) fprintf(stderr,
45810Sstevel@tonic-gate 				    gettext("Could not obtain basedn\n"));
45820Sstevel@tonic-gate 				ldap_freeEntry(e);
45830Sstevel@tonic-gate 				exit(1);
45840Sstevel@tonic-gate 			}
45850Sstevel@tonic-gate 		}
45860Sstevel@tonic-gate 		if (__ns_ldap_addEntry(databasetype, inputbasedn, e,
45870Sstevel@tonic-gate 		    &authority, flag, &errorp) != NS_LDAP_SUCCESS) {
45880Sstevel@tonic-gate 			(void) fprintf(stderr,
45890Sstevel@tonic-gate 			    gettext("Could not create container for %s\n"),
45900Sstevel@tonic-gate 			    databasetype);
45910Sstevel@tonic-gate 			ldap_freeEntry(e);
45920Sstevel@tonic-gate 		}
45930Sstevel@tonic-gate 	} else if (strcmp(databasetype, "publickey") != 0) {
45940Sstevel@tonic-gate 		if (rc == NS_LDAP_NOTFOUND) {
45950Sstevel@tonic-gate 			(void) fprintf(stderr,
45960Sstevel@tonic-gate 			    gettext("Container %s does not exist\n"),
45970Sstevel@tonic-gate 			    databasetype);
45980Sstevel@tonic-gate 			exit(1);
45990Sstevel@tonic-gate 		}
46000Sstevel@tonic-gate 	}
46010Sstevel@tonic-gate 
46020Sstevel@tonic-gate 	if (op == OP_DUMP) {
46030Sstevel@tonic-gate 		if (strcmp(databasetype, "publickey") == 0) {
46040Sstevel@tonic-gate 			dumptable("hosts");
46050Sstevel@tonic-gate 			dumptable("passwd");
46060Sstevel@tonic-gate 		} else {
46070Sstevel@tonic-gate 			dumptable(databasetype);
46080Sstevel@tonic-gate 		}
46090Sstevel@tonic-gate 		exit(exit_val);
46100Sstevel@tonic-gate 	}
46110Sstevel@tonic-gate 
46120Sstevel@tonic-gate 	if (etcfile) {
46130Sstevel@tonic-gate 		if ((etcf = fopen(etcfile, "r")) == 0) {
46140Sstevel@tonic-gate 			(void) fprintf(stderr,
46150Sstevel@tonic-gate 			    gettext("can't open file %s\n"), etcfile);
46160Sstevel@tonic-gate 			exit(1);
46170Sstevel@tonic-gate 		}
46180Sstevel@tonic-gate 	} else {
46190Sstevel@tonic-gate 		etcfile = "stdin";
46200Sstevel@tonic-gate 		etcf = stdin;
46210Sstevel@tonic-gate 	}
46220Sstevel@tonic-gate 
46230Sstevel@tonic-gate 	if (op == OP_ADD) {
46240Sstevel@tonic-gate 		(void) addfile();
46250Sstevel@tonic-gate 		(void) fprintf(stdout, gettext("%d entries added\n"), nent_add);
46260Sstevel@tonic-gate 	}
46270Sstevel@tonic-gate 
4628*6842Sth160488 	__ns_ldap_cancelStandalone();
4629839Smj162486 	/* exit() -> return for make lint */
4630839Smj162486 	return (exit_val);
46310Sstevel@tonic-gate }
46320Sstevel@tonic-gate 
46330Sstevel@tonic-gate 
46340Sstevel@tonic-gate /*
46350Sstevel@tonic-gate  * This is called when service == auto_*.
46360Sstevel@tonic-gate  * It calls __ns_ldap_getSearchDescriptors
46370Sstevel@tonic-gate  * to generate the dn from SSD's base dn.
46380Sstevel@tonic-gate  * If there is no SSD available,
46390Sstevel@tonic-gate  * default base dn will be used
46400Sstevel@tonic-gate  * Only the first baseDN in the SSD is used
46410Sstevel@tonic-gate  */
46420Sstevel@tonic-gate 
46430Sstevel@tonic-gate static int get_basedn(char *service, char **basedn) {
46440Sstevel@tonic-gate 	int rc = NS_LDAP_SUCCESS;
46450Sstevel@tonic-gate 	char *dn = NULL;
46460Sstevel@tonic-gate 	ns_ldap_search_desc_t **desc = NULL;
46470Sstevel@tonic-gate 	ns_ldap_error_t *errp = NULL;
46480Sstevel@tonic-gate 	void		**paramVal = NULL;
46490Sstevel@tonic-gate 	int		prepend_automountmapname = FALSE;
46500Sstevel@tonic-gate 
46510Sstevel@tonic-gate 	/*
46520Sstevel@tonic-gate 	 * Get auto_* SSD first
46530Sstevel@tonic-gate 	 */
46540Sstevel@tonic-gate 
46550Sstevel@tonic-gate 	if ((rc = __ns_ldap_getSearchDescriptors(
46560Sstevel@tonic-gate 			(const char *) service,
46570Sstevel@tonic-gate 			&desc, &errp))  == NS_LDAP_SUCCESS &&
46580Sstevel@tonic-gate 		desc != NULL) {
46590Sstevel@tonic-gate 
46600Sstevel@tonic-gate 		if (desc[0] != NULL && desc[0]->basedn != NULL) {
46610Sstevel@tonic-gate 			dn = strdup(desc[0]->basedn);
46620Sstevel@tonic-gate 			if (dn == NULL) {
46630Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors
46640Sstevel@tonic-gate 						(&desc);
46650Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
46660Sstevel@tonic-gate 			}
46670Sstevel@tonic-gate 		}
46680Sstevel@tonic-gate 	}
46690Sstevel@tonic-gate 
46700Sstevel@tonic-gate 	/* clean up */
46710Sstevel@tonic-gate 	if (desc) (void) __ns_ldap_freeSearchDescriptors(&desc);
46720Sstevel@tonic-gate 	if (errp) (void) __ns_ldap_freeError(&errp);
46730Sstevel@tonic-gate 
46740Sstevel@tonic-gate 	/*
46750Sstevel@tonic-gate 	 * If no dn is duplicated from auto_* SSD, try automount SSD
46760Sstevel@tonic-gate 	 */
46770Sstevel@tonic-gate 	if (dn == NULL) {
46780Sstevel@tonic-gate 		if ((rc = __ns_ldap_getSearchDescriptors(
46790Sstevel@tonic-gate 				"automount", &desc, &errp))
46800Sstevel@tonic-gate 				== NS_LDAP_SUCCESS && desc != NULL) {
46810Sstevel@tonic-gate 
46820Sstevel@tonic-gate 			if (desc[0] != NULL && desc[0]->basedn != NULL) {
46830Sstevel@tonic-gate 				dn = strdup(desc[0]->basedn);
46840Sstevel@tonic-gate 				if (dn == NULL) {
46850Sstevel@tonic-gate 					(void) __ns_ldap_freeSearchDescriptors
46860Sstevel@tonic-gate 							(&desc);
46870Sstevel@tonic-gate 					return (NS_LDAP_MEMORY);
46880Sstevel@tonic-gate 				}
46890Sstevel@tonic-gate 				prepend_automountmapname = TRUE;
46900Sstevel@tonic-gate 			}
46910Sstevel@tonic-gate 		}
46920Sstevel@tonic-gate 		/* clean up */
46930Sstevel@tonic-gate 		if (desc) (void) __ns_ldap_freeSearchDescriptors(&desc);
46940Sstevel@tonic-gate 		if (errp) (void) __ns_ldap_freeError(&errp);
46950Sstevel@tonic-gate 	}
46960Sstevel@tonic-gate 
46970Sstevel@tonic-gate 	/*
46980Sstevel@tonic-gate 	 * If no dn is duplicated from auto_* or automount SSD,
46990Sstevel@tonic-gate 	 * use default DN
47000Sstevel@tonic-gate 	 */
47010Sstevel@tonic-gate 
47020Sstevel@tonic-gate 	if (dn == NULL) {
47030Sstevel@tonic-gate 		if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P,
47040Sstevel@tonic-gate 			&paramVal, &errp)) == NS_LDAP_SUCCESS) {
47050Sstevel@tonic-gate 			dn = strdup((char *)paramVal[0]);
47060Sstevel@tonic-gate 			if (dn == NULL) {
47070Sstevel@tonic-gate 				(void) __ns_ldap_freeParam(&paramVal);
47080Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
47090Sstevel@tonic-gate 			}
47100Sstevel@tonic-gate 			prepend_automountmapname = TRUE;
47110Sstevel@tonic-gate 		}
47120Sstevel@tonic-gate 		if (paramVal) (void) __ns_ldap_freeParam(&paramVal);
47130Sstevel@tonic-gate 		if (errp) (void) __ns_ldap_freeError(&errp);
47140Sstevel@tonic-gate 	}
47150Sstevel@tonic-gate 
47160Sstevel@tonic-gate 
47170Sstevel@tonic-gate 	if (dn == NULL) {
47180Sstevel@tonic-gate 		return (NS_LDAP_OP_FAILED);
47190Sstevel@tonic-gate 	} else {
47200Sstevel@tonic-gate 		/*
47210Sstevel@tonic-gate 		 * If dn is duplicated from
47220Sstevel@tonic-gate 		 * automount SSD basedn or
47230Sstevel@tonic-gate 		 * default base dn
47240Sstevel@tonic-gate 		 * then prepend automountMapName=auto_xxx
47250Sstevel@tonic-gate 		 */
47260Sstevel@tonic-gate 		if (prepend_automountmapname)
47270Sstevel@tonic-gate 			rc = __s_api_prepend_automountmapname_to_dn(
47280Sstevel@tonic-gate 				service, &dn, &errp);
47290Sstevel@tonic-gate 
47300Sstevel@tonic-gate 		if (rc != NS_LDAP_SUCCESS) {
47310Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&errp);
47320Sstevel@tonic-gate 			free(dn);
47330Sstevel@tonic-gate 			return (rc);
47340Sstevel@tonic-gate 		}
47350Sstevel@tonic-gate 
47360Sstevel@tonic-gate 		*basedn = dn;
47370Sstevel@tonic-gate 
47380Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
47390Sstevel@tonic-gate 	}
47400Sstevel@tonic-gate }
47412830Sdjl static char *
47422830Sdjl h_errno2str(int h_errno) {
47432830Sdjl 	switch (h_errno) {
47442830Sdjl 	case HOST_NOT_FOUND:
47452830Sdjl 		return ("HOST_NOT_FOUND");
47462830Sdjl 		break;
47472830Sdjl 	case TRY_AGAIN:
47482830Sdjl 		return ("TRY_AGAIN");
47492830Sdjl 		break;
47502830Sdjl 	case NO_RECOVERY:
47512830Sdjl 		return ("NO_RECOVERY");
47522830Sdjl 		break;
47532830Sdjl 	case NO_DATA:
47542830Sdjl 		return ("NO_DATA");
47552830Sdjl 		break;
47562830Sdjl 	default:
47572830Sdjl 		break;
47582830Sdjl 	}
47592830Sdjl 	return ("UNKNOWN_ERROR");
47602830Sdjl }
4761