xref: /illumos-gate/usr/src/cmd/ldap/ns_ldap/ldaplist.c (revision e1dd0a2f)
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
5b446700bSjanga  * Common Development and Distribution License (the "License").
6b446700bSjanga  * 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 /*
22*e1dd0a2fSth  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <libintl.h>
317c478bd9Sstevel@tonic-gate #include <strings.h>
327c478bd9Sstevel@tonic-gate #include <locale.h>
337c478bd9Sstevel@tonic-gate #include <syslog.h>
34*e1dd0a2fSth 
35*e1dd0a2fSth #include "standalone.h"
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate extern char *set_filter(char **, char *, char **);
387c478bd9Sstevel@tonic-gate extern char *set_filter_publickey(char **, char *, int, char **);
397c478bd9Sstevel@tonic-gate extern void _printResult(ns_ldap_result_t *);
40b446700bSjanga extern void printMapping();
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate int listflag = 0;
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate void
457c478bd9Sstevel@tonic-gate usage(char *msg) {
467c478bd9Sstevel@tonic-gate 	if (msg)
47b446700bSjanga 		(void) fprintf(stderr, "%s\n", msg);
487c478bd9Sstevel@tonic-gate 
49b446700bSjanga 	(void) fprintf(stderr,
507c478bd9Sstevel@tonic-gate 	gettext(
51*e1dd0a2fSth 	"\n"
52*e1dd0a2fSth 	"usage: ldaplist [-dlv] [-h LDAP_server[:serverPort] [-M domainName]\n"
53*e1dd0a2fSth 	"[-N  profileName] [-a  authenticationMethod] [-P certifPath]\n"
54*e1dd0a2fSth 	"[-D  bindDN] [-w bindPassword] [-j passwdFile]]\n"
55*e1dd0a2fSth 	"[<database> [<key>] ...]\n\n"
56*e1dd0a2fSth 	"usage: ldaplist -h\n"
57*e1dd0a2fSth 	"\n"
58*e1dd0a2fSth 	"usage: ldaplist -g\n\n"
597c478bd9Sstevel@tonic-gate 	"\tOptions:\n"
607c478bd9Sstevel@tonic-gate 	"\t    -l list all the attributes found in entry.\n"
617c478bd9Sstevel@tonic-gate 	"\t       By default, it lists only the DNs.\n"
627c478bd9Sstevel@tonic-gate 	"\t    -d list attributes for the database instead of its entries\n"
637c478bd9Sstevel@tonic-gate 	"\t    -v print out the LDAP search filter.\n"
64*e1dd0a2fSth 	"\t    -g list the database mappings.\n"
65*e1dd0a2fSth 	"\t    -h An address (or a name) and a port of the LDAP server in\n"
66*e1dd0a2fSth 	"\t       which the entries will be stored. The default value for\n"
67*e1dd0a2fSth 	"\t       the port is 389 (or 636 for TLS connections).\n"
68*e1dd0a2fSth 	"\t    -M The name of a domain served by the specified server.\n"
69*e1dd0a2fSth 	"\t       If not specified, the default domain name will be used.\n"
70*e1dd0a2fSth 	"\t    -N Specifies a DUAProfile name.\n"
71*e1dd0a2fSth 	"\t       The default value is \"default\".\n"
72*e1dd0a2fSth 	"\t    -a Specifies an authentication method.\n"
73*e1dd0a2fSth 	"\t    -P The certificate path for the location of the certificate\n"
74*e1dd0a2fSth 	"\t       database.\n"
75*e1dd0a2fSth 	"\t    -D Specifies an entry which has read permission to\n"
76*e1dd0a2fSth 	"\t       the requested database.\n"
77*e1dd0a2fSth 	"\t    -w Password to be used for authenticating the bindDN.\n"
78*e1dd0a2fSth 	"\t    -j File containing the password for bindDN or SSL key db.\n"
797c478bd9Sstevel@tonic-gate 	"\t<database> is the database to be searched in.  Standard system\n"
807c478bd9Sstevel@tonic-gate 	"\tdatabases are:\n"
817c478bd9Sstevel@tonic-gate 	"\t\tpassword, printers, group, hosts, ethers, networks, netmasks,\n"
827c478bd9Sstevel@tonic-gate 	"\t\trpc, bootparams, protocols, services, netgroup, auto_*.\n"
837c478bd9Sstevel@tonic-gate 	"\tNon-standard system databases can be specified as follows:\n"
847c478bd9Sstevel@tonic-gate 	"\t\tby specific container: ou=<dbname> or\n"
857c478bd9Sstevel@tonic-gate 	"\t\tby default container: <dbname>.  In this case, 'nismapname'\n"
867c478bd9Sstevel@tonic-gate 	"\t\twill be used, thus mapping this to nismapname=<dbname>.\n"
877c478bd9Sstevel@tonic-gate 	"\t<key> is the key to search in the database.  For the standard\n"
887c478bd9Sstevel@tonic-gate 	"\tdatabases, the search type for the key is predefined.  You can\n"
89*e1dd0a2fSth 	"\toverride this by specifying <type>=<key>.\n"
90*e1dd0a2fSth 	"\nNOTE: The old -h option printing the mapping information is "
91*e1dd0a2fSth 	"deprecated.\nFor backward compatibility the following mode is "
92*e1dd0a2fSth 	"available:\nldaplist -h\n"));
937c478bd9Sstevel@tonic-gate 	exit(1);
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate  * This is a generic filter call back function for
987c478bd9Sstevel@tonic-gate  * merging the filter from service search descriptor with
997c478bd9Sstevel@tonic-gate  * an existing search filter. This routine expects userdata
1007c478bd9Sstevel@tonic-gate  * contain a format string with a single %s in it, and will
1017c478bd9Sstevel@tonic-gate  * use the format string with sprintf() to insert the SSD filter.
1027c478bd9Sstevel@tonic-gate  *
1037c478bd9Sstevel@tonic-gate  * This routine is passed to the __ns_ldap_list() or
1047c478bd9Sstevel@tonic-gate  * __ns_ldap_firstEntry() APIs as the filter call back
1057c478bd9Sstevel@tonic-gate  * together with the userdata. For example,
1067c478bd9Sstevel@tonic-gate  * the "ldaplist hosts sys1" processing may call __ns_ldap_list()
1077c478bd9Sstevel@tonic-gate  * with "(&(objectClass=ipHost)(cn=sys1))" as filter, this function
1087c478bd9Sstevel@tonic-gate  * as the filter call back, and "(&(%s)(cn=sys1))" as the
1097c478bd9Sstevel@tonic-gate  * userdata, this routine will in turn gets call to produce
1107c478bd9Sstevel@tonic-gate  * "(&(department=sds)(cn=sys1))" as the real search
1117c478bd9Sstevel@tonic-gate  * filter, if the input SSD contains a filter "department=sds".
1127c478bd9Sstevel@tonic-gate  */
1137c478bd9Sstevel@tonic-gate static int
1147c478bd9Sstevel@tonic-gate merge_SSD_filter(const ns_ldap_search_desc_t *desc,
1157c478bd9Sstevel@tonic-gate 			char **realfilter,
1167c478bd9Sstevel@tonic-gate 			const void *userdata)
1177c478bd9Sstevel@tonic-gate {
1187c478bd9Sstevel@tonic-gate 	int	len;
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	/* sanity check */
1217c478bd9Sstevel@tonic-gate 	if (realfilter == NULL)
1227c478bd9Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
1237c478bd9Sstevel@tonic-gate 	*realfilter = NULL;
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 	if (desc == NULL || desc->filter == NULL ||
126*e1dd0a2fSth 	    userdata == NULL)
1277c478bd9Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 	len = strlen(userdata) + strlen(desc->filter) + 1;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	*realfilter = (char *)malloc(len);
1327c478bd9Sstevel@tonic-gate 	if (*realfilter == NULL)
1337c478bd9Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	(void) sprintf(*realfilter, (char *)userdata,
136*e1dd0a2fSth 	    desc->filter);
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate /* returns 0=success, 1=error */
1427c478bd9Sstevel@tonic-gate int
1437c478bd9Sstevel@tonic-gate list(char *database, char *ldapfilter, char **ldapattribute,
1447c478bd9Sstevel@tonic-gate char **err, char *userdata)
1457c478bd9Sstevel@tonic-gate {
1467c478bd9Sstevel@tonic-gate 	ns_ldap_result_t	*result;
1477c478bd9Sstevel@tonic-gate 	ns_ldap_error_t	*errorp;
1487c478bd9Sstevel@tonic-gate 	int		rc;
1497c478bd9Sstevel@tonic-gate 	char		buf[500];
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 	*err = NULL;
1527c478bd9Sstevel@tonic-gate 	buf[0] = '\0';
1537c478bd9Sstevel@tonic-gate 	rc = __ns_ldap_list(database, (const char *)ldapfilter,
154*e1dd0a2fSth 	    merge_SSD_filter, (const char **)ldapattribute, NULL,
155*e1dd0a2fSth 	    listflag, &result, &errorp, NULL, userdata);
1567c478bd9Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS) {
1577c478bd9Sstevel@tonic-gate 		char *p;
1587c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_err2str(rc, &p);
1597c478bd9Sstevel@tonic-gate 		if (errorp && errorp->message) {
160b446700bSjanga 			(void) snprintf(buf, sizeof (buf), "%s (%s)",
161*e1dd0a2fSth 			    p, errorp->message);
162b446700bSjanga 			(void) __ns_ldap_freeError(&errorp);
1637c478bd9Sstevel@tonic-gate 		} else
164*e1dd0a2fSth 			(void) snprintf(buf, sizeof (buf), "%s\n", p);
1657c478bd9Sstevel@tonic-gate 		*err = strdup(buf);
1667c478bd9Sstevel@tonic-gate 		return (rc);
1677c478bd9Sstevel@tonic-gate 	}
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	_printResult(result);
170b446700bSjanga 	(void) __ns_ldap_freeResult(&result);
1717c478bd9Sstevel@tonic-gate 	return (0);
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate int
1767c478bd9Sstevel@tonic-gate switch_err(int rc)
1777c478bd9Sstevel@tonic-gate {
1787c478bd9Sstevel@tonic-gate 	switch (rc) {
1797c478bd9Sstevel@tonic-gate 	case NS_LDAP_SUCCESS:
1807c478bd9Sstevel@tonic-gate 		return (0);
1817c478bd9Sstevel@tonic-gate 	case NS_LDAP_NOTFOUND:
1827c478bd9Sstevel@tonic-gate 		return (1);
1837c478bd9Sstevel@tonic-gate 	}
1847c478bd9Sstevel@tonic-gate 	return (2);
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate 
187a506a34cSth int
1887c478bd9Sstevel@tonic-gate main(int argc, char **argv)
1897c478bd9Sstevel@tonic-gate {
1907c478bd9Sstevel@tonic-gate 
191*e1dd0a2fSth 	extern int		optind;
192*e1dd0a2fSth 	char			*database = NULL;
193*e1dd0a2fSth 	char			*ldapfilter = NULL;
194*e1dd0a2fSth 	char			*attribute = "dn";
195*e1dd0a2fSth 	char			**key = NULL;
196*e1dd0a2fSth 	char			**ldapattribute = NULL;
197*e1dd0a2fSth 	char 			*buffer[100];
198*e1dd0a2fSth 	char			*err = NULL;
199*e1dd0a2fSth 	char			*p;
200*e1dd0a2fSth 	int			index = 1;
201*e1dd0a2fSth 	int			c;
202*e1dd0a2fSth 	int			rc;
203*e1dd0a2fSth 	int			verbose = 0;
204*e1dd0a2fSth 	char			*udata = NULL;
205*e1dd0a2fSth 
206*e1dd0a2fSth 	ns_standalone_conf_t	standalone_cfg = standaloneDefaults;
207*e1dd0a2fSth 	ns_ldap_error_t		*errorp = NULL;
208*e1dd0a2fSth 	char			*authmech = NULL;
209*e1dd0a2fSth 	ns_auth_t		auth = {NS_LDAP_AUTH_NONE,
210*e1dd0a2fSth 					NS_LDAP_TLS_NONE,
211*e1dd0a2fSth 					NS_LDAP_SASL_NONE,
212*e1dd0a2fSth 					NS_LDAP_SASLOPT_NONE};
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
2157c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	openlog("ldaplist", LOG_PID, LOG_USER);
2187c478bd9Sstevel@tonic-gate 
219*e1dd0a2fSth 	if (argc == 2 &&
220*e1dd0a2fSth 	    strlen(argv[1]) == 2 && strncmp(argv[1], "-h", 2) == 0) {
221*e1dd0a2fSth 		/* preserve backwards compatability, support old -h option */
222*e1dd0a2fSth 		(void) printMapping();
223*e1dd0a2fSth 		exit(0);
224*e1dd0a2fSth 	}
225*e1dd0a2fSth 
226*e1dd0a2fSth 	while ((c = getopt(argc, argv, "h:M:N:P:r:a:D:w:j:dgvl")) != EOF) {
2277c478bd9Sstevel@tonic-gate 		switch (c) {
2287c478bd9Sstevel@tonic-gate 		case 'd':
2297c478bd9Sstevel@tonic-gate 			listflag |= NS_LDAP_SCOPE_BASE;
2307c478bd9Sstevel@tonic-gate 			break;
231*e1dd0a2fSth 		case 'g':
2327c478bd9Sstevel@tonic-gate 			(void) printMapping();
2337c478bd9Sstevel@tonic-gate 			exit(0);
234b446700bSjanga 			break; /* Never reached */
2357c478bd9Sstevel@tonic-gate 		case 'l':
2367c478bd9Sstevel@tonic-gate 			attribute = "NULL";
2377c478bd9Sstevel@tonic-gate 			break;
2387c478bd9Sstevel@tonic-gate 		case 'v':
2397c478bd9Sstevel@tonic-gate 			verbose = 1;
2407c478bd9Sstevel@tonic-gate 			break;
241*e1dd0a2fSth 		case 'M':
242*e1dd0a2fSth 			standalone_cfg.type = NS_LDAP_SERVER;
243*e1dd0a2fSth 			standalone_cfg.SA_DOMAIN = optarg;
244*e1dd0a2fSth 			break;
245*e1dd0a2fSth 		case 'h':
246*e1dd0a2fSth 			standalone_cfg.type = NS_LDAP_SERVER;
247*e1dd0a2fSth 			if (separatePort(optarg,
248*e1dd0a2fSth 			    &standalone_cfg.SA_SERVER,
249*e1dd0a2fSth 			    &standalone_cfg.SA_PORT) > 0) {
250*e1dd0a2fSth 				exit(1);
251*e1dd0a2fSth 			}
252*e1dd0a2fSth 			break;
253*e1dd0a2fSth 		case 'P':
254*e1dd0a2fSth 			standalone_cfg.type = NS_LDAP_SERVER;
255*e1dd0a2fSth 			standalone_cfg.SA_CERT_PATH = optarg;
256*e1dd0a2fSth 			break;
257*e1dd0a2fSth 		case 'N':
258*e1dd0a2fSth 			standalone_cfg.type = NS_LDAP_SERVER;
259*e1dd0a2fSth 			standalone_cfg.SA_PROFILE_NAME = optarg;
260*e1dd0a2fSth 			break;
261*e1dd0a2fSth 		case 'D':
262*e1dd0a2fSth 			standalone_cfg.type = NS_LDAP_SERVER;
263*e1dd0a2fSth 			standalone_cfg.SA_BIND_DN = strdup(optarg);
264*e1dd0a2fSth 			break;
265*e1dd0a2fSth 		case 'w':
266*e1dd0a2fSth 			if (standalone_cfg.SA_BIND_PWD != NULL) {
267*e1dd0a2fSth 				(void) fprintf(stderr,
268*e1dd0a2fSth 				    gettext("The -w option is mutually "
269*e1dd0a2fSth 				    "exclusive of -j. -w is ignored.\n"));
270*e1dd0a2fSth 				break;
271*e1dd0a2fSth 			}
272*e1dd0a2fSth 
273*e1dd0a2fSth 			if (optarg != NULL &&
274*e1dd0a2fSth 			    optarg[0] == '-' && optarg[1] == '\0') {
275*e1dd0a2fSth 				/* Ask for a password later */
276*e1dd0a2fSth 				break;
277*e1dd0a2fSth 			}
278*e1dd0a2fSth 
279*e1dd0a2fSth 			standalone_cfg.type = NS_LDAP_SERVER;
280*e1dd0a2fSth 			standalone_cfg.SA_BIND_PWD = strdup(optarg);
281*e1dd0a2fSth 			break;
282*e1dd0a2fSth 		case 'j':
283*e1dd0a2fSth 			if (standalone_cfg.SA_BIND_PWD != NULL) {
284*e1dd0a2fSth 				(void) fprintf(stderr,
285*e1dd0a2fSth 				    gettext("The -w option is mutually "
286*e1dd0a2fSth 				    "exclusive of -j. -w is ignored.\n"));
287*e1dd0a2fSth 				free(standalone_cfg.SA_BIND_PWD);
288*e1dd0a2fSth 			}
289*e1dd0a2fSth 			standalone_cfg.type = NS_LDAP_SERVER;
290*e1dd0a2fSth 			standalone_cfg.SA_BIND_PWD = readPwd(optarg);
291*e1dd0a2fSth 			if (standalone_cfg.SA_BIND_PWD == NULL) {
292*e1dd0a2fSth 				exit(1);
293*e1dd0a2fSth 			}
294*e1dd0a2fSth 			break;
295*e1dd0a2fSth 		case 'a':
296*e1dd0a2fSth 			authmech = optarg;
297*e1dd0a2fSth 			break;
2987c478bd9Sstevel@tonic-gate 		default:
2997c478bd9Sstevel@tonic-gate 			usage(gettext("Invalid option"));
3007c478bd9Sstevel@tonic-gate 		}
3017c478bd9Sstevel@tonic-gate 	}
302*e1dd0a2fSth 
303*e1dd0a2fSth 	if (standalone_cfg.type == NS_LDAP_SERVER &&
304*e1dd0a2fSth 	    standalone_cfg.SA_SERVER == NULL) {
305*e1dd0a2fSth 		(void) fprintf(stderr,
306*e1dd0a2fSth 		    gettext("Please specify an LDAP server you want "
307*e1dd0a2fSth 		    "to connect to. \n"));
308*e1dd0a2fSth 		exit(1);
309*e1dd0a2fSth 	}
310*e1dd0a2fSth 
3117c478bd9Sstevel@tonic-gate 	if ((c = argc - optind) > 0)
3127c478bd9Sstevel@tonic-gate 		database = argv[optind++];
3137c478bd9Sstevel@tonic-gate 	if ((--c) > 0)
3147c478bd9Sstevel@tonic-gate 		key = &argv[optind];
3157c478bd9Sstevel@tonic-gate 
316*e1dd0a2fSth 	if (authmech != NULL) {
317*e1dd0a2fSth 		if (__ns_ldap_initAuth(authmech,
318*e1dd0a2fSth 		    &auth,
319*e1dd0a2fSth 		    &errorp) != NS_LDAP_SUCCESS) {
320*e1dd0a2fSth 			if (errorp) {
321*e1dd0a2fSth 				(void) fprintf(stderr, "%s", errorp->message);
322*e1dd0a2fSth 				(void) __ns_ldap_freeError(&errorp);
323*e1dd0a2fSth 			}
324*e1dd0a2fSth 			exit(1);
325*e1dd0a2fSth 		}
326*e1dd0a2fSth 	}
327*e1dd0a2fSth 
328*e1dd0a2fSth 	if (auth.saslmech != NS_LDAP_SASL_GSSAPI &&
329*e1dd0a2fSth 	    standalone_cfg.SA_BIND_DN != NULL &&
330*e1dd0a2fSth 	    standalone_cfg.SA_BIND_PWD == NULL) {
331*e1dd0a2fSth 		/* If password is not specified, then prompt user for it. */
332*e1dd0a2fSth 		standalone_cfg.SA_BIND_PWD =
333*e1dd0a2fSth 		    strdup(getpassphrase("Enter password:"));
334*e1dd0a2fSth 	}
335*e1dd0a2fSth 
336*e1dd0a2fSth 	standalone_cfg.SA_AUTH = (authmech == NULL) ? NULL : &auth;
337*e1dd0a2fSth 
338*e1dd0a2fSth 	if (__ns_ldap_initStandalone(&standalone_cfg,
339*e1dd0a2fSth 	    &errorp) != NS_LDAP_SUCCESS) {
340*e1dd0a2fSth 		if (errorp) {
341*e1dd0a2fSth 			(void) fprintf(stderr, "%s\n", errorp->message);
342*e1dd0a2fSth 			(void) __ns_ldap_freeError(&errorp);
343*e1dd0a2fSth 		}
344*e1dd0a2fSth 		exit(1);
345*e1dd0a2fSth 	}
346*e1dd0a2fSth 
347*e1dd0a2fSth 	if (authmech != NULL) {
348*e1dd0a2fSth 		if (__ns_ldap_setParam(NS_LDAP_AUTH_P,
349*e1dd0a2fSth 		    authmech, &errorp) != NS_LDAP_SUCCESS) {
350*e1dd0a2fSth 			__ns_ldap_cancelStandalone();
351*e1dd0a2fSth 			if (errorp != NULL) {
352*e1dd0a2fSth 				(void) fprintf(stderr, "%s", errorp->message);
353*e1dd0a2fSth 				(void) __ns_ldap_freeError(&errorp);
354*e1dd0a2fSth 			}
355*e1dd0a2fSth 			exit(1);
356*e1dd0a2fSth 		}
357*e1dd0a2fSth 	}
358*e1dd0a2fSth 	if (standalone_cfg.SA_CRED != NULL) {
359*e1dd0a2fSth 		if (__ns_ldap_setParam(NS_LDAP_CREDENTIAL_LEVEL_P,
360*e1dd0a2fSth 		    standalone_cfg.SA_CRED, &errorp) != NS_LDAP_SUCCESS) {
361*e1dd0a2fSth 			__ns_ldap_cancelStandalone();
362*e1dd0a2fSth 			if (errorp != NULL) {
363*e1dd0a2fSth 				(void) fprintf(stderr, "%s", errorp->message);
364*e1dd0a2fSth 				(void) __ns_ldap_freeError(&errorp);
365*e1dd0a2fSth 			}
366*e1dd0a2fSth 			exit(1);
367*e1dd0a2fSth 		}
368*e1dd0a2fSth 	}
369*e1dd0a2fSth 
370*e1dd0a2fSth 	if (standalone_cfg.type != NS_CACHEMGR &&
371*e1dd0a2fSth 	    standalone_cfg.SA_BIND_DN != NULL) {
372*e1dd0a2fSth 		ns_auth_t **authpp = NULL, **authp = NULL;
373*e1dd0a2fSth 
374*e1dd0a2fSth 		if (__ns_ldap_getParam(NS_LDAP_AUTH_P,
375*e1dd0a2fSth 		    (void ***)&authpp,
376*e1dd0a2fSth 		    &errorp) != NS_LDAP_SUCCESS || authpp == NULL) {
377*e1dd0a2fSth 			__ns_ldap_cancelStandalone();
378*e1dd0a2fSth 			(void) __ns_ldap_freeParam((void ***)&authpp);
379*e1dd0a2fSth 			if (errorp) {
380*e1dd0a2fSth 				(void) fprintf(stderr,
381*e1dd0a2fSth 				    gettext(errorp->message));
382*e1dd0a2fSth 				(void) __ns_ldap_freeError(&errorp);
383*e1dd0a2fSth 			}
384*e1dd0a2fSth 			exit(1);
385*e1dd0a2fSth 		}
386*e1dd0a2fSth 		for (authp = authpp; *authp; authp++) {
387*e1dd0a2fSth 			if ((*authp)->saslmech == NS_LDAP_SASL_GSSAPI) {
388*e1dd0a2fSth 				/*
389*e1dd0a2fSth 				 * For now we have no use for bindDN and
390*e1dd0a2fSth 				 * bindPassword when using SASL/GSSAPI.
391*e1dd0a2fSth 				 */
392*e1dd0a2fSth 				(void) fprintf(stderr,
393*e1dd0a2fSth 				    gettext("Warning: SASL/GSSAPI will be "
394*e1dd0a2fSth 				    "used as an authentication method"
395*e1dd0a2fSth 				    "The bind DN and password will "
396*e1dd0a2fSth 				    "be ignored.\n"));
397*e1dd0a2fSth 				break;
398*e1dd0a2fSth 			}
399*e1dd0a2fSth 		}
400*e1dd0a2fSth 	}
401*e1dd0a2fSth 
4027c478bd9Sstevel@tonic-gate 	/*
4037c478bd9Sstevel@tonic-gate 	 * If dumpping a database,
4047c478bd9Sstevel@tonic-gate 	 * or all the containers,
4057c478bd9Sstevel@tonic-gate 	 * use page control just
4067c478bd9Sstevel@tonic-gate 	 * in case there are too many entries
4077c478bd9Sstevel@tonic-gate 	 */
4087c478bd9Sstevel@tonic-gate 	if (!key && !(listflag & NS_LDAP_SCOPE_BASE))
4097c478bd9Sstevel@tonic-gate 		listflag |= NS_LDAP_PAGE_CTRL;
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 	/* build the attribute array */
4127c478bd9Sstevel@tonic-gate 	if (strncasecmp(attribute, "NULL", 4) == 0)
4137c478bd9Sstevel@tonic-gate 		ldapattribute = NULL;
4147c478bd9Sstevel@tonic-gate 	else {
4157c478bd9Sstevel@tonic-gate 		buffer[0] = strdup(attribute);
4167c478bd9Sstevel@tonic-gate 		while ((p = strchr(attribute, ',')) != NULL) {
4177c478bd9Sstevel@tonic-gate 			buffer[index++] = attribute = p + 1;
4187c478bd9Sstevel@tonic-gate 			*p = '\0';
4197c478bd9Sstevel@tonic-gate 		}
4207c478bd9Sstevel@tonic-gate 		buffer[index] = NULL;
4217c478bd9Sstevel@tonic-gate 		ldapattribute = buffer;
4227c478bd9Sstevel@tonic-gate 	}
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 	/* build the filter */
4257c478bd9Sstevel@tonic-gate 	if (database && (strcasecmp(database, "publickey") == NULL)) {
4267c478bd9Sstevel@tonic-gate 		/* user publickey lookup */
4277c478bd9Sstevel@tonic-gate 		char *err1 = NULL;
4287c478bd9Sstevel@tonic-gate 		int  rc1;
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate 		rc = rc1 = -1;
4317c478bd9Sstevel@tonic-gate 		ldapfilter = set_filter_publickey(key, database, 0, &udata);
4327c478bd9Sstevel@tonic-gate 		if (ldapfilter) {
4337c478bd9Sstevel@tonic-gate 			if (verbose) {
434b446700bSjanga 				(void) fprintf(stdout,
435*e1dd0a2fSth 				    gettext("+++ database=%s\n"),
436*e1dd0a2fSth 				    (database ? database : "NULL"));
437b446700bSjanga 				(void) fprintf(stdout,
438*e1dd0a2fSth 				    gettext("+++ filter=%s\n"),
439*e1dd0a2fSth 				    (ldapfilter ? ldapfilter : "NULL"));
440b446700bSjanga 				(void) fprintf(stdout,
4417c478bd9Sstevel@tonic-gate 				gettext("+++ template for merging"
442*e1dd0a2fSth 				    "SSD filter=%s\n"),
443*e1dd0a2fSth 				    (udata ? udata : "NULL"));
4447c478bd9Sstevel@tonic-gate 			}
4457c478bd9Sstevel@tonic-gate 			rc = list("passwd", ldapfilter, ldapattribute,
446*e1dd0a2fSth 			    &err, udata);
4477c478bd9Sstevel@tonic-gate 			free(ldapfilter);
4487c478bd9Sstevel@tonic-gate 			free(udata);
4497c478bd9Sstevel@tonic-gate 		}
4507c478bd9Sstevel@tonic-gate 		/* hosts publickey lookup */
4517c478bd9Sstevel@tonic-gate 		ldapfilter = set_filter_publickey(key, database, 1, &udata);
4527c478bd9Sstevel@tonic-gate 		if (ldapfilter) {
4537c478bd9Sstevel@tonic-gate 			if (verbose) {
454b446700bSjanga 				(void) fprintf(stdout,
455*e1dd0a2fSth 				    gettext("+++ database=%s\n"),
456*e1dd0a2fSth 				    (database ? database : "NULL"));
457b446700bSjanga 				(void) fprintf(stdout,
458*e1dd0a2fSth 				    gettext("+++ filter=%s\n"),
459*e1dd0a2fSth 				    (ldapfilter ? ldapfilter : "NULL"));
460b446700bSjanga 				(void) fprintf(stdout,
4617c478bd9Sstevel@tonic-gate 				gettext("+++ template for merging"
462*e1dd0a2fSth 				    "SSD filter=%s\n"),
463*e1dd0a2fSth 				    (udata ? udata : "NULL"));
4647c478bd9Sstevel@tonic-gate 			}
4657c478bd9Sstevel@tonic-gate 			rc1 = list("hosts", ldapfilter, ldapattribute,
466*e1dd0a2fSth 			    &err1, udata);
4677c478bd9Sstevel@tonic-gate 			free(ldapfilter);
4687c478bd9Sstevel@tonic-gate 			free(udata);
4697c478bd9Sstevel@tonic-gate 		}
4707c478bd9Sstevel@tonic-gate 		if (rc == -1 && rc1 == -1) {
4717c478bd9Sstevel@tonic-gate 			/* this should never happen */
472b446700bSjanga 			(void) fprintf(stderr,
4737c478bd9Sstevel@tonic-gate 			    gettext("ldaplist: invalid publickey lookup\n"));
4747c478bd9Sstevel@tonic-gate 			rc = 2;
4757c478bd9Sstevel@tonic-gate 		} if (rc != 0 && rc1 != 0) {
476b446700bSjanga 			(void) fprintf(stderr,
4777c478bd9Sstevel@tonic-gate 			gettext("ldaplist: %s\n"), (err ? err : err1));
4787c478bd9Sstevel@tonic-gate 			if (rc == -1)
4797c478bd9Sstevel@tonic-gate 				rc = rc1;
4807c478bd9Sstevel@tonic-gate 		} else
4817c478bd9Sstevel@tonic-gate 			rc = 0;
4827c478bd9Sstevel@tonic-gate 		exit(switch_err(rc));
4837c478bd9Sstevel@tonic-gate 	}
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate 	/*
4867c478bd9Sstevel@tonic-gate 	 * we set the search filter to (objectclass=*) when we want
4877c478bd9Sstevel@tonic-gate 	 * to list the directory attribute instead of the entries
4887c478bd9Sstevel@tonic-gate 	 * (the -d option).
4897c478bd9Sstevel@tonic-gate 	 */
4907c478bd9Sstevel@tonic-gate 	if (((ldapfilter = set_filter(key, database, &udata)) == NULL) ||
491*e1dd0a2fSth 	    (listflag == NS_LDAP_SCOPE_BASE)) {
4927c478bd9Sstevel@tonic-gate 		ldapfilter = strdup("objectclass=*");
4937c478bd9Sstevel@tonic-gate 		udata = strdup("%s");
4947c478bd9Sstevel@tonic-gate 	}
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 	if (verbose) {
497b446700bSjanga 		(void) fprintf(stdout, gettext("+++ database=%s\n"),
498*e1dd0a2fSth 		    (database ? database : "NULL"));
499b446700bSjanga 		(void) fprintf(stdout, gettext("+++ filter=%s\n"),
500*e1dd0a2fSth 		    (ldapfilter ? ldapfilter : "NULL"));
501b446700bSjanga 		(void) fprintf(stdout,
502*e1dd0a2fSth 		    gettext("+++ template for merging SSD filter=%s\n"),
503*e1dd0a2fSth 		    (udata ? udata : "NULL"));
5047c478bd9Sstevel@tonic-gate 	}
5057c478bd9Sstevel@tonic-gate 	if (rc = list(database, ldapfilter, ldapattribute, &err, udata))
506b446700bSjanga 		(void) fprintf(stderr, gettext("ldaplist: %s\n"), err);
507*e1dd0a2fSth 
508*e1dd0a2fSth 	__ns_ldap_cancelStandalone();
509*e1dd0a2fSth 
5107c478bd9Sstevel@tonic-gate 	if (ldapfilter)
5117c478bd9Sstevel@tonic-gate 		free(ldapfilter);
5127c478bd9Sstevel@tonic-gate 	if (udata)
5137c478bd9Sstevel@tonic-gate 		free(udata);
5147c478bd9Sstevel@tonic-gate 	exit(switch_err(rc));
515b446700bSjanga 	return (0); /* Never reached */
5167c478bd9Sstevel@tonic-gate }
517