xref: /onnv-gate/usr/src/cmd/ldap/ns_ldap/ldaplist.c (revision 12758:996c46be076f)
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
51450Sjanga  * Common Development and Distribution License (the "License").
61450Sjanga  * 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*12758SJulian.Pullen@Sun.COM  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate  */
240Sstevel@tonic-gate 
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <stdio.h>
270Sstevel@tonic-gate #include <stdlib.h>
280Sstevel@tonic-gate #include <libintl.h>
290Sstevel@tonic-gate #include <strings.h>
300Sstevel@tonic-gate #include <locale.h>
310Sstevel@tonic-gate #include <syslog.h>
326842Sth160488 
336842Sth160488 #include "standalone.h"
340Sstevel@tonic-gate 
350Sstevel@tonic-gate extern char *set_filter(char **, char *, char **);
360Sstevel@tonic-gate extern char *set_filter_publickey(char **, char *, int, char **);
370Sstevel@tonic-gate extern void _printResult(ns_ldap_result_t *);
381450Sjanga extern void printMapping();
390Sstevel@tonic-gate 
400Sstevel@tonic-gate int listflag = 0;
410Sstevel@tonic-gate 
42*12758SJulian.Pullen@Sun.COM 
43*12758SJulian.Pullen@Sun.COM 
44*12758SJulian.Pullen@Sun.COM static struct database_t {
45*12758SJulian.Pullen@Sun.COM 	const char *database;
46*12758SJulian.Pullen@Sun.COM 	const char *sortattr;
47*12758SJulian.Pullen@Sun.COM }databaselist[] = {
48*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_HOSTS, "cn" },
49*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_IPNODES, "cn" },
50*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_RPC, "cn" },
51*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_PROTOCOLS, "cn" },
52*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_NETWORKS, "ipnetworknumber" },
53*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_SERVICES, "cn" },
54*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_GROUP, "gidnumber" },
55*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_NETMASKS, "ipnetworknumber"},
56*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_ETHERS, "cn" },
57*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_NETGROUP, "cn" },
58*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_BOOTPARAMS, "cn" },
59*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_PUBLICKEY, "cn" },
60*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_PASSWD, "uid" },
61*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_SHADOW, "uid" },
62*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_ALIASES, "cn" },
63*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_AUTOMOUNT, "automountKey" },
64*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_USERATTR, "uid" },
65*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_PROFILE, "cn" },
66*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_EXECATTR, "cn" },
67*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_AUTHATTR, "cn" },
68*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_AUUSER, "uid" },
69*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_TNRHDB, "ipTnetNumber" },
70*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_TNRHTP, "ipTnetTemplateName" },
71*12758SJulian.Pullen@Sun.COM 	{ NS_LDAP_TYPE_PROJECT, "SolarisProjectName" },
72*12758SJulian.Pullen@Sun.COM 	{ 0, 0 }
73*12758SJulian.Pullen@Sun.COM };
74*12758SJulian.Pullen@Sun.COM 
75*12758SJulian.Pullen@Sun.COM 
760Sstevel@tonic-gate void
usage(char * msg)770Sstevel@tonic-gate usage(char *msg) {
780Sstevel@tonic-gate 	if (msg)
791450Sjanga 		(void) fprintf(stderr, "%s\n", msg);
800Sstevel@tonic-gate 
811450Sjanga 	(void) fprintf(stderr,
820Sstevel@tonic-gate 	gettext(
836842Sth160488 	"\n"
846842Sth160488 	"usage: ldaplist [-dlv] [-h LDAP_server[:serverPort] [-M domainName]\n"
856842Sth160488 	"[-N  profileName] [-a  authenticationMethod] [-P certifPath]\n"
866842Sth160488 	"[-D  bindDN] [-w bindPassword] [-j passwdFile]]\n"
876842Sth160488 	"[<database> [<key>] ...]\n\n"
886842Sth160488 	"usage: ldaplist -h\n"
896842Sth160488 	"\n"
906842Sth160488 	"usage: ldaplist -g\n\n"
910Sstevel@tonic-gate 	"\tOptions:\n"
920Sstevel@tonic-gate 	"\t    -l list all the attributes found in entry.\n"
930Sstevel@tonic-gate 	"\t       By default, it lists only the DNs.\n"
940Sstevel@tonic-gate 	"\t    -d list attributes for the database instead of its entries\n"
950Sstevel@tonic-gate 	"\t    -v print out the LDAP search filter.\n"
966842Sth160488 	"\t    -g list the database mappings.\n"
976842Sth160488 	"\t    -h An address (or a name) and a port of the LDAP server in\n"
986842Sth160488 	"\t       which the entries will be stored. The default value for\n"
996842Sth160488 	"\t       the port is 389 (or 636 for TLS connections).\n"
1006842Sth160488 	"\t    -M The name of a domain served by the specified server.\n"
1016842Sth160488 	"\t       If not specified, the default domain name will be used.\n"
1026842Sth160488 	"\t    -N Specifies a DUAProfile name.\n"
1036842Sth160488 	"\t       The default value is \"default\".\n"
1046842Sth160488 	"\t    -a Specifies an authentication method.\n"
1056842Sth160488 	"\t    -P The certificate path for the location of the certificate\n"
1066842Sth160488 	"\t       database.\n"
1076842Sth160488 	"\t    -D Specifies an entry which has read permission to\n"
1086842Sth160488 	"\t       the requested database.\n"
1096842Sth160488 	"\t    -w Password to be used for authenticating the bindDN.\n"
1106842Sth160488 	"\t    -j File containing the password for bindDN or SSL key db.\n"
1110Sstevel@tonic-gate 	"\t<database> is the database to be searched in.  Standard system\n"
1120Sstevel@tonic-gate 	"\tdatabases are:\n"
1130Sstevel@tonic-gate 	"\t\tpassword, printers, group, hosts, ethers, networks, netmasks,\n"
1140Sstevel@tonic-gate 	"\t\trpc, bootparams, protocols, services, netgroup, auto_*.\n"
1150Sstevel@tonic-gate 	"\tNon-standard system databases can be specified as follows:\n"
1160Sstevel@tonic-gate 	"\t\tby specific container: ou=<dbname> or\n"
1170Sstevel@tonic-gate 	"\t\tby default container: <dbname>.  In this case, 'nismapname'\n"
1180Sstevel@tonic-gate 	"\t\twill be used, thus mapping this to nismapname=<dbname>.\n"
1190Sstevel@tonic-gate 	"\t<key> is the key to search in the database.  For the standard\n"
1200Sstevel@tonic-gate 	"\tdatabases, the search type for the key is predefined.  You can\n"
1216842Sth160488 	"\toverride this by specifying <type>=<key>.\n"
1226842Sth160488 	"\nNOTE: The old -h option printing the mapping information is "
1236842Sth160488 	"deprecated.\nFor backward compatibility the following mode is "
1246842Sth160488 	"available:\nldaplist -h\n"));
1250Sstevel@tonic-gate 	exit(1);
1260Sstevel@tonic-gate }
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate /*
1290Sstevel@tonic-gate  * This is a generic filter call back function for
1300Sstevel@tonic-gate  * merging the filter from service search descriptor with
1310Sstevel@tonic-gate  * an existing search filter. This routine expects userdata
1320Sstevel@tonic-gate  * contain a format string with a single %s in it, and will
1330Sstevel@tonic-gate  * use the format string with sprintf() to insert the SSD filter.
1340Sstevel@tonic-gate  *
1350Sstevel@tonic-gate  * This routine is passed to the __ns_ldap_list() or
1360Sstevel@tonic-gate  * __ns_ldap_firstEntry() APIs as the filter call back
1370Sstevel@tonic-gate  * together with the userdata. For example,
1380Sstevel@tonic-gate  * the "ldaplist hosts sys1" processing may call __ns_ldap_list()
1390Sstevel@tonic-gate  * with "(&(objectClass=ipHost)(cn=sys1))" as filter, this function
1400Sstevel@tonic-gate  * as the filter call back, and "(&(%s)(cn=sys1))" as the
1410Sstevel@tonic-gate  * userdata, this routine will in turn gets call to produce
1420Sstevel@tonic-gate  * "(&(department=sds)(cn=sys1))" as the real search
1430Sstevel@tonic-gate  * filter, if the input SSD contains a filter "department=sds".
1440Sstevel@tonic-gate  */
1450Sstevel@tonic-gate static int
merge_SSD_filter(const ns_ldap_search_desc_t * desc,char ** realfilter,const void * userdata)1460Sstevel@tonic-gate merge_SSD_filter(const ns_ldap_search_desc_t *desc,
1470Sstevel@tonic-gate 			char **realfilter,
1480Sstevel@tonic-gate 			const void *userdata)
1490Sstevel@tonic-gate {
1500Sstevel@tonic-gate 	int	len;
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate 	/* sanity check */
1530Sstevel@tonic-gate 	if (realfilter == NULL)
1540Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
1550Sstevel@tonic-gate 	*realfilter = NULL;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	if (desc == NULL || desc->filter == NULL ||
1586842Sth160488 	    userdata == NULL)
1590Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate 	len = strlen(userdata) + strlen(desc->filter) + 1;
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 	*realfilter = (char *)malloc(len);
1640Sstevel@tonic-gate 	if (*realfilter == NULL)
1650Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate 	(void) sprintf(*realfilter, (char *)userdata,
1686842Sth160488 	    desc->filter);
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
1710Sstevel@tonic-gate }
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate /* returns 0=success, 1=error */
1740Sstevel@tonic-gate int
list(char * database,char * ldapfilter,char ** ldapattribute,char ** err,char * userdata)1750Sstevel@tonic-gate list(char *database, char *ldapfilter, char **ldapattribute,
1760Sstevel@tonic-gate char **err, char *userdata)
1770Sstevel@tonic-gate {
1780Sstevel@tonic-gate 	ns_ldap_result_t	*result;
1790Sstevel@tonic-gate 	ns_ldap_error_t	*errorp;
1800Sstevel@tonic-gate 	int		rc;
1810Sstevel@tonic-gate 	char		buf[500];
182*12758SJulian.Pullen@Sun.COM 	const char 	*sort = NULL;
183*12758SJulian.Pullen@Sun.COM 	int		i;
184*12758SJulian.Pullen@Sun.COM 
185*12758SJulian.Pullen@Sun.COM 	if (database) {
186*12758SJulian.Pullen@Sun.COM 		for (i = 0; databaselist[i].database; i++) {
187*12758SJulian.Pullen@Sun.COM 			if (strcmp(databaselist[i].database, database) == 0) {
188*12758SJulian.Pullen@Sun.COM 				sort = databaselist[i].sortattr;
189*12758SJulian.Pullen@Sun.COM 				break;
190*12758SJulian.Pullen@Sun.COM 			}
191*12758SJulian.Pullen@Sun.COM 			if (strcmp(databaselist[i].database,
192*12758SJulian.Pullen@Sun.COM 			    NS_LDAP_TYPE_AUTOMOUNT) == 0 &&
193*12758SJulian.Pullen@Sun.COM 			    strncmp(database, NS_LDAP_TYPE_AUTOMOUNT,
194*12758SJulian.Pullen@Sun.COM 			    sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0) {
195*12758SJulian.Pullen@Sun.COM 				sort = databaselist[i].sortattr;
196*12758SJulian.Pullen@Sun.COM 				break;
197*12758SJulian.Pullen@Sun.COM 			}
198*12758SJulian.Pullen@Sun.COM 		}
199*12758SJulian.Pullen@Sun.COM 	}
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	*err = NULL;
2020Sstevel@tonic-gate 	buf[0] = '\0';
203*12758SJulian.Pullen@Sun.COM 	rc = __ns_ldap_list_sort(database, (const char *)ldapfilter,
204*12758SJulian.Pullen@Sun.COM 	    sort, merge_SSD_filter, (const char **)ldapattribute, NULL,
2056842Sth160488 	    listflag, &result, &errorp, NULL, userdata);
2060Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS) {
2070Sstevel@tonic-gate 		char *p;
2080Sstevel@tonic-gate 		(void) __ns_ldap_err2str(rc, &p);
2090Sstevel@tonic-gate 		if (errorp && errorp->message) {
2101450Sjanga 			(void) snprintf(buf, sizeof (buf), "%s (%s)",
2116842Sth160488 			    p, errorp->message);
2121450Sjanga 			(void) __ns_ldap_freeError(&errorp);
2130Sstevel@tonic-gate 		} else
2146842Sth160488 			(void) snprintf(buf, sizeof (buf), "%s\n", p);
2150Sstevel@tonic-gate 		*err = strdup(buf);
2160Sstevel@tonic-gate 		return (rc);
2170Sstevel@tonic-gate 	}
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate 	_printResult(result);
2201450Sjanga 	(void) __ns_ldap_freeResult(&result);
2210Sstevel@tonic-gate 	return (0);
2220Sstevel@tonic-gate }
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate int
switch_err(int rc)2260Sstevel@tonic-gate switch_err(int rc)
2270Sstevel@tonic-gate {
2280Sstevel@tonic-gate 	switch (rc) {
2290Sstevel@tonic-gate 	case NS_LDAP_SUCCESS:
2300Sstevel@tonic-gate 		return (0);
2310Sstevel@tonic-gate 	case NS_LDAP_NOTFOUND:
2320Sstevel@tonic-gate 		return (1);
2330Sstevel@tonic-gate 	}
2340Sstevel@tonic-gate 	return (2);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate 
237702Sth160488 int
main(int argc,char ** argv)2380Sstevel@tonic-gate main(int argc, char **argv)
2390Sstevel@tonic-gate {
2400Sstevel@tonic-gate 
2416842Sth160488 	extern int		optind;
2426842Sth160488 	char			*database = NULL;
2436842Sth160488 	char			*ldapfilter = NULL;
2446842Sth160488 	char			*attribute = "dn";
2456842Sth160488 	char			**key = NULL;
2466842Sth160488 	char			**ldapattribute = NULL;
2476842Sth160488 	char 			*buffer[100];
2486842Sth160488 	char			*err = NULL;
2496842Sth160488 	char			*p;
2506842Sth160488 	int			index = 1;
2516842Sth160488 	int			c;
2526842Sth160488 	int			rc;
2536842Sth160488 	int			verbose = 0;
2546842Sth160488 	char			*udata = NULL;
2556842Sth160488 
2566842Sth160488 	ns_standalone_conf_t	standalone_cfg = standaloneDefaults;
2576842Sth160488 	ns_ldap_error_t		*errorp = NULL;
2586842Sth160488 	char			*authmech = NULL;
2596842Sth160488 	ns_auth_t		auth = {NS_LDAP_AUTH_NONE,
2606842Sth160488 					NS_LDAP_TLS_NONE,
2616842Sth160488 					NS_LDAP_SASL_NONE,
2626842Sth160488 					NS_LDAP_SASLOPT_NONE};
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
2650Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
2660Sstevel@tonic-gate 
2670Sstevel@tonic-gate 	openlog("ldaplist", LOG_PID, LOG_USER);
2680Sstevel@tonic-gate 
2696842Sth160488 	if (argc == 2 &&
2706842Sth160488 	    strlen(argv[1]) == 2 && strncmp(argv[1], "-h", 2) == 0) {
2716842Sth160488 		/* preserve backwards compatability, support old -h option */
2726842Sth160488 		(void) printMapping();
2736842Sth160488 		exit(0);
2746842Sth160488 	}
2756842Sth160488 
2766842Sth160488 	while ((c = getopt(argc, argv, "h:M:N:P:r:a:D:w:j:dgvl")) != EOF) {
2770Sstevel@tonic-gate 		switch (c) {
2780Sstevel@tonic-gate 		case 'd':
2790Sstevel@tonic-gate 			listflag |= NS_LDAP_SCOPE_BASE;
2800Sstevel@tonic-gate 			break;
2816842Sth160488 		case 'g':
2820Sstevel@tonic-gate 			(void) printMapping();
2830Sstevel@tonic-gate 			exit(0);
2841450Sjanga 			break; /* Never reached */
2850Sstevel@tonic-gate 		case 'l':
2860Sstevel@tonic-gate 			attribute = "NULL";
2870Sstevel@tonic-gate 			break;
2880Sstevel@tonic-gate 		case 'v':
2890Sstevel@tonic-gate 			verbose = 1;
2900Sstevel@tonic-gate 			break;
2916842Sth160488 		case 'M':
2926842Sth160488 			standalone_cfg.type = NS_LDAP_SERVER;
2936842Sth160488 			standalone_cfg.SA_DOMAIN = optarg;
2946842Sth160488 			break;
2956842Sth160488 		case 'h':
2966842Sth160488 			standalone_cfg.type = NS_LDAP_SERVER;
2976842Sth160488 			if (separatePort(optarg,
2986842Sth160488 			    &standalone_cfg.SA_SERVER,
2996842Sth160488 			    &standalone_cfg.SA_PORT) > 0) {
3006842Sth160488 				exit(1);
3016842Sth160488 			}
3026842Sth160488 			break;
3036842Sth160488 		case 'P':
3046842Sth160488 			standalone_cfg.type = NS_LDAP_SERVER;
3056842Sth160488 			standalone_cfg.SA_CERT_PATH = optarg;
3066842Sth160488 			break;
3076842Sth160488 		case 'N':
3086842Sth160488 			standalone_cfg.type = NS_LDAP_SERVER;
3096842Sth160488 			standalone_cfg.SA_PROFILE_NAME = optarg;
3106842Sth160488 			break;
3116842Sth160488 		case 'D':
3126842Sth160488 			standalone_cfg.type = NS_LDAP_SERVER;
3136842Sth160488 			standalone_cfg.SA_BIND_DN = strdup(optarg);
3146842Sth160488 			break;
3156842Sth160488 		case 'w':
3166842Sth160488 			if (standalone_cfg.SA_BIND_PWD != NULL) {
3176842Sth160488 				(void) fprintf(stderr,
3186842Sth160488 				    gettext("The -w option is mutually "
3196842Sth160488 				    "exclusive of -j. -w is ignored.\n"));
3206842Sth160488 				break;
3216842Sth160488 			}
3226842Sth160488 
3236842Sth160488 			if (optarg != NULL &&
3246842Sth160488 			    optarg[0] == '-' && optarg[1] == '\0') {
3256842Sth160488 				/* Ask for a password later */
3266842Sth160488 				break;
3276842Sth160488 			}
3286842Sth160488 
3296842Sth160488 			standalone_cfg.type = NS_LDAP_SERVER;
3306842Sth160488 			standalone_cfg.SA_BIND_PWD = strdup(optarg);
3316842Sth160488 			break;
3326842Sth160488 		case 'j':
3336842Sth160488 			if (standalone_cfg.SA_BIND_PWD != NULL) {
3346842Sth160488 				(void) fprintf(stderr,
3356842Sth160488 				    gettext("The -w option is mutually "
3366842Sth160488 				    "exclusive of -j. -w is ignored.\n"));
3376842Sth160488 				free(standalone_cfg.SA_BIND_PWD);
3386842Sth160488 			}
3396842Sth160488 			standalone_cfg.type = NS_LDAP_SERVER;
3406842Sth160488 			standalone_cfg.SA_BIND_PWD = readPwd(optarg);
3416842Sth160488 			if (standalone_cfg.SA_BIND_PWD == NULL) {
3426842Sth160488 				exit(1);
3436842Sth160488 			}
3446842Sth160488 			break;
3456842Sth160488 		case 'a':
3466842Sth160488 			authmech = optarg;
3476842Sth160488 			break;
3480Sstevel@tonic-gate 		default:
3490Sstevel@tonic-gate 			usage(gettext("Invalid option"));
3500Sstevel@tonic-gate 		}
3510Sstevel@tonic-gate 	}
3526842Sth160488 
3536842Sth160488 	if (standalone_cfg.type == NS_LDAP_SERVER &&
3546842Sth160488 	    standalone_cfg.SA_SERVER == NULL) {
3556842Sth160488 		(void) fprintf(stderr,
3566842Sth160488 		    gettext("Please specify an LDAP server you want "
3576842Sth160488 		    "to connect to. \n"));
3586842Sth160488 		exit(1);
3596842Sth160488 	}
3606842Sth160488 
3610Sstevel@tonic-gate 	if ((c = argc - optind) > 0)
3620Sstevel@tonic-gate 		database = argv[optind++];
3630Sstevel@tonic-gate 	if ((--c) > 0)
3640Sstevel@tonic-gate 		key = &argv[optind];
3650Sstevel@tonic-gate 
3666842Sth160488 	if (authmech != NULL) {
3676842Sth160488 		if (__ns_ldap_initAuth(authmech,
3686842Sth160488 		    &auth,
3696842Sth160488 		    &errorp) != NS_LDAP_SUCCESS) {
3706842Sth160488 			if (errorp) {
3716842Sth160488 				(void) fprintf(stderr, "%s", errorp->message);
3726842Sth160488 				(void) __ns_ldap_freeError(&errorp);
3736842Sth160488 			}
3746842Sth160488 			exit(1);
3756842Sth160488 		}
3766842Sth160488 	}
3776842Sth160488 
3786842Sth160488 	if (auth.saslmech != NS_LDAP_SASL_GSSAPI &&
3796842Sth160488 	    standalone_cfg.SA_BIND_DN != NULL &&
3806842Sth160488 	    standalone_cfg.SA_BIND_PWD == NULL) {
3816842Sth160488 		/* If password is not specified, then prompt user for it. */
3826842Sth160488 		standalone_cfg.SA_BIND_PWD =
3836842Sth160488 		    strdup(getpassphrase("Enter password:"));
3846842Sth160488 	}
3856842Sth160488 
3866842Sth160488 	standalone_cfg.SA_AUTH = (authmech == NULL) ? NULL : &auth;
3876842Sth160488 
3886842Sth160488 	if (__ns_ldap_initStandalone(&standalone_cfg,
3896842Sth160488 	    &errorp) != NS_LDAP_SUCCESS) {
3906842Sth160488 		if (errorp) {
3916842Sth160488 			(void) fprintf(stderr, "%s\n", errorp->message);
3926842Sth160488 			(void) __ns_ldap_freeError(&errorp);
3936842Sth160488 		}
3946842Sth160488 		exit(1);
3956842Sth160488 	}
3966842Sth160488 
3976842Sth160488 	if (authmech != NULL) {
3986842Sth160488 		if (__ns_ldap_setParam(NS_LDAP_AUTH_P,
3996842Sth160488 		    authmech, &errorp) != NS_LDAP_SUCCESS) {
4006842Sth160488 			__ns_ldap_cancelStandalone();
4016842Sth160488 			if (errorp != NULL) {
4026842Sth160488 				(void) fprintf(stderr, "%s", errorp->message);
4036842Sth160488 				(void) __ns_ldap_freeError(&errorp);
4046842Sth160488 			}
4056842Sth160488 			exit(1);
4066842Sth160488 		}
4076842Sth160488 	}
4086842Sth160488 	if (standalone_cfg.SA_CRED != NULL) {
4096842Sth160488 		if (__ns_ldap_setParam(NS_LDAP_CREDENTIAL_LEVEL_P,
4106842Sth160488 		    standalone_cfg.SA_CRED, &errorp) != NS_LDAP_SUCCESS) {
4116842Sth160488 			__ns_ldap_cancelStandalone();
4126842Sth160488 			if (errorp != NULL) {
4136842Sth160488 				(void) fprintf(stderr, "%s", errorp->message);
4146842Sth160488 				(void) __ns_ldap_freeError(&errorp);
4156842Sth160488 			}
4166842Sth160488 			exit(1);
4176842Sth160488 		}
4186842Sth160488 	}
4196842Sth160488 
4206842Sth160488 	if (standalone_cfg.type != NS_CACHEMGR &&
4216842Sth160488 	    standalone_cfg.SA_BIND_DN != NULL) {
4226842Sth160488 		ns_auth_t **authpp = NULL, **authp = NULL;
4236842Sth160488 
4246842Sth160488 		if (__ns_ldap_getParam(NS_LDAP_AUTH_P,
4256842Sth160488 		    (void ***)&authpp,
4266842Sth160488 		    &errorp) != NS_LDAP_SUCCESS || authpp == NULL) {
4276842Sth160488 			__ns_ldap_cancelStandalone();
4286842Sth160488 			(void) __ns_ldap_freeParam((void ***)&authpp);
4296842Sth160488 			if (errorp) {
4306842Sth160488 				(void) fprintf(stderr,
4316842Sth160488 				    gettext(errorp->message));
4326842Sth160488 				(void) __ns_ldap_freeError(&errorp);
4336842Sth160488 			}
4346842Sth160488 			exit(1);
4356842Sth160488 		}
4366842Sth160488 		for (authp = authpp; *authp; authp++) {
4376842Sth160488 			if ((*authp)->saslmech == NS_LDAP_SASL_GSSAPI) {
4386842Sth160488 				/*
4396842Sth160488 				 * For now we have no use for bindDN and
4406842Sth160488 				 * bindPassword when using SASL/GSSAPI.
4416842Sth160488 				 */
4426842Sth160488 				(void) fprintf(stderr,
4436842Sth160488 				    gettext("Warning: SASL/GSSAPI will be "
4446842Sth160488 				    "used as an authentication method"
4456842Sth160488 				    "The bind DN and password will "
4466842Sth160488 				    "be ignored.\n"));
4476842Sth160488 				break;
4486842Sth160488 			}
4496842Sth160488 		}
4506842Sth160488 	}
4516842Sth160488 
4520Sstevel@tonic-gate 	/*
4530Sstevel@tonic-gate 	 * If dumpping a database,
4540Sstevel@tonic-gate 	 * or all the containers,
4550Sstevel@tonic-gate 	 * use page control just
4560Sstevel@tonic-gate 	 * in case there are too many entries
4570Sstevel@tonic-gate 	 */
4580Sstevel@tonic-gate 	if (!key && !(listflag & NS_LDAP_SCOPE_BASE))
4590Sstevel@tonic-gate 		listflag |= NS_LDAP_PAGE_CTRL;
4600Sstevel@tonic-gate 
4610Sstevel@tonic-gate 	/* build the attribute array */
4620Sstevel@tonic-gate 	if (strncasecmp(attribute, "NULL", 4) == 0)
4630Sstevel@tonic-gate 		ldapattribute = NULL;
4640Sstevel@tonic-gate 	else {
4650Sstevel@tonic-gate 		buffer[0] = strdup(attribute);
4660Sstevel@tonic-gate 		while ((p = strchr(attribute, ',')) != NULL) {
4670Sstevel@tonic-gate 			buffer[index++] = attribute = p + 1;
4680Sstevel@tonic-gate 			*p = '\0';
4690Sstevel@tonic-gate 		}
4700Sstevel@tonic-gate 		buffer[index] = NULL;
4710Sstevel@tonic-gate 		ldapattribute = buffer;
4720Sstevel@tonic-gate 	}
4730Sstevel@tonic-gate 
4740Sstevel@tonic-gate 	/* build the filter */
4750Sstevel@tonic-gate 	if (database && (strcasecmp(database, "publickey") == NULL)) {
4760Sstevel@tonic-gate 		/* user publickey lookup */
4770Sstevel@tonic-gate 		char *err1 = NULL;
4780Sstevel@tonic-gate 		int  rc1;
4790Sstevel@tonic-gate 
4800Sstevel@tonic-gate 		rc = rc1 = -1;
4810Sstevel@tonic-gate 		ldapfilter = set_filter_publickey(key, database, 0, &udata);
4820Sstevel@tonic-gate 		if (ldapfilter) {
4830Sstevel@tonic-gate 			if (verbose) {
4841450Sjanga 				(void) fprintf(stdout,
4856842Sth160488 				    gettext("+++ database=%s\n"),
4866842Sth160488 				    (database ? database : "NULL"));
4871450Sjanga 				(void) fprintf(stdout,
4886842Sth160488 				    gettext("+++ filter=%s\n"),
4896842Sth160488 				    (ldapfilter ? ldapfilter : "NULL"));
4901450Sjanga 				(void) fprintf(stdout,
4910Sstevel@tonic-gate 				gettext("+++ template for merging"
4926842Sth160488 				    "SSD filter=%s\n"),
4936842Sth160488 				    (udata ? udata : "NULL"));
4940Sstevel@tonic-gate 			}
4950Sstevel@tonic-gate 			rc = list("passwd", ldapfilter, ldapattribute,
4966842Sth160488 			    &err, udata);
4970Sstevel@tonic-gate 			free(ldapfilter);
4980Sstevel@tonic-gate 			free(udata);
4990Sstevel@tonic-gate 		}
5000Sstevel@tonic-gate 		/* hosts publickey lookup */
5010Sstevel@tonic-gate 		ldapfilter = set_filter_publickey(key, database, 1, &udata);
5020Sstevel@tonic-gate 		if (ldapfilter) {
5030Sstevel@tonic-gate 			if (verbose) {
5041450Sjanga 				(void) fprintf(stdout,
5056842Sth160488 				    gettext("+++ database=%s\n"),
5066842Sth160488 				    (database ? database : "NULL"));
5071450Sjanga 				(void) fprintf(stdout,
5086842Sth160488 				    gettext("+++ filter=%s\n"),
5096842Sth160488 				    (ldapfilter ? ldapfilter : "NULL"));
5101450Sjanga 				(void) fprintf(stdout,
5110Sstevel@tonic-gate 				gettext("+++ template for merging"
5126842Sth160488 				    "SSD filter=%s\n"),
5136842Sth160488 				    (udata ? udata : "NULL"));
5140Sstevel@tonic-gate 			}
5150Sstevel@tonic-gate 			rc1 = list("hosts", ldapfilter, ldapattribute,
5166842Sth160488 			    &err1, udata);
5170Sstevel@tonic-gate 			free(ldapfilter);
5180Sstevel@tonic-gate 			free(udata);
5190Sstevel@tonic-gate 		}
5200Sstevel@tonic-gate 		if (rc == -1 && rc1 == -1) {
5210Sstevel@tonic-gate 			/* this should never happen */
5221450Sjanga 			(void) fprintf(stderr,
5230Sstevel@tonic-gate 			    gettext("ldaplist: invalid publickey lookup\n"));
5240Sstevel@tonic-gate 			rc = 2;
5257777SChin-Long.Shu@Sun.COM 		} else if (rc != 0 && rc1 != 0) {
5261450Sjanga 			(void) fprintf(stderr,
5270Sstevel@tonic-gate 			gettext("ldaplist: %s\n"), (err ? err : err1));
5280Sstevel@tonic-gate 			if (rc == -1)
5290Sstevel@tonic-gate 				rc = rc1;
5300Sstevel@tonic-gate 		} else
5310Sstevel@tonic-gate 			rc = 0;
5320Sstevel@tonic-gate 		exit(switch_err(rc));
5330Sstevel@tonic-gate 	}
5340Sstevel@tonic-gate 
5350Sstevel@tonic-gate 	/*
5360Sstevel@tonic-gate 	 * we set the search filter to (objectclass=*) when we want
5370Sstevel@tonic-gate 	 * to list the directory attribute instead of the entries
5380Sstevel@tonic-gate 	 * (the -d option).
5390Sstevel@tonic-gate 	 */
5400Sstevel@tonic-gate 	if (((ldapfilter = set_filter(key, database, &udata)) == NULL) ||
5416842Sth160488 	    (listflag == NS_LDAP_SCOPE_BASE)) {
5420Sstevel@tonic-gate 		ldapfilter = strdup("objectclass=*");
5430Sstevel@tonic-gate 		udata = strdup("%s");
5440Sstevel@tonic-gate 	}
5450Sstevel@tonic-gate 
5460Sstevel@tonic-gate 	if (verbose) {
5471450Sjanga 		(void) fprintf(stdout, gettext("+++ database=%s\n"),
5486842Sth160488 		    (database ? database : "NULL"));
5491450Sjanga 		(void) fprintf(stdout, gettext("+++ filter=%s\n"),
5506842Sth160488 		    (ldapfilter ? ldapfilter : "NULL"));
5511450Sjanga 		(void) fprintf(stdout,
5526842Sth160488 		    gettext("+++ template for merging SSD filter=%s\n"),
5536842Sth160488 		    (udata ? udata : "NULL"));
5540Sstevel@tonic-gate 	}
5550Sstevel@tonic-gate 	if (rc = list(database, ldapfilter, ldapattribute, &err, udata))
5561450Sjanga 		(void) fprintf(stderr, gettext("ldaplist: %s\n"), err);
5576842Sth160488 
5586842Sth160488 	__ns_ldap_cancelStandalone();
5596842Sth160488 
5600Sstevel@tonic-gate 	if (ldapfilter)
5610Sstevel@tonic-gate 		free(ldapfilter);
5620Sstevel@tonic-gate 	if (udata)
5630Sstevel@tonic-gate 		free(udata);
5640Sstevel@tonic-gate 	exit(switch_err(rc));
5651450Sjanga 	return (0); /* Never reached */
5660Sstevel@tonic-gate }
567