17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5f31b640dSvl  * Common Development and Distribution License (the "License").
6f31b640dSvl  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
229f2fd570SJulian Pullen  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
2333f5ff17SMilan Jurik  * Copyright 2012 Milan Jurik. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * ldapaddent.c
287c478bd9Sstevel@tonic-gate  *
297c478bd9Sstevel@tonic-gate  * Utility to add /etc files into LDAP.
307c478bd9Sstevel@tonic-gate  * Can also be used to dump entries from a ldap container in /etc format.
317c478bd9Sstevel@tonic-gate  */
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include <stdio.h>
347c478bd9Sstevel@tonic-gate #include <stdlib.h>
357c478bd9Sstevel@tonic-gate #include <libintl.h>
367c478bd9Sstevel@tonic-gate #include <strings.h>
377c478bd9Sstevel@tonic-gate #include <sys/param.h>
387c478bd9Sstevel@tonic-gate #include <ctype.h>
397c478bd9Sstevel@tonic-gate #include <sys/types.h>
407c478bd9Sstevel@tonic-gate #include <sys/socket.h>
417c478bd9Sstevel@tonic-gate #include <netinet/in.h>
427c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
437c478bd9Sstevel@tonic-gate #include <locale.h>
447c478bd9Sstevel@tonic-gate #include <syslog.h>
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #undef opaque
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate #include <nss_dbdefs.h>
497c478bd9Sstevel@tonic-gate #include <netdb.h>
507c478bd9Sstevel@tonic-gate #include <rpc/rpcent.h>
517c478bd9Sstevel@tonic-gate #include <grp.h>
527c478bd9Sstevel@tonic-gate #include <pwd.h>
53e1dd0a2fSth #include <project.h>
547c478bd9Sstevel@tonic-gate #include <shadow.h>
557c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
567c478bd9Sstevel@tonic-gate #include "ns_internal.h"
577c478bd9Sstevel@tonic-gate #include "ldapaddent.h"
58e1dd0a2fSth #include "standalone.h"
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate #define	OP_ADD	0
617c478bd9Sstevel@tonic-gate #define	OP_DUMP	3
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate static struct ttypelist_t {
647c478bd9Sstevel@tonic-gate 	char *ttype;		/* type tag */
657c478bd9Sstevel@tonic-gate 	int (*genent)(char *, int(*)());
667c478bd9Sstevel@tonic-gate 				/* routine to turn line into ldap entries */
677c478bd9Sstevel@tonic-gate 	void (*dump)(ns_ldap_result_t *);
687c478bd9Sstevel@tonic-gate 				/* routine to print ldap containers */
697c478bd9Sstevel@tonic-gate 	int (*filedbmline)();	/* routine to turn file line into dbm line */
707c478bd9Sstevel@tonic-gate 	char *objclass;		/* Objectclass for the servicetype */
719f2fd570SJulian Pullen 	char *sortattr;		/* Sort attr for enumeration */
727c478bd9Sstevel@tonic-gate } *tt;
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate char	parse_err_msg [PARSE_ERR_MSG_LEN];
757c478bd9Sstevel@tonic-gate int	continue_onerror = 0;  /* do not exit on error */
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate static int get_basedn(char *service, char **basedn);
787c478bd9Sstevel@tonic-gate static int check_ipaddr(char *addr, char **newaddr);
79e1dd0a2fSth static int check_projname(char *addr);
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate extern	int	optind;
827c478bd9Sstevel@tonic-gate extern	char	*optarg;
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate extern	char	*__nis_quote_key(const char *, char *, int);
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate static char	*inputbasedn = NULL;
877c478bd9Sstevel@tonic-gate static char	*databasetype = NULL;
887c478bd9Sstevel@tonic-gate static int	exit_val = 0;
897c478bd9Sstevel@tonic-gate static unsigned	nent_add = 0;
907c478bd9Sstevel@tonic-gate static FILE	*etcf = 0;
917c478bd9Sstevel@tonic-gate static ns_cred_t	authority;
927c478bd9Sstevel@tonic-gate unsigned	flags = 0;
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate static void
perr(ns_ldap_error_t * e)957c478bd9Sstevel@tonic-gate perr(ns_ldap_error_t *e)
967c478bd9Sstevel@tonic-gate {
977c478bd9Sstevel@tonic-gate 	if (e)
98e1dd0a2fSth 		(void) fprintf(stderr, "%d: %s\n",
99e1dd0a2fSth 		    e->status, e->message);
1007c478bd9Sstevel@tonic-gate }
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate static int
ascii_to_int(char * str)1047c478bd9Sstevel@tonic-gate ascii_to_int(char *str)
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate 	int i;
1077c478bd9Sstevel@tonic-gate 	char *c = str;
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 	if (c == NULL || *c == '\0')
1107c478bd9Sstevel@tonic-gate 		return (-1);
1117c478bd9Sstevel@tonic-gate 
1123718f283SToomas Soome 	while (*c == ' ')
1137c478bd9Sstevel@tonic-gate 		c++;
1147c478bd9Sstevel@tonic-gate 	if (*c == '\0')
1157c478bd9Sstevel@tonic-gate 		return (-1);
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	for (i = 0; i < strlen(c); i++)
1187c478bd9Sstevel@tonic-gate 		if (!isdigit(c[i]))
1197c478bd9Sstevel@tonic-gate 			return (-1);
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 	return (atoi(c));
1227c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate /*
1257c478bd9Sstevel@tonic-gate  * Internet network address interpretation routine.
1267c478bd9Sstevel@tonic-gate  * The library routines call this routine to interpret
1277c478bd9Sstevel@tonic-gate  * network numbers.
1287c478bd9Sstevel@tonic-gate  */
1297c478bd9Sstevel@tonic-gate static in_addr_t
encode_network(const char * cp)1307c478bd9Sstevel@tonic-gate encode_network(const char *cp)
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate 	in_addr_t val;
1337c478bd9Sstevel@tonic-gate 	int base;
1347c478bd9Sstevel@tonic-gate 	ptrdiff_t n;
1357c478bd9Sstevel@tonic-gate 	char c;
1367c478bd9Sstevel@tonic-gate 	in_addr_t parts[4], *pp = parts;
1377c478bd9Sstevel@tonic-gate 	int i;
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate again:
1407c478bd9Sstevel@tonic-gate 	val = 0; base = 10;
1417c478bd9Sstevel@tonic-gate 	if (*cp == '0') {
1427c478bd9Sstevel@tonic-gate 		if (*++cp == 'x' || *cp == 'X')
1437c478bd9Sstevel@tonic-gate 			base = 16, cp++;
1447c478bd9Sstevel@tonic-gate 		else
1457c478bd9Sstevel@tonic-gate 			base = 8;
1467c478bd9Sstevel@tonic-gate 	}
147c59d9dffSToomas Soome 	while ((c = *cp) != '\0') {
1487c478bd9Sstevel@tonic-gate 		if (isdigit(c)) {
1497c478bd9Sstevel@tonic-gate 			if ((c - '0') >= base)
150e1dd0a2fSth 				break;
1517c478bd9Sstevel@tonic-gate 			val = (val * base) + (c - '0');
1527c478bd9Sstevel@tonic-gate 			cp++;
1537c478bd9Sstevel@tonic-gate 			continue;
1547c478bd9Sstevel@tonic-gate 		}
1557c478bd9Sstevel@tonic-gate 		if (base == 16 && isxdigit(c)) {
1567c478bd9Sstevel@tonic-gate 			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
1577c478bd9Sstevel@tonic-gate 			cp++;
1587c478bd9Sstevel@tonic-gate 			continue;
1597c478bd9Sstevel@tonic-gate 		}
1607c478bd9Sstevel@tonic-gate 		break;
1617c478bd9Sstevel@tonic-gate 	}
1627c478bd9Sstevel@tonic-gate 	if (*cp == '.') {
1637c478bd9Sstevel@tonic-gate 		if (pp >= parts + 4)
1647c478bd9Sstevel@tonic-gate 			return ((in_addr_t)-1);
1657c478bd9Sstevel@tonic-gate 		*pp++ = val, cp++;
1667c478bd9Sstevel@tonic-gate 		goto again;
1677c478bd9Sstevel@tonic-gate 	}
1687c478bd9Sstevel@tonic-gate 	if (*cp && !isspace(*cp))
1697c478bd9Sstevel@tonic-gate 		return ((in_addr_t)-1);
1707c478bd9Sstevel@tonic-gate 	*pp++ = val;
1717c478bd9Sstevel@tonic-gate 	n = pp - parts;
1727c478bd9Sstevel@tonic-gate 	if (n > 4)
1737c478bd9Sstevel@tonic-gate 		return ((in_addr_t)-1);
1747c478bd9Sstevel@tonic-gate 	for (val = 0, i = 0; i < n; i++) {
1757c478bd9Sstevel@tonic-gate 		val <<= 8;
1767c478bd9Sstevel@tonic-gate 		val |= parts[i] & 0xff;
1777c478bd9Sstevel@tonic-gate 	}
1787c478bd9Sstevel@tonic-gate 	for (/* no init */; i < 4; i++)
1797c478bd9Sstevel@tonic-gate 		val <<= 8;
1807c478bd9Sstevel@tonic-gate 	return (val);
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate static void
replace_tab2space(char * str)1847c478bd9Sstevel@tonic-gate replace_tab2space(char *str)
1857c478bd9Sstevel@tonic-gate {
1867c478bd9Sstevel@tonic-gate 	int i = 0;
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 	while ((str) && (str[i])) {
1897c478bd9Sstevel@tonic-gate 		if (str[i] == '\t')
1907c478bd9Sstevel@tonic-gate 			str[i] = ' ';
1917c478bd9Sstevel@tonic-gate 		i++;
1927c478bd9Sstevel@tonic-gate 	}
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate static int
blankline(char * line)1967c478bd9Sstevel@tonic-gate blankline(char *line)
1977c478bd9Sstevel@tonic-gate {
1987c478bd9Sstevel@tonic-gate 	char *p;
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 	for (p = line; *p; p++)
2017c478bd9Sstevel@tonic-gate 		if (*p != ' ' && *p != '\t')
2027c478bd9Sstevel@tonic-gate 			return (0);
2037c478bd9Sstevel@tonic-gate 	return (1);
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate 
206f31b640dSvl /*
207f31b640dSvl  * check whether the token <tok> is a triplet,
208f31b640dSvl  * i. e. <tok> := (<hostname>,<username>,<domainname>)
209f31b640dSvl  * where <hostname>, <username>, <domainname> are IA5String
210f31b640dSvl  * <tok> supposes to contain NO spaces and start with '('
211f31b640dSvl  */
212f31b640dSvl static int
is_triplet(char * tok)213f31b640dSvl is_triplet(char *tok)
214f31b640dSvl {
215f31b640dSvl 	char *s;
216f31b640dSvl 	return (strchr(++tok, '(') == NULL &&		/* no more '(' */
217e1dd0a2fSth 	    (s = strchr(tok, ')')) != NULL &&		/* find ')' */
218e1dd0a2fSth 	    !*++s &&					/* ')' ends token */
219e1dd0a2fSth 	    (tok = strchr(tok, ',')) != NULL &&		/* host up to ',' */
220e1dd0a2fSth 	    (tok = strchr(++tok, ',')) != NULL &&	/* user up to ',' */
221e1dd0a2fSth 	    strchr(++tok, ',') == NULL);		/* no more ',' */
222f31b640dSvl }
223f31b640dSvl 
2247c478bd9Sstevel@tonic-gate static void
line_buf_expand(struct line_buf * line)2257c478bd9Sstevel@tonic-gate line_buf_expand(struct line_buf *line)
2267c478bd9Sstevel@tonic-gate {
2277c478bd9Sstevel@tonic-gate 	line->alloc += BUFSIZ;
2287c478bd9Sstevel@tonic-gate 	line->str = (char *)realloc(line->str, line->alloc);
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	if (line->str == NULL) {
2317c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
2327c478bd9Sstevel@tonic-gate 		    gettext("line_buf_expand: out of memory\n"));
2337c478bd9Sstevel@tonic-gate 		exit(1);
2347c478bd9Sstevel@tonic-gate 	}
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate static void
line_buf_init(struct line_buf * line)2387c478bd9Sstevel@tonic-gate line_buf_init(struct line_buf *line)
2397c478bd9Sstevel@tonic-gate {
2407c478bd9Sstevel@tonic-gate 	(void) memset((char *)line, 0, sizeof (*line));
2417c478bd9Sstevel@tonic-gate 	line_buf_expand(line);
2427c478bd9Sstevel@tonic-gate }
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate static int
__s_add_attr(ns_ldap_entry_t * e,char * attrname,char * value)2457c478bd9Sstevel@tonic-gate __s_add_attr(ns_ldap_entry_t *e, char *attrname, char *value)
2467c478bd9Sstevel@tonic-gate {
2477c478bd9Sstevel@tonic-gate 	ns_ldap_attr_t	*a;
2487c478bd9Sstevel@tonic-gate 	char		*v;
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 	a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t));
2517c478bd9Sstevel@tonic-gate 	if (a == NULL)
2527c478bd9Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2537c478bd9Sstevel@tonic-gate 	a->attrname = strdup(attrname);
2547c478bd9Sstevel@tonic-gate 	if (a->attrname == NULL) {
2557c478bd9Sstevel@tonic-gate 		free(a);
2567c478bd9Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2577c478bd9Sstevel@tonic-gate 	}
2587c478bd9Sstevel@tonic-gate 	a->attrvalue = (char **)calloc(1, sizeof (char **));
2597c478bd9Sstevel@tonic-gate 	if (a->attrvalue == NULL) {
2607c478bd9Sstevel@tonic-gate 		free(a->attrname);
2617c478bd9Sstevel@tonic-gate 		free(a);
2627c478bd9Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2637c478bd9Sstevel@tonic-gate 	}
2647c478bd9Sstevel@tonic-gate 	a->value_count = 1;
2657c478bd9Sstevel@tonic-gate 	a->attrvalue[0] = NULL;
2667c478bd9Sstevel@tonic-gate 	v = strdup(value);
2677c478bd9Sstevel@tonic-gate 	if (v == NULL) {
2687c478bd9Sstevel@tonic-gate 		free(a->attrname);
2697c478bd9Sstevel@tonic-gate 		free(a->attrvalue);
2707c478bd9Sstevel@tonic-gate 		free(a);
2717c478bd9Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2727c478bd9Sstevel@tonic-gate 	}
2737c478bd9Sstevel@tonic-gate 	a->attrvalue[0] = v;
2747c478bd9Sstevel@tonic-gate 	e->attr_pair[e->attr_count] = a;
2757c478bd9Sstevel@tonic-gate 	e->attr_count++;
2767c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate static int
__s_add_attrlist(ns_ldap_entry_t * e,char * attrname,char ** argv)2807c478bd9Sstevel@tonic-gate __s_add_attrlist(ns_ldap_entry_t *e, char *attrname, char **argv)
2817c478bd9Sstevel@tonic-gate {
2827c478bd9Sstevel@tonic-gate 	ns_ldap_attr_t	*a;
2837c478bd9Sstevel@tonic-gate 	char		*v;
2847c478bd9Sstevel@tonic-gate 	char		**av;
2857c478bd9Sstevel@tonic-gate 	int		i, j;
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 	a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t));
2887c478bd9Sstevel@tonic-gate 	if (a == NULL)
2897c478bd9Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2907c478bd9Sstevel@tonic-gate 	a->attrname = strdup(attrname);
2917c478bd9Sstevel@tonic-gate 	if (a->attrname == NULL) {
2927c478bd9Sstevel@tonic-gate 		free(a);
2937c478bd9Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
2947c478bd9Sstevel@tonic-gate 	}
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	for (i = 0, av = argv; *av != NULL; av++, i++)
2977c478bd9Sstevel@tonic-gate 		;
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 	a->attrvalue = (char **)calloc(i, sizeof (char **));
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate 	if (a->attrvalue == NULL) {
3027c478bd9Sstevel@tonic-gate 		free(a->attrname);
3037c478bd9Sstevel@tonic-gate 		free(a);
3047c478bd9Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
3057c478bd9Sstevel@tonic-gate 	}
3067c478bd9Sstevel@tonic-gate 	a->value_count = i;
3077c478bd9Sstevel@tonic-gate 	for (j = 0; j < i; j++) {
3087c478bd9Sstevel@tonic-gate 		v = strdup(argv[j]);
3097c478bd9Sstevel@tonic-gate 		if (v == NULL) {
3107c478bd9Sstevel@tonic-gate 			free(a->attrname);
3117c478bd9Sstevel@tonic-gate 			free(a->attrvalue);
3127c478bd9Sstevel@tonic-gate 			free(a);
3137c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
3147c478bd9Sstevel@tonic-gate 		}
3157c478bd9Sstevel@tonic-gate 		a->attrvalue[j] = v;
3167c478bd9Sstevel@tonic-gate 	}
3177c478bd9Sstevel@tonic-gate 	e->attr_pair[e->attr_count] = a;
3187c478bd9Sstevel@tonic-gate 	e->attr_count++;
3197c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
3207c478bd9Sstevel@tonic-gate }
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate static ns_ldap_entry_t *
__s_mk_entry(char ** objclass,int max_attr)3237c478bd9Sstevel@tonic-gate __s_mk_entry(char **objclass, int max_attr)
3247c478bd9Sstevel@tonic-gate {
3257c478bd9Sstevel@tonic-gate 	ns_ldap_entry_t *e;
3267c478bd9Sstevel@tonic-gate 	e = (ns_ldap_entry_t *)calloc(1, sizeof (ns_ldap_entry_t));
3277c478bd9Sstevel@tonic-gate 	if (e == NULL)
3287c478bd9Sstevel@tonic-gate 		return (NULL);
3297c478bd9Sstevel@tonic-gate 	e->attr_pair = (ns_ldap_attr_t **)calloc(max_attr+1,
330e1dd0a2fSth 	    sizeof (ns_ldap_attr_t *));
3317c478bd9Sstevel@tonic-gate 	if (e->attr_pair == NULL) {
3327c478bd9Sstevel@tonic-gate 		free(e);
3337c478bd9Sstevel@tonic-gate 		return (NULL);
3347c478bd9Sstevel@tonic-gate 	}
3357c478bd9Sstevel@tonic-gate 	e->attr_count = 0;
3367c478bd9Sstevel@tonic-gate 	if (__s_add_attrlist(e, "objectClass", objclass) != NS_LDAP_SUCCESS) {
3377c478bd9Sstevel@tonic-gate 		free(e->attr_pair);
3387c478bd9Sstevel@tonic-gate 		free(e);
3397c478bd9Sstevel@tonic-gate 		return (NULL);
3407c478bd9Sstevel@tonic-gate 	}
3417c478bd9Sstevel@tonic-gate 	return (e);
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate static void
ldap_freeEntry(ns_ldap_entry_t * ep)3457c478bd9Sstevel@tonic-gate ldap_freeEntry(ns_ldap_entry_t *ep)
3467c478bd9Sstevel@tonic-gate {
3477c478bd9Sstevel@tonic-gate 	int		j, k = 0;
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate 	if (ep == NULL)
3507c478bd9Sstevel@tonic-gate 		return;
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 	if (ep->attr_pair == NULL) {
3537c478bd9Sstevel@tonic-gate 		free(ep);
3547c478bd9Sstevel@tonic-gate 		return;
3557c478bd9Sstevel@tonic-gate 	}
3567c478bd9Sstevel@tonic-gate 	for (j = 0; j < ep->attr_count; j++) {
3577c478bd9Sstevel@tonic-gate 		if (ep->attr_pair[j] == NULL)
3587c478bd9Sstevel@tonic-gate 			continue;
3597c478bd9Sstevel@tonic-gate 		if (ep->attr_pair[j]->attrname)
3607c478bd9Sstevel@tonic-gate 			free(ep->attr_pair[j]->attrname);
3617c478bd9Sstevel@tonic-gate 		if (ep->attr_pair[j]->attrvalue) {
3627c478bd9Sstevel@tonic-gate 			for (k = 0; (k < ep->attr_pair[j]->value_count) &&
363e1dd0a2fSth 			    (ep->attr_pair[j]->attrvalue[k]); k++) {
3647c478bd9Sstevel@tonic-gate 				free(ep->attr_pair[j]->attrvalue[k]);
3657c478bd9Sstevel@tonic-gate 			}
3667c478bd9Sstevel@tonic-gate 			free(ep->attr_pair[j]->attrvalue);
3677c478bd9Sstevel@tonic-gate 		}
3687c478bd9Sstevel@tonic-gate 		free(ep->attr_pair[j]);
3697c478bd9Sstevel@tonic-gate 	}
3707c478bd9Sstevel@tonic-gate 	free(ep->attr_pair);
3717c478bd9Sstevel@tonic-gate 	free(ep);
3727c478bd9Sstevel@tonic-gate }
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate static int
addentry(void * entry,int mod)3757c478bd9Sstevel@tonic-gate addentry(void *entry, int mod)
3767c478bd9Sstevel@tonic-gate {
3777c478bd9Sstevel@tonic-gate 	int		 result = 0;
3787c478bd9Sstevel@tonic-gate 	ns_ldap_error_t	 *eres = NULL;
3797c478bd9Sstevel@tonic-gate 	int		rc = 1;
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate 	/*  adds entry into the LDAP tree */
3837c478bd9Sstevel@tonic-gate 	if (mod)
3847c478bd9Sstevel@tonic-gate 		result = __ns_ldap_addTypedEntry(databasetype, inputbasedn,
385e1dd0a2fSth 		    entry, 0, &authority, NS_LDAP_FOLLOWREF | NS_LDAP_KEEP_CONN,
386e1dd0a2fSth 		    &eres);
3877c478bd9Sstevel@tonic-gate 	else
3887c478bd9Sstevel@tonic-gate 		result = __ns_ldap_addTypedEntry(databasetype, inputbasedn,
389e1dd0a2fSth 		    entry, 1, &authority, NS_LDAP_FOLLOWREF | NS_LDAP_KEEP_CONN,
390e1dd0a2fSth 		    &eres);
3917c478bd9Sstevel@tonic-gate 	/*
3927c478bd9Sstevel@tonic-gate 	 *  Return	0 on success
3937c478bd9Sstevel@tonic-gate 	 *		LDAP_ALREADY_EXISTS if entry exists already
3947c478bd9Sstevel@tonic-gate 	 *		1 for all other non-fatal errors.
3957c478bd9Sstevel@tonic-gate 	 *  Exit on fatal errors.
3967c478bd9Sstevel@tonic-gate 	 */
3977c478bd9Sstevel@tonic-gate 	switch (result) {
3987c478bd9Sstevel@tonic-gate 	case NS_LDAP_SUCCESS:
3997c478bd9Sstevel@tonic-gate 		nent_add++;
4007c478bd9Sstevel@tonic-gate 		rc = 0;
4017c478bd9Sstevel@tonic-gate 		break;
4027c478bd9Sstevel@tonic-gate 
4037c478bd9Sstevel@tonic-gate 	case NS_LDAP_OP_FAILED:
4047c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("operation failed.\n"));
4057c478bd9Sstevel@tonic-gate 		rc = 1;
4067c478bd9Sstevel@tonic-gate 		break;
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate 	case NS_LDAP_INVALID_PARAM:
4097c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
4107c478bd9Sstevel@tonic-gate 		    gettext("invalid parameter(s) passed.\n"));
4117c478bd9Sstevel@tonic-gate 		rc = 1;
4127c478bd9Sstevel@tonic-gate 		break;
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate 	case NS_LDAP_NOTFOUND:
4157c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("entry not found.\n"));
4167c478bd9Sstevel@tonic-gate 		rc = 1;
4177c478bd9Sstevel@tonic-gate 		break;
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate 	case NS_LDAP_MEMORY:
4207c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
4217c478bd9Sstevel@tonic-gate 		    gettext("internal memory allocation error.\n"));
4227c478bd9Sstevel@tonic-gate 		exit(1);
4237c478bd9Sstevel@tonic-gate 		break;
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate 	case NS_LDAP_CONFIG:
4267c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
4277c478bd9Sstevel@tonic-gate 		    gettext("LDAP Configuration problem.\n"));
4287c478bd9Sstevel@tonic-gate 		perr(eres);
4297c478bd9Sstevel@tonic-gate 		exit(1);
4307c478bd9Sstevel@tonic-gate 		break;
4317c478bd9Sstevel@tonic-gate 
4327c478bd9Sstevel@tonic-gate 	case NS_LDAP_PARTIAL:
4337c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
4347c478bd9Sstevel@tonic-gate 		    gettext("partial result returned\n"));
4357c478bd9Sstevel@tonic-gate 		perr(eres);
4367c478bd9Sstevel@tonic-gate 		rc = 1;
4377c478bd9Sstevel@tonic-gate 		break;
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate 	case NS_LDAP_INTERNAL:
44012fbe00aSjs 		if (eres->status == LDAP_ALREADY_EXISTS ||
441e1dd0a2fSth 		    eres->status == LDAP_NO_SUCH_OBJECT)
4427c478bd9Sstevel@tonic-gate 			rc = eres->status;
443cb5caa98Sdjl 		else if (eres->status == LDAP_INSUFFICIENT_ACCESS) {
444cb5caa98Sdjl 			(void) fprintf(stderr,
445e1dd0a2fSth 			    gettext("The user does not have permission"
446e1dd0a2fSth 			    " to add/modify entries\n"));
447cb5caa98Sdjl 			perr(eres);
448cb5caa98Sdjl 			exit(1);
449cb5caa98Sdjl 		} else {
4507c478bd9Sstevel@tonic-gate 			rc = 1;
4517c478bd9Sstevel@tonic-gate 			perr(eres);
4527c478bd9Sstevel@tonic-gate 		}
4537c478bd9Sstevel@tonic-gate 		break;
4547c478bd9Sstevel@tonic-gate 	}
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 	if (eres)
4577c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&eres);
4587c478bd9Sstevel@tonic-gate 	return (rc);
4597c478bd9Sstevel@tonic-gate }
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate /*
4627c478bd9Sstevel@tonic-gate  * usage(char *msg)
4637c478bd9Sstevel@tonic-gate  * Display usage message to STDERR.
4647c478bd9Sstevel@tonic-gate  */
4657c478bd9Sstevel@tonic-gate static void
usage(char * msg)466c59d9dffSToomas Soome usage(char *msg)
467c59d9dffSToomas Soome {
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 	if (msg)
470e1dd0a2fSth 		(void) fprintf(stderr, "%s\n", msg);
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
473e1dd0a2fSth 	"usage: ldapaddent [-cpv] [-a authenticationMethod] [-b baseDN]\n"
474e1dd0a2fSth 	"-D bindDN [-w bindPassword] [-j passwdFile] [-f filename]\n"
475e1dd0a2fSth 	"database\n"
476e1dd0a2fSth 	"\n"
477e1dd0a2fSth 	"usage: ldapaddent  [-cpv] -asasl/GSSAPI [-b baseDN] [-f filename]\n"
478e1dd0a2fSth 	"database\n"
479e1dd0a2fSth 	"\n"
480e1dd0a2fSth 	"usage: ldapaddent  -d [-v] [-a authenticationMethod] [-D bindDN]\n"
481e1dd0a2fSth 	"[-w bindPassword] [-j passwdFile] database\n"
482e1dd0a2fSth 	"\n"
483e1dd0a2fSth 	"usage: ldapaddent [-cpv] -h LDAP_server[:serverPort] [-M domainName]\n"
484e1dd0a2fSth 	"[-N  profileName]  [-P certifPath]  [-a authenticationMethod]\n"
485e1dd0a2fSth 	"[-b baseDN] -D bindDN [-w bindPassword] [-f filename]\n"
486e1dd0a2fSth 	"[-j passwdFile] database\n"
487e1dd0a2fSth 	"\n"
488e1dd0a2fSth 	"usage: ldapaddent [-cpv] -h LDAP_server[:serverPort] [-M domainName]\n"
489e1dd0a2fSth 	"[-N  profileName]  [-P certifPath] -asasl/GSSAPI  [-b baseDN]\n"
490e1dd0a2fSth 	"[-f filename] database\n"
491e1dd0a2fSth 	"\n"
492e1dd0a2fSth 	"usage: ldapaddent -d [-v] -h LDAP_server[:serverPort]"
493e1dd0a2fSth 	" [-M domainName]\n"
494e1dd0a2fSth 	"[-N profileName]  [-P certifPath]  [-a authenticationMethod]\n"
495e1dd0a2fSth 	"[-b baseDN] -D bindDN [-w bindPassword] [-j passwdFile]\n"
496e1dd0a2fSth 	"database\n"));
4977c478bd9Sstevel@tonic-gate 	exit(1);
4987c478bd9Sstevel@tonic-gate }
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate /*
5017c478bd9Sstevel@tonic-gate  * Determine if the given string is an IP address (IPv4 or IPv6).
5027c478bd9Sstevel@tonic-gate  * If so, it's converted to the preferred form (rfc2373) and
5037c478bd9Sstevel@tonic-gate  * *newaddr will point to the new address.
5047c478bd9Sstevel@tonic-gate  *
5057c478bd9Sstevel@tonic-gate  * Returns	-2		: inet_ntop error
5067c478bd9Sstevel@tonic-gate  *		-1		: not an IP address
5077c478bd9Sstevel@tonic-gate  *		0		: unsupported IP address (future use)
5087c478bd9Sstevel@tonic-gate  *		AF_INET		: IPv4
5097c478bd9Sstevel@tonic-gate  *		AF_INET6	: IPv6
5107c478bd9Sstevel@tonic-gate  */
5117c478bd9Sstevel@tonic-gate static int
check_ipaddr(char * addr,char ** newaddr)512c59d9dffSToomas Soome check_ipaddr(char *addr, char **newaddr)
513c59d9dffSToomas Soome {
5147c478bd9Sstevel@tonic-gate 	ipaddr_t	addr_ipv4 = 0;
5157c478bd9Sstevel@tonic-gate 	in6_addr_t	addr_ipv6;
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate 	/* IPv6 */
5187c478bd9Sstevel@tonic-gate 	if (inet_pton(AF_INET6, addr, &addr_ipv6) == 1) {
5197c478bd9Sstevel@tonic-gate 		if (newaddr == NULL)
5207c478bd9Sstevel@tonic-gate 			return (AF_INET6);
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 		/* Convert IPv4-mapped IPv6 address to IPv4 */
5237c478bd9Sstevel@tonic-gate 		if (IN6_IS_ADDR_V4MAPPED(&addr_ipv6) ||
524c59d9dffSToomas Soome 		    IN6_IS_ADDR_V4COMPAT(&addr_ipv6)) {
5257c478bd9Sstevel@tonic-gate 			IN6_V4MAPPED_TO_IPADDR(&addr_ipv6, addr_ipv4);
5267c478bd9Sstevel@tonic-gate 			if ((*newaddr = calloc(1, INET_ADDRSTRLEN)) == NULL) {
5277c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
5287c478bd9Sstevel@tonic-gate 				    gettext("out of memory\n"));
5297c478bd9Sstevel@tonic-gate 				exit(1);
5307c478bd9Sstevel@tonic-gate 			}
5317c478bd9Sstevel@tonic-gate 			if (inet_ntop(AF_INET, &addr_ipv4, *newaddr,
5327c478bd9Sstevel@tonic-gate 			    INET_ADDRSTRLEN))
5337c478bd9Sstevel@tonic-gate 				return (AF_INET6);
5347c478bd9Sstevel@tonic-gate 			free(*newaddr);
5357c478bd9Sstevel@tonic-gate 			return (-2);
5367c478bd9Sstevel@tonic-gate 		}
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 		/* Processing general IPv6 addresses */
5397c478bd9Sstevel@tonic-gate 		if ((*newaddr = calloc(1, INET6_ADDRSTRLEN)) == NULL) {
5407c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
5417c478bd9Sstevel@tonic-gate 			exit(1);
5427c478bd9Sstevel@tonic-gate 		}
5437c478bd9Sstevel@tonic-gate 		if (inet_ntop(AF_INET6, &addr_ipv6, *newaddr, INET6_ADDRSTRLEN))
5447c478bd9Sstevel@tonic-gate 			return (AF_INET6);
5457c478bd9Sstevel@tonic-gate 		free(*newaddr);
5467c478bd9Sstevel@tonic-gate 		return (-2);
5477c478bd9Sstevel@tonic-gate 	}
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate 	/* Processing IPv4 addresses of the type d.d.d.d. */
5507c478bd9Sstevel@tonic-gate 	if (inet_pton(AF_INET, addr, &addr_ipv4) == 1) {
5517c478bd9Sstevel@tonic-gate 		if (newaddr == NULL)
5527c478bd9Sstevel@tonic-gate 			return (AF_INET);
5537c478bd9Sstevel@tonic-gate 		if ((*newaddr = calloc(1, INET_ADDRSTRLEN)) == NULL) {
5547c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
5557c478bd9Sstevel@tonic-gate 			exit(1);
5567c478bd9Sstevel@tonic-gate 		}
5577c478bd9Sstevel@tonic-gate 		if (inet_ntop(AF_INET, &addr_ipv4, *newaddr, INET_ADDRSTRLEN))
5587c478bd9Sstevel@tonic-gate 			return (AF_INET);
5597c478bd9Sstevel@tonic-gate 		free(*newaddr);
5607c478bd9Sstevel@tonic-gate 		return (-2);
5617c478bd9Sstevel@tonic-gate 	}
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 	/* Processing IPv4 addresses d.d.d , d.d and d */
5647c478bd9Sstevel@tonic-gate 	if (inet_addr(addr) != (in_addr_t)-1) {
5657c478bd9Sstevel@tonic-gate 		if (newaddr == NULL)
5667c478bd9Sstevel@tonic-gate 			return (AF_INET);
5677c478bd9Sstevel@tonic-gate 		if ((*newaddr = strdup(addr)) == NULL) {
5687c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
5697c478bd9Sstevel@tonic-gate 			exit(1);
5707c478bd9Sstevel@tonic-gate 		}
5717c478bd9Sstevel@tonic-gate 		return (AF_INET);
5727c478bd9Sstevel@tonic-gate 	}
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	return (-1);
5757c478bd9Sstevel@tonic-gate }
5767c478bd9Sstevel@tonic-gate 
577e1dd0a2fSth /*
578*bbf21555SRichard Lowe  * Verifies that project name meets the restrictions defined by project(5).
579e1dd0a2fSth  */
580e1dd0a2fSth static int
check_projname(char * addr)581e1dd0a2fSth check_projname(char *addr)
582e1dd0a2fSth {
583e1dd0a2fSth 	int i;
584e1dd0a2fSth 	if (addr == NULL || *addr == '\0')
585e1dd0a2fSth 		return (-1);
586e1dd0a2fSth 
587e1dd0a2fSth 	for (i = 0; i < strlen(addr); i++) {
588e1dd0a2fSth 		if (!isalpha(addr[i]) &&
589e1dd0a2fSth 		    !isdigit(addr[i]) &&
590e1dd0a2fSth 		    addr[i] != '_' &&
591e1dd0a2fSth 		    addr[i] != '-' &&
592e1dd0a2fSth 		    addr[i] != '.')
593e1dd0a2fSth 			return (-1);
594e1dd0a2fSth 	}
595e1dd0a2fSth 
596e1dd0a2fSth 	return (0);
597e1dd0a2fSth }
598e1dd0a2fSth 
5997c478bd9Sstevel@tonic-gate static int
genent_hosts(char * line,int (* cback)())6007c478bd9Sstevel@tonic-gate genent_hosts(char *line, int (*cback)())
6017c478bd9Sstevel@tonic-gate {
6027c478bd9Sstevel@tonic-gate 	char buf[BUFSIZ+1];
6036d3c3c6aSiz 	char *t, *comment;
6047c478bd9Sstevel@tonic-gate 	entry_col ecol[4];
6057c478bd9Sstevel@tonic-gate 	char *cname, *pref_addr;
6067c478bd9Sstevel@tonic-gate 	int ctr = 0, retval = 1;
6077c478bd9Sstevel@tonic-gate 	int rc = GENENT_OK, af;
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate 	struct hostent  data;
6107c478bd9Sstevel@tonic-gate 	char *alias;
6117c478bd9Sstevel@tonic-gate 
6127c478bd9Sstevel@tonic-gate 	/*
6137c478bd9Sstevel@tonic-gate 	 * don't clobber our argument
6147c478bd9Sstevel@tonic-gate 	 */
6157c478bd9Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
616e1dd0a2fSth 		(void) strlcpy(parse_err_msg, gettext("line too long"),
617e1dd0a2fSth 		    PARSE_ERR_MSG_LEN);
6187c478bd9Sstevel@tonic-gate 		return (GENENT_PARSEERR);
6197c478bd9Sstevel@tonic-gate 	}
6207c478bd9Sstevel@tonic-gate 	(void) strcpy(buf, line);
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate 	/*
6237c478bd9Sstevel@tonic-gate 	 * clear column data
6247c478bd9Sstevel@tonic-gate 	 */
6257c478bd9Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate 	/*
6287c478bd9Sstevel@tonic-gate 	 * comment (col 3)
6296d3c3c6aSiz 	 * All leading spaces will be deleted from the comment
6307c478bd9Sstevel@tonic-gate 	 */
6316d3c3c6aSiz 	ecol[3].ec_value.ec_value_val = "";
6326d3c3c6aSiz 	ecol[3].ec_value.ec_value_len = 0;
6336d3c3c6aSiz 	comment = t = strchr(buf, '#');
6346d3c3c6aSiz 	if (comment) {
6356d3c3c6aSiz 		do {
6366d3c3c6aSiz 			++comment;
6376d3c3c6aSiz 		} while (*comment != '\0' && isspace(*comment));
6386d3c3c6aSiz 		if (*comment != '\0') {
6396d3c3c6aSiz 			*--comment = '#';
6406d3c3c6aSiz 			ecol[3].ec_value.ec_value_val = strdup(comment);
6416d3c3c6aSiz 			ecol[3].ec_value.ec_value_len = strlen(comment)+1;
6426d3c3c6aSiz 		}
6437c478bd9Sstevel@tonic-gate 
6446d3c3c6aSiz 		*t = '\0';
6456d3c3c6aSiz 	}
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate 	/*
6487c478bd9Sstevel@tonic-gate 	 * addr(col 2)
6497c478bd9Sstevel@tonic-gate 	 */
6507c478bd9Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
651e1dd0a2fSth 		(void) strlcpy(parse_err_msg, gettext("no host"),
652e1dd0a2fSth 		    PARSE_ERR_MSG_LEN);
6537c478bd9Sstevel@tonic-gate 		return (GENENT_PARSEERR);
6547c478bd9Sstevel@tonic-gate 	}
6557c478bd9Sstevel@tonic-gate 
6567c478bd9Sstevel@tonic-gate 	af = check_ipaddr(t, &pref_addr);
6577c478bd9Sstevel@tonic-gate 	if (af == -2) {
658e1dd0a2fSth 		(void) strlcpy(parse_err_msg, gettext("Internal error"),
659e1dd0a2fSth 		    PARSE_ERR_MSG_LEN);
6607c478bd9Sstevel@tonic-gate 	} else if (af == -1) {
6617c478bd9Sstevel@tonic-gate 		(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
662e1dd0a2fSth 		    gettext("Invalid IP address: %s"), t);
6637c478bd9Sstevel@tonic-gate 	} else if (flags & F_VERBOSE) {
6647c478bd9Sstevel@tonic-gate 		if ((strncasecmp(t, pref_addr, strlen(t))) != 0) {
6657c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
6667c478bd9Sstevel@tonic-gate 			    gettext("IP address %s converted to %s\n"),
6677c478bd9Sstevel@tonic-gate 			    t, pref_addr);
6687c478bd9Sstevel@tonic-gate 		}
6697c478bd9Sstevel@tonic-gate 	}
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate 	if (af < 0) {
672e1dd0a2fSth 		(void) fprintf(stderr, "%s\n", parse_err_msg);
6737c478bd9Sstevel@tonic-gate 		if (continue_onerror == 0)
6747c478bd9Sstevel@tonic-gate 			return (GENENT_CBERR);
6757c478bd9Sstevel@tonic-gate 		else
6767c478bd9Sstevel@tonic-gate 			return (rc);
6777c478bd9Sstevel@tonic-gate 	}
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = pref_addr;
6807c478bd9Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(pref_addr)+1;
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate 	/*
6837c478bd9Sstevel@tonic-gate 	 * cname (col 0)
6847c478bd9Sstevel@tonic-gate 	 */
6857c478bd9Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
686e1dd0a2fSth 		(void) strlcpy(parse_err_msg, gettext("no cname"),
687e1dd0a2fSth 		    PARSE_ERR_MSG_LEN);
6887c478bd9Sstevel@tonic-gate 		return (GENENT_PARSEERR);
6897c478bd9Sstevel@tonic-gate 	}
6907c478bd9Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
6917c478bd9Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
6927c478bd9Sstevel@tonic-gate 	cname = t;
6937c478bd9Sstevel@tonic-gate 
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate 	/* build entry */
6967c478bd9Sstevel@tonic-gate 	if ((data.h_addr_list = (char **)calloc(2, sizeof (char **))) == NULL) {
6977c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
6987c478bd9Sstevel@tonic-gate 		exit(1);
6997c478bd9Sstevel@tonic-gate 	}
7007c478bd9Sstevel@tonic-gate 	data.h_addr_list[0] = strdup(ecol[2].ec_value.ec_value_val);
7017c478bd9Sstevel@tonic-gate 	data.h_addr_list[1] = NULL;
7027c478bd9Sstevel@tonic-gate 
7037c478bd9Sstevel@tonic-gate 	free(pref_addr);
7047c478bd9Sstevel@tonic-gate 	data.h_name = strdup(ecol[0].ec_value.ec_value_val);
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate 	/*
7077c478bd9Sstevel@tonic-gate 	 * name (col 1)
7087c478bd9Sstevel@tonic-gate 	 */
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate 	data.h_aliases = NULL;
7117c478bd9Sstevel@tonic-gate 
7127c478bd9Sstevel@tonic-gate 	do {
7137c478bd9Sstevel@tonic-gate 		/*
7147c478bd9Sstevel@tonic-gate 		 * don't clobber comment in canonical entry
7157c478bd9Sstevel@tonic-gate 		 */
7167c478bd9Sstevel@tonic-gate 
7177c478bd9Sstevel@tonic-gate 		/* This call to AddEntry may move out of the loop */
7187c478bd9Sstevel@tonic-gate 		/* This is because we have to call the function just once */
7197c478bd9Sstevel@tonic-gate 		if (t != cname && strcasecmp(t, cname) == 0)
7207c478bd9Sstevel@tonic-gate 			continue;
7217c478bd9Sstevel@tonic-gate 		if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
7227c478bd9Sstevel@tonic-gate 			continue;
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_val = t;
7257c478bd9Sstevel@tonic-gate 		ecol[1].ec_value.ec_value_len = strlen(t)+1;
7267c478bd9Sstevel@tonic-gate 
7277c478bd9Sstevel@tonic-gate 		ctr++;
7287c478bd9Sstevel@tonic-gate 		alias = strdup(ecol[1].ec_value.ec_value_val);
7297c478bd9Sstevel@tonic-gate 		if ((data.h_aliases = (char **)realloc(data.h_aliases,
730e1dd0a2fSth 		    ctr * sizeof (char **))) == NULL) {
7317c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("out of memory\n"));
7327c478bd9Sstevel@tonic-gate 			exit(1);
7337c478bd9Sstevel@tonic-gate 		}
7347c478bd9Sstevel@tonic-gate 		data.h_aliases[ctr-1] = alias;
7357c478bd9Sstevel@tonic-gate 	} while (t = strtok(NULL, " \t"));
7367c478bd9Sstevel@tonic-gate 
7376d3c3c6aSiz 	/*
7386d3c3c6aSiz 	 * End the list of all the aliases by NULL
7396d3c3c6aSiz 	 * If there is some comment, it will be stored as the last entry
7406d3c3c6aSiz 	 * in the list of the host aliases
7416d3c3c6aSiz 	 */
7427c478bd9Sstevel@tonic-gate 	if ((data.h_aliases = (char **)realloc(data.h_aliases,
743e1dd0a2fSth 	    (ecol[3].ec_value.ec_value_len != 0 ?
744e1dd0a2fSth 	    ctr + 2 : ctr + 1) * sizeof (char **))) == NULL) {
7457c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("out of memory\n"));
7467c478bd9Sstevel@tonic-gate 		exit(1);
7477c478bd9Sstevel@tonic-gate 	}
7486d3c3c6aSiz 
7496d3c3c6aSiz 	if (ecol[3].ec_value.ec_value_len != 0) {
7506d3c3c6aSiz 		data.h_aliases[ctr++] = ecol[3].ec_value.ec_value_val;
7516d3c3c6aSiz 	}
7527c478bd9Sstevel@tonic-gate 	data.h_aliases[ctr] = NULL;
7537c478bd9Sstevel@tonic-gate 
7547c478bd9Sstevel@tonic-gate 	if (flags & F_VERBOSE)
7557c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
7567c478bd9Sstevel@tonic-gate 		    gettext("Adding entry : cn=%s+ipHostNumber=%s\n"),
7577c478bd9Sstevel@tonic-gate 		    data.h_name, data.h_addr_list[0]);
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate 	retval = (*cback)(&data, 0);
7607c478bd9Sstevel@tonic-gate 
7616d3c3c6aSiz 	if (ecol[3].ec_value.ec_value_len != 0) {
7626d3c3c6aSiz 		free(ecol[3].ec_value.ec_value_val);
7636d3c3c6aSiz 	}
7646d3c3c6aSiz 
7657c478bd9Sstevel@tonic-gate 	if (retval == LDAP_ALREADY_EXISTS) {
7667c478bd9Sstevel@tonic-gate 		if (continue_onerror)
7677c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
768e1dd0a2fSth 			    gettext("Entry: cn=%s+ipHostNumber=%s "
769e1dd0a2fSth 			    "already Exists -skipping it\n"),
770e1dd0a2fSth 			    data.h_name, data.h_addr_list[0]);
7717c478bd9Sstevel@tonic-gate 		else {
7727c478bd9Sstevel@tonic-gate 			rc = GENENT_CBERR;
7737c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
774e1dd0a2fSth 			    gettext("Entry: cn=%s+ipHostNumber=%s"
775e1dd0a2fSth 			    " already Exists\n"),
776e1dd0a2fSth 			    data.h_name, data.h_addr_list[0]);
7777c478bd9Sstevel@tonic-gate 		}
7787c478bd9Sstevel@tonic-gate 	} else if (retval)
7797c478bd9Sstevel@tonic-gate 		rc = GENENT_CBERR;
7807c478bd9Sstevel@tonic-gate 
7817c478bd9Sstevel@tonic-gate 	free(data.h_name);
7827c478bd9Sstevel@tonic-gate 	free(data.h_aliases);
7837c478bd9Sstevel@tonic-gate 	free(data.h_addr_list);
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate 	return (rc);
7867c478bd9Sstevel@tonic-gate }
7877c478bd9Sstevel@tonic-gate 
7887c478bd9Sstevel@tonic-gate 
7897c478bd9Sstevel@tonic-gate 
7907c478bd9Sstevel@tonic-gate static void
dump_hosts(ns_ldap_result_t * res)7917c478bd9Sstevel@tonic-gate dump_hosts(ns_ldap_result_t *res)
7927c478bd9Sstevel@tonic-gate {
7936d3c3c6aSiz 	ns_ldap_attr_t	*attrptr = NULL,
794e1dd0a2fSth 	    *cn = NULL,
795e1dd0a2fSth 	    *iphostnumber = NULL,
796e1dd0a2fSth 	    *desc = NULL;
7977c478bd9Sstevel@tonic-gate 	int		 i, j;
7987c478bd9Sstevel@tonic-gate 	char		*name; /* host name */
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate 	if (res == NULL || res->entry == NULL)
8017c478bd9Sstevel@tonic-gate 		return;
8027c478bd9Sstevel@tonic-gate 	for (i = 0; i < res->entry->attr_count; i++) {
8037c478bd9Sstevel@tonic-gate 		attrptr = res->entry->attr_pair[i];
8047c478bd9Sstevel@tonic-gate 		if (strcasecmp(attrptr->attrname, "cn") == 0)
8057c478bd9Sstevel@tonic-gate 			cn = attrptr;
8067c478bd9Sstevel@tonic-gate 		else if (strcasecmp(attrptr->attrname, "iphostnumber") == 0)
8077c478bd9Sstevel@tonic-gate 			iphostnumber = attrptr;
8086d3c3c6aSiz 		else if (strcasecmp(attrptr->attrname, "description") == 0) {
8096d3c3c6aSiz 			desc = attrptr;
8106d3c3c6aSiz 		}
8117c478bd9Sstevel@tonic-gate 	}
8127c478bd9Sstevel@tonic-gate 	/* sanity check */
8137c478bd9Sstevel@tonic-gate 	if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
8147c478bd9Sstevel@tonic-gate 	    iphostnumber == NULL || iphostnumber->attrvalue == NULL ||
8157c478bd9Sstevel@tonic-gate 	    iphostnumber->attrvalue[0] == NULL)
8167c478bd9Sstevel@tonic-gate 		return;
8177c478bd9Sstevel@tonic-gate 
8187c478bd9Sstevel@tonic-gate 	if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
8197c478bd9Sstevel@tonic-gate 		return;
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate 	/* ip host/ipnode number */
8227c478bd9Sstevel@tonic-gate 	if (strlen(iphostnumber->attrvalue[0]) <= INET_ADDRSTRLEN)
8237c478bd9Sstevel@tonic-gate 		/* IPV4 or IPV6 but <= NET_ADDRSTRLEN */
8247c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout, "%-18s", iphostnumber->attrvalue[0]);
8257c478bd9Sstevel@tonic-gate 	else
8267c478bd9Sstevel@tonic-gate 		/* IPV6 */
8277c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout, "%-48s", iphostnumber->attrvalue[0]);
8287c478bd9Sstevel@tonic-gate 
8297c478bd9Sstevel@tonic-gate 	/* host/ipnode name */
8307c478bd9Sstevel@tonic-gate 	(void) fprintf(stdout, "%s ", name);
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate 	/* aliases */
8337c478bd9Sstevel@tonic-gate 	for (j = 0; j < cn->value_count; j++) {
8347c478bd9Sstevel@tonic-gate 		if (cn->attrvalue[j]) {
8357c478bd9Sstevel@tonic-gate 			if (strcasecmp(name, cn->attrvalue[j]) == 0)
8367c478bd9Sstevel@tonic-gate 				/* skip host name */
8377c478bd9Sstevel@tonic-gate 				continue;
8387c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout, "%s ", cn->attrvalue[j]);
8397c478bd9Sstevel@tonic-gate 		}
8407c478bd9Sstevel@tonic-gate 	}
8417c478bd9Sstevel@tonic-gate 
8426d3c3c6aSiz 	/* description */
8436d3c3c6aSiz 	if (desc != NULL && desc->attrvalue != NULL &&
8446d3c3c6aSiz 	    desc->attrvalue[0] != NULL) {
8456d3c3c6aSiz 		(void) fprintf(stdout, "#%s", desc->attrvalue[0]);
8466d3c3c6aSiz 	}
8476d3c3c6aSiz 
8487c478bd9Sstevel@tonic-gate 	/* end of line */
8497c478bd9Sstevel@tonic-gate 	(void) fprintf(stdout, "\n");
8507c478bd9Sstevel@tonic-gate }
8517c478bd9Sstevel@tonic-gate 
8527c478bd9Sstevel@tonic-gate /*
8537c478bd9Sstevel@tonic-gate  * /etc/rpc
8547c478bd9Sstevel@tonic-gate  */
8557c478bd9Sstevel@tonic-gate 
8567c478bd9Sstevel@tonic-gate static int
genent_rpc(char * line,int (* cback)())8577c478bd9Sstevel@tonic-gate genent_rpc(char *line, int (*cback)())
8587c478bd9Sstevel@tonic-gate {
8597c478bd9Sstevel@tonic-gate 	char buf[BUFSIZ+1];
8607c478bd9Sstevel@tonic-gate 	char *t;
8617c478bd9Sstevel@tonic-gate 	entry_col ecol[4];
8627c478bd9Sstevel@tonic-gate 	char *cname;
8637c478bd9Sstevel@tonic-gate 
8647c478bd9Sstevel@tonic-gate 	struct rpcent	data;
8657c478bd9Sstevel@tonic-gate 	char *alias;
8667c478bd9Sstevel@tonic-gate 	int ctr = 0;
8677c478bd9Sstevel@tonic-gate 	int retval = 1;
8687c478bd9Sstevel@tonic-gate 	int rc = GENENT_OK;
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate 	/*
8717c478bd9Sstevel@tonic-gate 	 * don't clobber our argument
8727c478bd9Sstevel@tonic-gate 	 */
8737c478bd9Sstevel@tonic-gate 	if (strlen(line) >= sizeof (buf)) {
874e1dd0a2fSth 		(void) strlcpy(parse_err_msg, gettext("line too long"),
875e1dd0a2fSth 		    PARSE_ERR_MSG_LEN);
8767c478bd9Sstevel@tonic-gate 		return (GENENT_PARSEERR);
8777c478bd9Sstevel@tonic-gate 	}
8787c478bd9Sstevel@tonic-gate 	(void) strcpy(buf, line);
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate 	/*
8817c478bd9Sstevel@tonic-gate 	 * clear column data
8827c478bd9Sstevel@tonic-gate 	 */
8837c478bd9Sstevel@tonic-gate 	(void) memset((char *)ecol, 0, sizeof (ecol));
8847c478bd9Sstevel@tonic-gate 
8857c478bd9Sstevel@tonic-gate 	/*
8867c478bd9Sstevel@tonic-gate 	 * comment (col 3)
8877c478bd9Sstevel@tonic-gate 	 */
8887c478bd9Sstevel@tonic-gate 	t = strchr(buf, '#');
8897c478bd9Sstevel@tonic-gate 	if (t) {
8907c478bd9Sstevel@tonic-gate 		*t++ = 0;
8917c478bd9Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = t;
8927c478bd9Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = strlen(t)+1;
8937c478bd9Sstevel@tonic-gate 	} else {
8947c478bd9Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_val = 0;
8957c478bd9Sstevel@tonic-gate 		ecol[3].ec_value.ec_value_len = 0;
8967c478bd9Sstevel@tonic-gate 	}
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate 	/*
8997c478bd9Sstevel@tonic-gate 	 * cname(col 0)
9007c478bd9Sstevel@tonic-gate 	 */
9017c478bd9Sstevel@tonic-gate 	if ((t = strtok(buf, " \t")) == 0) {
902e1dd0a2fSth 		(void) strlcpy(parse_err_msg, gettext("no number"),
903e1dd0a2fSth 		    PARSE_ERR_MSG_LEN);
9047c478bd9Sstevel@tonic-gate 		return (GENENT_PARSEERR);
9057c478bd9Sstevel@tonic-gate 	}
9067c478bd9Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_val = t;
9077c478bd9Sstevel@tonic-gate 	ecol[0].ec_value.ec_value_len = strlen(t)+1;
9087c478bd9Sstevel@tonic-gate 	cname = t;
9097c478bd9Sstevel@tonic-gate 
9107c478bd9Sstevel@tonic-gate 	/*
9117c478bd9Sstevel@tonic-gate 	 * number (col 2)
9127c478bd9Sstevel@tonic-gate 	 */
9137c478bd9Sstevel@tonic-gate 	if ((t = strtok(NULL, " \t")) == 0) {
914e1dd0a2fSth 		(void) strlcpy(parse_err_msg, gettext("no number"),
915e1dd0a2fSth 		    PARSE_ERR_MSG_LEN);
9167c478bd9Sstevel@tonic-gate 		return (GENENT_PARSEERR);
9177c478bd9Sstevel@tonic-gate 	}
9187c478bd9Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_val = t;
9197c478bd9Sstevel@tonic-gate 	ecol[2].ec_value.ec_value_len = strlen(t)+1;
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate 	/*
9237c478bd9Sstevel@tonic-gate 	 * build entry
9247c478bd9Sstevel@tonic-gate 	 */
9257c478bd9Sstevel@tonic-gate 
9267c478bd9Sstevel@tonic-gate 	data.r_name = strdup(ecol[0].ec_value.ec_value_val);
9277c478bd9Sstevel@tonic-gate 	if (ecol[2].ec_value.ec_value_val != NULL &&
928e1dd0a2fSth 	    ecol[2].ec_value.ec_value_val[0] != '\0') {
9297c478bd9Sstevel@tonic-gate 
9307c478bd9Sstevel@tonic-gate 		data.r_number = ascii_to_int(ecol[2].ec_value.ec_value_val);
9317c478bd9Sstevel@tonic-gate 		if (data.r_number == -1) {
9327c478bd9Sstevel@tonic-gate 			(void) snprintf(parse_err_msg, sizeof (parse_err_msg),
933e1dd0a2fSth 			    gettext("invalid program number: %s"),
9347c478bd9Sstevel@tonic-gate 			    ecol[2].ec_value.ec_value_val);
9357c478bd9Sstevel@tonic-gate 		return (GENENT_PARSEERR);
9367c478bd9Sstevel@tonic-gate 		}
9377c478bd9Sstevel@tonic-gate 	} else
9387c478bd9Sstevel@tonic-gate 		data.r_number = -1;
9397c478bd9Sstevel@tonic-gate 
9407c478bd9Sstevel@tonic-gate 	/*
9417c478bd9Sstevel@tonic-gate 	 * name (col 1)
9427c478bd9Sstevel@tonic-gate 	 */
9437c478bd9Sstevel@tonic-gate 	t = cname;
9447c478bd9Sstevel@tonic-gate 	data.r_aliases = NULL;
9457c478bd9Sstevel@tonic-gate 	do {
9467c478bd9Sstevel@tonic-gate 
947