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 /*
229f2fd570SJulian Pullen * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
23528b7d8bSRichard Lowe * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate #include <stdio.h>
287c478bd9Sstevel@tonic-gate #include <stdlib.h>
297c478bd9Sstevel@tonic-gate #include <libintl.h>
307c478bd9Sstevel@tonic-gate #include <strings.h>
317c478bd9Sstevel@tonic-gate #include <locale.h>
327c478bd9Sstevel@tonic-gate #include <syslog.h>
33e1dd0a2fSth
34e1dd0a2fSth #include "standalone.h"
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate extern char *set_filter(char **, char *, char **);
377c478bd9Sstevel@tonic-gate extern char *set_filter_publickey(char **, char *, int, char **);
387c478bd9Sstevel@tonic-gate extern void _printResult(ns_ldap_result_t *);
39b446700bSjanga extern void printMapping();
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate int listflag = 0;
427c478bd9Sstevel@tonic-gate
439f2fd570SJulian Pullen
449f2fd570SJulian Pullen
459f2fd570SJulian Pullen static struct database_t {
469f2fd570SJulian Pullen const char *database;
479f2fd570SJulian Pullen const char *sortattr;
489f2fd570SJulian Pullen }databaselist[] = {
499f2fd570SJulian Pullen { NS_LDAP_TYPE_HOSTS, "cn" },
509f2fd570SJulian Pullen { NS_LDAP_TYPE_IPNODES, "cn" },
519f2fd570SJulian Pullen { NS_LDAP_TYPE_RPC, "cn" },
529f2fd570SJulian Pullen { NS_LDAP_TYPE_PROTOCOLS, "cn" },
539f2fd570SJulian Pullen { NS_LDAP_TYPE_NETWORKS, "ipnetworknumber" },
549f2fd570SJulian Pullen { NS_LDAP_TYPE_SERVICES, "cn" },
559f2fd570SJulian Pullen { NS_LDAP_TYPE_GROUP, "gidnumber" },
569f2fd570SJulian Pullen { NS_LDAP_TYPE_NETMASKS, "ipnetworknumber"},
579f2fd570SJulian Pullen { NS_LDAP_TYPE_ETHERS, "cn" },
589f2fd570SJulian Pullen { NS_LDAP_TYPE_NETGROUP, "cn" },
599f2fd570SJulian Pullen { NS_LDAP_TYPE_BOOTPARAMS, "cn" },
609f2fd570SJulian Pullen { NS_LDAP_TYPE_PUBLICKEY, "cn" },
619f2fd570SJulian Pullen { NS_LDAP_TYPE_PASSWD, "uid" },
629f2fd570SJulian Pullen { NS_LDAP_TYPE_SHADOW, "uid" },
639f2fd570SJulian Pullen { NS_LDAP_TYPE_ALIASES, "cn" },
649f2fd570SJulian Pullen { NS_LDAP_TYPE_AUTOMOUNT, "automountKey" },
659f2fd570SJulian Pullen { NS_LDAP_TYPE_USERATTR, "uid" },
669f2fd570SJulian Pullen { NS_LDAP_TYPE_PROFILE, "cn" },
679f2fd570SJulian Pullen { NS_LDAP_TYPE_EXECATTR, "cn" },
689f2fd570SJulian Pullen { NS_LDAP_TYPE_AUTHATTR, "cn" },
699f2fd570SJulian Pullen { NS_LDAP_TYPE_AUUSER, "uid" },
709f2fd570SJulian Pullen { NS_LDAP_TYPE_TNRHDB, "ipTnetNumber" },
719f2fd570SJulian Pullen { NS_LDAP_TYPE_TNRHTP, "ipTnetTemplateName" },
729f2fd570SJulian Pullen { NS_LDAP_TYPE_PROJECT, "SolarisProjectName" },
739f2fd570SJulian Pullen { 0, 0 }
749f2fd570SJulian Pullen };
759f2fd570SJulian Pullen
769f2fd570SJulian Pullen
777c478bd9Sstevel@tonic-gate void
usage(char * msg)78*c59d9dffSToomas Soome usage(char *msg)
79*c59d9dffSToomas Soome {
807c478bd9Sstevel@tonic-gate if (msg)
81b446700bSjanga (void) fprintf(stderr, "%s\n", msg);
827c478bd9Sstevel@tonic-gate
83*c59d9dffSToomas Soome (void) fprintf(stderr, gettext(
84e1dd0a2fSth "\n"
85e1dd0a2fSth "usage: ldaplist [-dlv] [-h LDAP_server[:serverPort] [-M domainName]\n"
86e1dd0a2fSth "[-N profileName] [-a authenticationMethod] [-P certifPath]\n"
87e1dd0a2fSth "[-D bindDN] [-w bindPassword] [-j passwdFile]]\n"
88e1dd0a2fSth "[<database> [<key>] ...]\n\n"
89e1dd0a2fSth "usage: ldaplist -h\n"
90e1dd0a2fSth "\n"
91e1dd0a2fSth "usage: ldaplist -g\n\n"
927c478bd9Sstevel@tonic-gate "\tOptions:\n"
937c478bd9Sstevel@tonic-gate "\t -l list all the attributes found in entry.\n"
947c478bd9Sstevel@tonic-gate "\t By default, it lists only the DNs.\n"
957c478bd9Sstevel@tonic-gate "\t -d list attributes for the database instead of its entries\n"
967c478bd9Sstevel@tonic-gate "\t -v print out the LDAP search filter.\n"
97e1dd0a2fSth "\t -g list the database mappings.\n"
98e1dd0a2fSth "\t -h An address (or a name) and a port of the LDAP server in\n"
99e1dd0a2fSth "\t which the entries will be stored. The default value for\n"
100e1dd0a2fSth "\t the port is 389 (or 636 for TLS connections).\n"
101e1dd0a2fSth "\t -M The name of a domain served by the specified server.\n"
102e1dd0a2fSth "\t If not specified, the default domain name will be used.\n"
103e1dd0a2fSth "\t -N Specifies a DUAProfile name.\n"
104e1dd0a2fSth "\t The default value is \"default\".\n"
105e1dd0a2fSth "\t -a Specifies an authentication method.\n"
106e1dd0a2fSth "\t -P The certificate path for the location of the certificate\n"
107e1dd0a2fSth "\t database.\n"
108e1dd0a2fSth "\t -D Specifies an entry which has read permission to\n"
109e1dd0a2fSth "\t the requested database.\n"
110e1dd0a2fSth "\t -w Password to be used for authenticating the bindDN.\n"
111e1dd0a2fSth "\t -j File containing the password for bindDN or SSL key db.\n"
1127c478bd9Sstevel@tonic-gate "\t<database> is the database to be searched in. Standard system\n"
1137c478bd9Sstevel@tonic-gate "\tdatabases are:\n"
1147c478bd9Sstevel@tonic-gate "\t\tpassword, printers, group, hosts, ethers, networks, netmasks,\n"
1157c478bd9Sstevel@tonic-gate "\t\trpc, bootparams, protocols, services, netgroup, auto_*.\n"
1167c478bd9Sstevel@tonic-gate "\tNon-standard system databases can be specified as follows:\n"
1177c478bd9Sstevel@tonic-gate "\t\tby specific container: ou=<dbname> or\n"
1187c478bd9Sstevel@tonic-gate "\t\tby default container: <dbname>. In this case, 'nismapname'\n"
1197c478bd9Sstevel@tonic-gate "\t\twill be used, thus mapping this to nismapname=<dbname>.\n"
1207c478bd9Sstevel@tonic-gate "\t<key> is the key to search in the database. For the standard\n"
1217c478bd9Sstevel@tonic-gate "\tdatabases, the search type for the key is predefined. You can\n"
122e1dd0a2fSth "\toverride this by specifying <type>=<key>.\n"
123e1dd0a2fSth "\nNOTE: The old -h option printing the mapping information is "
124e1dd0a2fSth "deprecated.\nFor backward compatibility the following mode is "
125e1dd0a2fSth "available:\nldaplist -h\n"));
1267c478bd9Sstevel@tonic-gate exit(1);
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate /*
1307c478bd9Sstevel@tonic-gate * This is a generic filter call back function for
1317c478bd9Sstevel@tonic-gate * merging the filter from service search descriptor with
1327c478bd9Sstevel@tonic-gate * an existing search filter. This routine expects userdata
1337c478bd9Sstevel@tonic-gate * contain a format string with a single %s in it, and will
1347c478bd9Sstevel@tonic-gate * use the format string with sprintf() to insert the SSD filter.
1357c478bd9Sstevel@tonic-gate *
1367c478bd9Sstevel@tonic-gate * This routine is passed to the __ns_ldap_list() or
1377c478bd9Sstevel@tonic-gate * __ns_ldap_firstEntry() APIs as the filter call back
1387c478bd9Sstevel@tonic-gate * together with the userdata. For example,
1397c478bd9Sstevel@tonic-gate * the "ldaplist hosts sys1" processing may call __ns_ldap_list()
1407c478bd9Sstevel@tonic-gate * with "(&(objectClass=ipHost)(cn=sys1))" as filter, this function
1417c478bd9Sstevel@tonic-gate * as the filter call back, and "(&(%s)(cn=sys1))" as the
1427c478bd9Sstevel@tonic-gate * userdata, this routine will in turn gets call to produce
1437c478bd9Sstevel@tonic-gate * "(&(department=sds)(cn=sys1))" as the real search
1447c478bd9Sstevel@tonic-gate * filter, if the input SSD contains a filter "department=sds".
1457c478bd9Sstevel@tonic-gate */
1467c478bd9Sstevel@tonic-gate static int
merge_SSD_filter(const ns_ldap_search_desc_t * desc,char ** realfilter,const void * userdata)147*c59d9dffSToomas Soome merge_SSD_filter(const ns_ldap_search_desc_t *desc, char **realfilter,
148*c59d9dffSToomas Soome const void *userdata)
1497c478bd9Sstevel@tonic-gate {
1507c478bd9Sstevel@tonic-gate int len;
151528b7d8bSRichard Lowe char *checker;
1527c478bd9Sstevel@tonic-gate
1537c478bd9Sstevel@tonic-gate /* sanity check */
1547c478bd9Sstevel@tonic-gate if (realfilter == NULL)
1557c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM);
1567c478bd9Sstevel@tonic-gate *realfilter = NULL;
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate if (desc == NULL || desc->filter == NULL ||
159e1dd0a2fSth userdata == NULL)
1607c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM);
1617c478bd9Sstevel@tonic-gate
162528b7d8bSRichard Lowe /* Parameter check. We only want one %s here, otherwise bail. */
163528b7d8bSRichard Lowe len = 0; /* Reuse 'len' as "Number of %s hits"... */
164528b7d8bSRichard Lowe checker = (char *)userdata;
165528b7d8bSRichard Lowe do {
166528b7d8bSRichard Lowe checker = strchr(checker, '%');
167528b7d8bSRichard Lowe if (checker != NULL) {
168528b7d8bSRichard Lowe if (len > 0 || *(checker + 1) != 's')
169528b7d8bSRichard Lowe return (NS_LDAP_INVALID_PARAM);
170528b7d8bSRichard Lowe len++; /* Got our %s. */
171528b7d8bSRichard Lowe checker += 2;
172528b7d8bSRichard Lowe } else if (len != 1)
173528b7d8bSRichard Lowe return (NS_LDAP_INVALID_PARAM);
174528b7d8bSRichard Lowe } while (checker != NULL);
175528b7d8bSRichard Lowe
1767c478bd9Sstevel@tonic-gate len = strlen(userdata) + strlen(desc->filter) + 1;
1777c478bd9Sstevel@tonic-gate
1787c478bd9Sstevel@tonic-gate *realfilter = (char *)malloc(len);
1797c478bd9Sstevel@tonic-gate if (*realfilter == NULL)
1807c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY);
1817c478bd9Sstevel@tonic-gate
1827c478bd9Sstevel@tonic-gate (void) sprintf(*realfilter, (char *)userdata,
183e1dd0a2fSth desc->filter);
1847c478bd9Sstevel@tonic-gate
1857c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS);
1867c478bd9Sstevel@tonic-gate }
1877c478bd9Sstevel@tonic-gate
1887c478bd9Sstevel@tonic-gate /* returns 0=success, 1=error */
1897c478bd9Sstevel@tonic-gate int
list(char * database,char * ldapfilter,char ** ldapattribute,char ** err,char * userdata)1907c478bd9Sstevel@tonic-gate list(char *database, char *ldapfilter, char **ldapattribute,
191*c59d9dffSToomas Soome char **err, char *userdata)
1927c478bd9Sstevel@tonic-gate {
1937c478bd9Sstevel@tonic-gate ns_ldap_result_t *result;
1947c478bd9Sstevel@tonic-gate ns_ldap_error_t *errorp;
1957c478bd9Sstevel@tonic-gate int rc;
1967c478bd9Sstevel@tonic-gate char buf[500];
197*c59d9dffSToomas Soome const char *sort = NULL;
1989f2fd570SJulian Pullen int i;
1999f2fd570SJulian Pullen
2009f2fd570SJulian Pullen if (database) {
2019f2fd570SJulian Pullen for (i = 0; databaselist[i].database; i++) {
2029f2fd570SJulian Pullen if (strcmp(databaselist[i].database, database) == 0) {
2039f2fd570SJulian Pullen sort = databaselist[i].sortattr;
2049f2fd570SJulian Pullen break;
2059f2fd570SJulian Pullen }
2069f2fd570SJulian Pullen if (strcmp(databaselist[i].database,
2079f2fd570SJulian Pullen NS_LDAP_TYPE_AUTOMOUNT) == 0 &&
2089f2fd570SJulian Pullen strncmp(database, NS_LDAP_TYPE_AUTOMOUNT,
2099f2fd570SJulian Pullen sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0) {
2109f2fd570SJulian Pullen sort = databaselist[i].sortattr;
2119f2fd570SJulian Pullen break;
2129f2fd570SJulian Pullen }
2139f2fd570SJulian Pullen }
2149f2fd570SJulian Pullen }
2157c478bd9Sstevel@tonic-gate
2167c478bd9Sstevel@tonic-gate *err = NULL;
2177c478bd9Sstevel@tonic-gate buf[0] = '\0';
2189f2fd570SJulian Pullen rc = __ns_ldap_list_sort(database, (const char *)ldapfilter,
2199f2fd570SJulian Pullen sort, merge_SSD_filter, (const char **)ldapattribute, NULL,
220e1dd0a2fSth listflag, &result, &errorp, NULL, userdata);
2217c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) {
2227c478bd9Sstevel@tonic-gate char *p;
2237c478bd9Sstevel@tonic-gate (void) __ns_ldap_err2str(rc, &p);
2247c478bd9Sstevel@tonic-gate if (errorp && errorp->message) {
225b446700bSjanga (void) snprintf(buf, sizeof (buf), "%s (%s)",
226e1dd0a2fSth p, errorp->message);
227b446700bSjanga (void) __ns_ldap_freeError(&errorp);
2287c478bd9Sstevel@tonic-gate } else
229e1dd0a2fSth (void) snprintf(buf, sizeof (buf), "%s\n", p);
2307c478bd9Sstevel@tonic-gate *err = strdup(buf);
2317c478bd9Sstevel@tonic-gate return (rc);
2327c478bd9Sstevel@tonic-gate }
2337c478bd9Sstevel@tonic-gate
2347c478bd9Sstevel@tonic-gate _printResult(result);
235b446700bSjanga (void) __ns_ldap_freeResult(&result);
2367c478bd9Sstevel@tonic-gate return (0);
2377c478bd9Sstevel@tonic-gate }
2387c478bd9Sstevel@tonic-gate
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate int
switch_err(int rc)2417c478bd9Sstevel@tonic-gate switch_err(int rc)
2427c478bd9Sstevel@tonic-gate {
2437c478bd9Sstevel@tonic-gate switch (rc) {
2447c478bd9Sstevel@tonic-gate case NS_LDAP_SUCCESS:
2457c478bd9Sstevel@tonic-gate return (0);
2467c478bd9Sstevel@tonic-gate case NS_LDAP_NOTFOUND:
2477c478bd9Sstevel@tonic-gate return (1);
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate return (2);
2507c478bd9Sstevel@tonic-gate }
2517c478bd9Sstevel@tonic-gate
252a506a34cSth int
main(int argc,char ** argv)2537c478bd9Sstevel@tonic-gate main(int argc, char **argv)
2547c478bd9Sstevel@tonic-gate {
2557c478bd9Sstevel@tonic-gate
256e1dd0a2fSth extern int optind;
257e1dd0a2fSth char *database = NULL;
258e1dd0a2fSth char *ldapfilter = NULL;
259e1dd0a2fSth char *attribute = "dn";
260e1dd0a2fSth char **key = NULL;
261e1dd0a2fSth char **ldapattribute = NULL;
262*c59d9dffSToomas Soome char *buffer[100];
263e1dd0a2fSth char *err = NULL;
264e1dd0a2fSth char *p;
265e1dd0a2fSth int index = 1;
266e1dd0a2fSth int c;
267e1dd0a2fSth int rc;
268e1dd0a2fSth int verbose = 0;
269e1dd0a2fSth char *udata = NULL;
270e1dd0a2fSth
271e1dd0a2fSth ns_standalone_conf_t standalone_cfg = standaloneDefaults;
272e1dd0a2fSth ns_ldap_error_t *errorp = NULL;
273e1dd0a2fSth char *authmech = NULL;
274e1dd0a2fSth ns_auth_t auth = {NS_LDAP_AUTH_NONE,
275e1dd0a2fSth NS_LDAP_TLS_NONE,
276e1dd0a2fSth NS_LDAP_SASL_NONE,
277e1dd0a2fSth NS_LDAP_SASLOPT_NONE};
2787c478bd9Sstevel@tonic-gate
2797c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
2807c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate openlog("ldaplist", LOG_PID, LOG_USER);
2837c478bd9Sstevel@tonic-gate
284e1dd0a2fSth if (argc == 2 &&
285e1dd0a2fSth strlen(argv[1]) == 2 && strncmp(argv[1], "-h", 2) == 0) {
286e1dd0a2fSth /* preserve backwards compatability, support old -h option */
287e1dd0a2fSth (void) printMapping();
288e1dd0a2fSth exit(0);
289e1dd0a2fSth }
290e1dd0a2fSth
291e1dd0a2fSth while ((c = getopt(argc, argv, "h:M:N:P:r:a:D:w:j:dgvl")) != EOF) {
2927c478bd9Sstevel@tonic-gate switch (c) {
2937c478bd9Sstevel@tonic-gate case 'd':
2947c478bd9Sstevel@tonic-gate listflag |= NS_LDAP_SCOPE_BASE;
2957c478bd9Sstevel@tonic-gate break;
296e1dd0a2fSth case 'g':
2977c478bd9Sstevel@tonic-gate (void) printMapping();
2987c478bd9Sstevel@tonic-gate exit(0);
299b446700bSjanga break; /* Never reached */
3007c478bd9Sstevel@tonic-gate case 'l':
3017c478bd9Sstevel@tonic-gate attribute = "NULL";
3027c478bd9Sstevel@tonic-gate break;
3037c478bd9Sstevel@tonic-gate case 'v':
3047c478bd9Sstevel@tonic-gate verbose = 1;
3057c478bd9Sstevel@tonic-gate break;
306e1dd0a2fSth case 'M':
307e1dd0a2fSth standalone_cfg.type = NS_LDAP_SERVER;
308e1dd0a2fSth standalone_cfg.SA_DOMAIN = optarg;
309e1dd0a2fSth break;
310e1dd0a2fSth case 'h':
311e1dd0a2fSth standalone_cfg.type = NS_LDAP_SERVER;
312e1dd0a2fSth if (separatePort(optarg,
313e1dd0a2fSth &standalone_cfg.SA_SERVER,
314e1dd0a2fSth &standalone_cfg.SA_PORT) > 0) {
315e1dd0a2fSth exit(1);
316e1dd0a2fSth }
317e1dd0a2fSth break;
318e1dd0a2fSth case 'P':
319e1dd0a2fSth standalone_cfg.type = NS_LDAP_SERVER;
320e1dd0a2fSth standalone_cfg.SA_CERT_PATH = optarg;
321e1dd0a2fSth break;
322e1dd0a2fSth case 'N':
323e1dd0a2fSth standalone_cfg.type = NS_LDAP_SERVER;
324e1dd0a2fSth standalone_cfg.SA_PROFILE_NAME = optarg;
325e1dd0a2fSth break;
326e1dd0a2fSth case 'D':
327e1dd0a2fSth standalone_cfg.type = NS_LDAP_SERVER;
328e1dd0a2fSth standalone_cfg.SA_BIND_DN = strdup(optarg);
329e1dd0a2fSth break;
330e1dd0a2fSth case 'w':
331e1dd0a2fSth if (standalone_cfg.SA_BIND_PWD != NULL) {
332e1dd0a2fSth (void) fprintf(stderr,
333e1dd0a2fSth gettext("The -w option is mutually "
334e1dd0a2fSth "exclusive of -j. -w is ignored.\n"));
335e1dd0a2fSth break;
336e1dd0a2fSth }
337e1dd0a2fSth
338e1dd0a2fSth if (optarg != NULL &&
339e1dd0a2fSth optarg[0] == '-' && optarg[1] == '\0') {
340e1dd0a2fSth /* Ask for a password later */
341e1dd0a2fSth break;
342e1dd0a2fSth }
343e1dd0a2fSth
344e1dd0a2fSth standalone_cfg.type = NS_LDAP_SERVER;
345e1dd0a2fSth standalone_cfg.SA_BIND_PWD = strdup(optarg);
346e1dd0a2fSth break;
347e1dd0a2fSth case 'j':
348e1dd0a2fSth if (standalone_cfg.SA_BIND_PWD != NULL) {
349e1dd0a2fSth (void) fprintf(stderr,
350e1dd0a2fSth gettext("The -w option is mutually "
351e1dd0a2fSth "exclusive of -j. -w is ignored.\n"));
352e1dd0a2fSth free(standalone_cfg.SA_BIND_PWD);
353e1dd0a2fSth }
354e1dd0a2fSth standalone_cfg.type = NS_LDAP_SERVER;
355e1dd0a2fSth standalone_cfg.SA_BIND_PWD = readPwd(optarg);
356e1dd0a2fSth if (standalone_cfg.SA_BIND_PWD == NULL) {
357e1dd0a2fSth exit(1);
358e1dd0a2fSth }
359e1dd0a2fSth break;
360e1dd0a2fSth case 'a':
361e1dd0a2fSth authmech = optarg;
362e1dd0a2fSth break;
3637c478bd9Sstevel@tonic-gate default:
3647c478bd9Sstevel@tonic-gate usage(gettext("Invalid option"));
3657c478bd9Sstevel@tonic-gate }
3667c478bd9Sstevel@tonic-gate }
367e1dd0a2fSth
368e1dd0a2fSth if (standalone_cfg.type == NS_LDAP_SERVER &&
369e1dd0a2fSth standalone_cfg.SA_SERVER == NULL) {
370e1dd0a2fSth (void) fprintf(stderr,
371e1dd0a2fSth gettext("Please specify an LDAP server you want "
372e1dd0a2fSth "to connect to. \n"));
373e1dd0a2fSth exit(1);
374e1dd0a2fSth }
375e1dd0a2fSth
3767c478bd9Sstevel@tonic-gate if ((c = argc - optind) > 0)
3777c478bd9Sstevel@tonic-gate database = argv[optind++];
3787c478bd9Sstevel@tonic-gate if ((--c) > 0)
3797c478bd9Sstevel@tonic-gate key = &argv[optind];
3807c478bd9Sstevel@tonic-gate
381e1dd0a2fSth if (authmech != NULL) {
382e1dd0a2fSth if (__ns_ldap_initAuth(authmech,
383e1dd0a2fSth &auth,
384e1dd0a2fSth &errorp) != NS_LDAP_SUCCESS) {
385e1dd0a2fSth if (errorp) {
386e1dd0a2fSth (void) fprintf(stderr, "%s", errorp->message);
387e1dd0a2fSth (void) __ns_ldap_freeError(&errorp);
388e1dd0a2fSth }
389e1dd0a2fSth exit(1);
390e1dd0a2fSth }
391e1dd0a2fSth }
392e1dd0a2fSth
393e1dd0a2fSth if (auth.saslmech != NS_LDAP_SASL_GSSAPI &&
394e1dd0a2fSth standalone_cfg.SA_BIND_DN != NULL &&
395e1dd0a2fSth standalone_cfg.SA_BIND_PWD == NULL) {
396e1dd0a2fSth /* If password is not specified, then prompt user for it. */
397e1dd0a2fSth standalone_cfg.SA_BIND_PWD =
398e1dd0a2fSth strdup(getpassphrase("Enter password:"));
399e1dd0a2fSth }
400e1dd0a2fSth
401e1dd0a2fSth standalone_cfg.SA_AUTH = (authmech == NULL) ? NULL : &auth;
402e1dd0a2fSth
403e1dd0a2fSth if (__ns_ldap_initStandalone(&standalone_cfg,
404e1dd0a2fSth &errorp) != NS_LDAP_SUCCESS) {
405e1dd0a2fSth if (errorp) {
406e1dd0a2fSth (void) fprintf(stderr, "%s\n", errorp->message);
407e1dd0a2fSth (void) __ns_ldap_freeError(&errorp);
408e1dd0a2fSth }
409e1dd0a2fSth exit(1);
410e1dd0a2fSth }
411e1dd0a2fSth
412e1dd0a2fSth if (authmech != NULL) {
413e1dd0a2fSth if (__ns_ldap_setParam(NS_LDAP_AUTH_P,
414e1dd0a2fSth authmech, &errorp) != NS_LDAP_SUCCESS) {
415e1dd0a2fSth __ns_ldap_cancelStandalone();
416e1dd0a2fSth if (errorp != NULL) {
417e1dd0a2fSth (void) fprintf(stderr, "%s", errorp->message);
418e1dd0a2fSth (void) __ns_ldap_freeError(&errorp);
419e1dd0a2fSth }
420e1dd0a2fSth exit(1);
421e1dd0a2fSth }
422e1dd0a2fSth }
423e1dd0a2fSth if (standalone_cfg.SA_CRED != NULL) {
424e1dd0a2fSth if (__ns_ldap_setParam(NS_LDAP_CREDENTIAL_LEVEL_P,
425e1dd0a2fSth standalone_cfg.SA_CRED, &errorp) != NS_LDAP_SUCCESS) {
426e1dd0a2fSth __ns_ldap_cancelStandalone();
427e1dd0a2fSth if (errorp != NULL) {
428e1dd0a2fSth (void) fprintf(stderr, "%s", errorp->message);
429e1dd0a2fSth (void) __ns_ldap_freeError(&errorp);
430e1dd0a2fSth }
431e1dd0a2fSth exit(1);
432e1dd0a2fSth }
433e1dd0a2fSth }
434e1dd0a2fSth
435e1dd0a2fSth if (standalone_cfg.type != NS_CACHEMGR &&
436e1dd0a2fSth standalone_cfg.SA_BIND_DN != NULL) {
437e1dd0a2fSth ns_auth_t **authpp = NULL, **authp = NULL;
438e1dd0a2fSth
439e1dd0a2fSth if (__ns_ldap_getParam(NS_LDAP_AUTH_P,
440e1dd0a2fSth (void ***)&authpp,
441e1dd0a2fSth &errorp) != NS_LDAP_SUCCESS || authpp == NULL) {
442e1dd0a2fSth __ns_ldap_cancelStandalone();
443e1dd0a2fSth (void) __ns_ldap_freeParam((void ***)&authpp);
444e1dd0a2fSth if (errorp) {
445e1dd0a2fSth (void) fprintf(stderr,
446e1dd0a2fSth gettext(errorp->message));
447e1dd0a2fSth (void) __ns_ldap_freeError(&errorp);
448e1dd0a2fSth }
449e1dd0a2fSth exit(1);
450e1dd0a2fSth }
451e1dd0a2fSth for (authp = authpp; *authp; authp++) {
452e1dd0a2fSth if ((*authp)->saslmech == NS_LDAP_SASL_GSSAPI) {
453e1dd0a2fSth /*
454e1dd0a2fSth * For now we have no use for bindDN and
455e1dd0a2fSth * bindPassword when using SASL/GSSAPI.
456e1dd0a2fSth */
457e1dd0a2fSth (void) fprintf(stderr,
458e1dd0a2fSth gettext("Warning: SASL/GSSAPI will be "
459e1dd0a2fSth "used as an authentication method"
460e1dd0a2fSth "The bind DN and password will "
461e1dd0a2fSth "be ignored.\n"));
462e1dd0a2fSth break;
463e1dd0a2fSth }
464e1dd0a2fSth }
465e1dd0a2fSth }
466e1dd0a2fSth
4677c478bd9Sstevel@tonic-gate /*
4687c478bd9Sstevel@tonic-gate * If dumpping a database,
4697c478bd9Sstevel@tonic-gate * or all the containers,
4707c478bd9Sstevel@tonic-gate * use page control just
4717c478bd9Sstevel@tonic-gate * in case there are too many entries
4727c478bd9Sstevel@tonic-gate */
4737c478bd9Sstevel@tonic-gate if (!key && !(listflag & NS_LDAP_SCOPE_BASE))
4747c478bd9Sstevel@tonic-gate listflag |= NS_LDAP_PAGE_CTRL;
4757c478bd9Sstevel@tonic-gate
4767c478bd9Sstevel@tonic-gate /* build the attribute array */
4777c478bd9Sstevel@tonic-gate if (strncasecmp(attribute, "NULL", 4) == 0)
4787c478bd9Sstevel@tonic-gate ldapattribute = NULL;
4797c478bd9Sstevel@tonic-gate else {
4807c478bd9Sstevel@tonic-gate buffer[0] = strdup(attribute);
4817c478bd9Sstevel@tonic-gate while ((p = strchr(attribute, ',')) != NULL) {
4827c478bd9Sstevel@tonic-gate buffer[index++] = attribute = p + 1;
4837c478bd9Sstevel@tonic-gate *p = '\0';
4847c478bd9Sstevel@tonic-gate }
4857c478bd9Sstevel@tonic-gate buffer[index] = NULL;
4867c478bd9Sstevel@tonic-gate ldapattribute = buffer;
4877c478bd9Sstevel@tonic-gate }
4887c478bd9Sstevel@tonic-gate
4897c478bd9Sstevel@tonic-gate /* build the filter */
490*c59d9dffSToomas Soome if (database && (strcasecmp(database, "publickey") == 0)) {
4917c478bd9Sstevel@tonic-gate /* user publickey lookup */
4927c478bd9Sstevel@tonic-gate char *err1 = NULL;
4937c478bd9Sstevel@tonic-gate int rc1;
4947c478bd9Sstevel@tonic-gate
4957c478bd9Sstevel@tonic-gate rc = rc1 = -1;
4967c478bd9Sstevel@tonic-gate ldapfilter = set_filter_publickey(key, database, 0, &udata);
4977c478bd9Sstevel@tonic-gate if (ldapfilter) {
4987c478bd9Sstevel@tonic-gate if (verbose) {
499b446700bSjanga (void) fprintf(stdout,
500e1dd0a2fSth gettext("+++ database=%s\n"),
501e1dd0a2fSth (database ? database : "NULL"));
502b446700bSjanga (void) fprintf(stdout,
503e1dd0a2fSth gettext("+++ filter=%s\n"),
504e1dd0a2fSth (ldapfilter ? ldapfilter : "NULL"));
505b446700bSjanga (void) fprintf(stdout,
5067c478bd9Sstevel@tonic-gate gettext("+++ template for merging"
507e1dd0a2fSth "SSD filter=%s\n"),
508e1dd0a2fSth (udata ? udata : "NULL"));
5097c478bd9Sstevel@tonic-gate }
5107c478bd9Sstevel@tonic-gate rc = list("passwd", ldapfilter, ldapattribute,
511e1dd0a2fSth &err, udata);
5127c478bd9Sstevel@tonic-gate free(ldapfilter);
5137c478bd9Sstevel@tonic-gate free(udata);
5147c478bd9Sstevel@tonic-gate }
5157c478bd9Sstevel@tonic-gate /* hosts publickey lookup */
5167c478bd9Sstevel@tonic-gate ldapfilter = set_filter_publickey(key, database, 1, &udata);
5177c478bd9Sstevel@tonic-gate if (ldapfilter) {
5187c478bd9Sstevel@tonic-gate if (verbose) {
519b446700bSjanga (void) fprintf(stdout,
520e1dd0a2fSth gettext("+++ database=%s\n"),
521e1dd0a2fSth (database ? database : "NULL"));
522b446700bSjanga (void) fprintf(stdout,
523e1dd0a2fSth gettext("+++ filter=%s\n"),
524e1dd0a2fSth (ldapfilter ? ldapfilter : "NULL"));
525b446700bSjanga (void) fprintf(stdout,
5267c478bd9Sstevel@tonic-gate gettext("+++ template for merging"
527e1dd0a2fSth "SSD filter=%s\n"),
528e1dd0a2fSth (udata ? udata : "NULL"));
5297c478bd9Sstevel@tonic-gate }
5307c478bd9Sstevel@tonic-gate rc1 = list("hosts", ldapfilter, ldapattribute,
531e1dd0a2fSth &err1, udata);
5327c478bd9Sstevel@tonic-gate free(ldapfilter);
5337c478bd9Sstevel@tonic-gate free(udata);
5347c478bd9Sstevel@tonic-gate }
5357c478bd9Sstevel@tonic-gate if (rc == -1 && rc1 == -1) {
5367c478bd9Sstevel@tonic-gate /* this should never happen */
537b446700bSjanga (void) fprintf(stderr,
5387c478bd9Sstevel@tonic-gate gettext("ldaplist: invalid publickey lookup\n"));
5397c478bd9Sstevel@tonic-gate rc = 2;
5405aa2fb58SChin-Long Shu } else if (rc != 0 && rc1 != 0) {
541b446700bSjanga (void) fprintf(stderr,
5427c478bd9Sstevel@tonic-gate gettext("ldaplist: %s\n"), (err ? err : err1));
5437c478bd9Sstevel@tonic-gate if (rc == -1)
5447c478bd9Sstevel@tonic-gate rc = rc1;
5457c478bd9Sstevel@tonic-gate } else
5467c478bd9Sstevel@tonic-gate rc = 0;
5477c478bd9Sstevel@tonic-gate exit(switch_err(rc));
5487c478bd9Sstevel@tonic-gate }
5497c478bd9Sstevel@tonic-gate
5507c478bd9Sstevel@tonic-gate /*
5517c478bd9Sstevel@tonic-gate * we set the search filter to (objectclass=*) when we want
5527c478bd9Sstevel@tonic-gate * to list the directory attribute instead of the entries
5537c478bd9Sstevel@tonic-gate * (the -d option).
5547c478bd9Sstevel@tonic-gate */
5557c478bd9Sstevel@tonic-gate if (((ldapfilter = set_filter(key, database, &udata)) == NULL) ||
556e1dd0a2fSth (listflag == NS_LDAP_SCOPE_BASE)) {
5577c478bd9Sstevel@tonic-gate ldapfilter = strdup("objectclass=*");
5587c478bd9Sstevel@tonic-gate udata = strdup("%s");
5597c478bd9Sstevel@tonic-gate }
5607c478bd9Sstevel@tonic-gate
5617c478bd9Sstevel@tonic-gate if (verbose) {
562b446700bSjanga (void) fprintf(stdout, gettext("+++ database=%s\n"),
563e1dd0a2fSth (database ? database : "NULL"));
564b446700bSjanga (void) fprintf(stdout, gettext("+++ filter=%s\n"),
565e1dd0a2fSth (ldapfilter ? ldapfilter : "NULL"));
566b446700bSjanga (void) fprintf(stdout,
567e1dd0a2fSth gettext("+++ template for merging SSD filter=%s\n"),
568e1dd0a2fSth (udata ? udata : "NULL"));
5697c478bd9Sstevel@tonic-gate }
5707c478bd9Sstevel@tonic-gate if (rc = list(database, ldapfilter, ldapattribute, &err, udata))
571b446700bSjanga (void) fprintf(stderr, gettext("ldaplist: %s\n"), err);
572e1dd0a2fSth
573e1dd0a2fSth __ns_ldap_cancelStandalone();
574e1dd0a2fSth
5757c478bd9Sstevel@tonic-gate if (ldapfilter)
5767c478bd9Sstevel@tonic-gate free(ldapfilter);
5777c478bd9Sstevel@tonic-gate if (udata)
5787c478bd9Sstevel@tonic-gate free(udata);
5797c478bd9Sstevel@tonic-gate exit(switch_err(rc));
580b446700bSjanga return (0); /* Never reached */
5817c478bd9Sstevel@tonic-gate }
582