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  */
21*1676Sjpk 
220Sstevel@tonic-gate /*
231450Sjanga  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <ctype.h>
300Sstevel@tonic-gate #include <libintl.h>
310Sstevel@tonic-gate #include <strings.h>
320Sstevel@tonic-gate #include <stdio.h>
33*1676Sjpk #include <tsol/label.h>
340Sstevel@tonic-gate #include "../../../lib/libsldap/common/ns_sldap.h"
350Sstevel@tonic-gate 
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #define	SAME	0
380Sstevel@tonic-gate 
390Sstevel@tonic-gate struct mapping {
400Sstevel@tonic-gate 	char *database;
410Sstevel@tonic-gate 	char *def_type;
420Sstevel@tonic-gate 	char *objectclass;
430Sstevel@tonic-gate 	char *actual_db;
440Sstevel@tonic-gate };
450Sstevel@tonic-gate 
460Sstevel@tonic-gate #define	PUBLICKEY	0
470Sstevel@tonic-gate 
480Sstevel@tonic-gate static struct mapping maplist[] = {
490Sstevel@tonic-gate 	{"publickey", "uidnumber", "niskeyobject", "passwd"},
500Sstevel@tonic-gate 	{"publickey", "cn", "niskeyobject", "host"},
510Sstevel@tonic-gate 	{"bootparams", "cn", "bootableDevice", NULL},
520Sstevel@tonic-gate 	{"ethers", "cn", "ieee802Device", NULL},
530Sstevel@tonic-gate 	{"group", "cn", "posixgroup", NULL},
540Sstevel@tonic-gate 	{"hosts", "cn", "iphost", NULL},
550Sstevel@tonic-gate 	{"ipnodes", "cn", "iphost", NULL},
560Sstevel@tonic-gate 	{"netgroup", "cn", "nisnetgroup", NULL},
570Sstevel@tonic-gate 	{"netmasks", "ipnetworknumber", "ipnetwork", NULL},
580Sstevel@tonic-gate 	{"networks", "ipnetworknumber", "ipnetwork", NULL},
590Sstevel@tonic-gate 	{"passwd", "uid", "posixaccount", NULL},
600Sstevel@tonic-gate 	{"protocols", "cn", "ipprotocol", NULL},
610Sstevel@tonic-gate 	{"rpc", "cn", "oncrpc", NULL},
620Sstevel@tonic-gate 	{"services", "cn", "ipservice", NULL},
630Sstevel@tonic-gate 	{"aliases", "cn", "mailGroup", NULL},
640Sstevel@tonic-gate 	{"project", "SolarisProjectID", "SolarisProject", NULL},
650Sstevel@tonic-gate 	{"printers", "printer-uri", "sunPrinter", NULL},
660Sstevel@tonic-gate 	{"shadow", "uid", "shadowaccount", NULL},
670Sstevel@tonic-gate 	{"auth_attr", "cn", "SolarisAuthAttr", NULL},
680Sstevel@tonic-gate 	{"prof_attr", "cn", "SolarisProfAttr", NULL},
690Sstevel@tonic-gate 	{"exec_attr", "cn", "SolarisExecAttr", NULL},
700Sstevel@tonic-gate 	{"user_attr", "uid", "SolarisUserAttr", NULL},
710Sstevel@tonic-gate 	{"audit_user", "uid", "SolarisAuditUser", NULL},
72*1676Sjpk 	{"tnrhtp", "ipTnetTemplateName", "ipTnetTemplate", NULL},
73*1676Sjpk 	{"tnrhdb", "ipTnetNumber", "ipTnetHost", NULL},
740Sstevel@tonic-gate 	{NULL, NULL, NULL, NULL}
750Sstevel@tonic-gate };
760Sstevel@tonic-gate 
771450Sjanga /* Malloc and print error message in case of failure */
781450Sjanga #define	MALLOC(ptr, len) \
791450Sjanga 	if ((ptr = (char *)malloc(len)) == NULL) { \
801450Sjanga 		(void) fprintf(stderr, gettext("out of memory\n")); \
811450Sjanga 	}
821450Sjanga 
831450Sjanga /*
841450Sjanga  * Allocate memory for filter and user data. Set
851450Sjanga  * error to 1 if either of the mallocs fail.
861450Sjanga  * In addition, free the memory allocated for filter,
871450Sjanga  * if memory allocation for user data fails.
881450Sjanga  */
891450Sjanga #define	MALLOC_FILTER_UDATA(ptr1, len1, ptr2, len2, error) \
901450Sjanga 	error = 0; \
911450Sjanga 	MALLOC(ptr1, len1); \
921450Sjanga 	if (!ptr1) { \
931450Sjanga 		error = 1; \
941450Sjanga 	} \
951450Sjanga 	else { \
961450Sjanga 		MALLOC(ptr2, len2); \
971450Sjanga 		if (!ptr2) { \
981450Sjanga 			error = 1; \
991450Sjanga 			free(ptr1); \
1001450Sjanga 		} \
1011450Sjanga 	}
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate void
1040Sstevel@tonic-gate printMapping()
1050Sstevel@tonic-gate {
1060Sstevel@tonic-gate 	int	i;
1070Sstevel@tonic-gate 
1081450Sjanga 	(void) fprintf(stdout,
1090Sstevel@tonic-gate 		gettext("database       default type        objectclass\n"));
1101450Sjanga 	(void) fprintf(stdout,
1110Sstevel@tonic-gate 		gettext("=============  =================   =============\n"));
1120Sstevel@tonic-gate 	/* first dump auto_* and automount which are not in maplist[] */
1131450Sjanga 	(void) fprintf(stdout, "%-15s%-20s%s\n", "auto_*", "automountKey",
1140Sstevel@tonic-gate 		"automount");
1151450Sjanga 	(void) fprintf(stdout, "%-15s%-20s%s\n", "automount",
1161450Sjanga 		"automountMapName",
1170Sstevel@tonic-gate 		"automountMap");
1180Sstevel@tonic-gate 	for (i = 0; maplist[i].database != NULL; i++) {
119*1676Sjpk 		/* skip printing shadow */
120*1676Sjpk 		if (strcasecmp(maplist[i].database, "shadow") == 0)
121*1676Sjpk 			continue;
122*1676Sjpk 		if (!is_system_labeled()) {
123*1676Sjpk 			/*
124*1676Sjpk 			 * do not print tnrhdb and tnrhtp if system is
125*1676Sjpk 			 * not configured with Trusted Extensions
126*1676Sjpk 			 */
127*1676Sjpk 			if ((strcasecmp(maplist[i].database, "tnrhdb") == 0) ||
128*1676Sjpk 			    (strcasecmp(maplist[i].database, "tnrhtp") == 0))
129*1676Sjpk 				continue;
130*1676Sjpk 		}
1311450Sjanga 		(void) fprintf(stdout, "%-15s%-20s%s\n", maplist[i].database,
132*1676Sjpk 		    maplist[i].def_type, maplist[i].objectclass);
1330Sstevel@tonic-gate 	}
1340Sstevel@tonic-gate }
1350Sstevel@tonic-gate 
1361450Sjanga /*
1371450Sjanga  * set_key routine to handle user specified keys.
1381450Sjanga  * A key can be of the form: attribute=value or value.
1391450Sjanga  * A filter is constructed from a set of keys specified in
1401450Sjanga  * the form (|(key1)(key2)...(keyn))
1411450Sjanga  * It returns: NULL if no keys are defined or
1421450Sjanga  *		the keyfilter as constructed above.
1431450Sjanga  */
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate char *
1460Sstevel@tonic-gate set_keys(char **key, char *attrtype)
1470Sstevel@tonic-gate {
1480Sstevel@tonic-gate 	char	*keyeq = NULL;
1491450Sjanga 	char	*keyfilter = NULL;
1501450Sjanga 	int	len, totlen = 1; /* Terminating NULL byte */
1510Sstevel@tonic-gate 	char	*k, **karray;
1521450Sjanga 	char	*tmpptr;
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	if (!key || !key[0])	/* should never contain NULL string */
1550Sstevel@tonic-gate 		return (NULL);
1560Sstevel@tonic-gate 
1571450Sjanga 	if (key[1]) {
1581450Sjanga 		totlen += 3;
1591450Sjanga 		/* Allocate memory for '(|)' */
1601450Sjanga 		MALLOC(keyfilter, totlen);
1611450Sjanga 		if (!keyfilter)
1621450Sjanga 			exit(2);
1631450Sjanga 		(void) snprintf(keyfilter, totlen, "(|");
1640Sstevel@tonic-gate 	}
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate 	karray = key;
1671450Sjanga 	while ((k = *karray) != 0) {
1680Sstevel@tonic-gate 		keyeq = strchr(k, '=');
1691450Sjanga 		if (keyeq) {
1701450Sjanga 			/* make enough room for (%s) */
1711450Sjanga 			totlen += strlen(k) + 2;
1721450Sjanga 		} else {
1731450Sjanga 			/* make enough room for (%s=%s) */
1741450Sjanga 			totlen += strlen(attrtype) + strlen(k) + 3;
1751450Sjanga 		}
1761450Sjanga 
1771450Sjanga 		len = keyfilter ? strlen(keyfilter) : 0;
1781450Sjanga 
1791450Sjanga 		if (!(tmpptr = (char *)realloc(keyfilter, totlen))) {
1801450Sjanga 			if (keyfilter)
1811450Sjanga 				free(keyfilter);
1821450Sjanga 			(void) fprintf(stderr, gettext("out of memory\n"));
1830Sstevel@tonic-gate 			exit(2);
1840Sstevel@tonic-gate 		}
1851450Sjanga 		keyfilter = tmpptr;
1861450Sjanga 
1871450Sjanga 		if (keyeq) {
1881450Sjanga 			(void) snprintf(keyfilter + len, totlen - len,
1891450Sjanga 					"(%s)", k);
1901450Sjanga 		} else {
1911450Sjanga 			(void) snprintf(keyfilter + len, totlen - len,
1921450Sjanga 					"(%s=%s)", attrtype, k);
1931450Sjanga 		}
1940Sstevel@tonic-gate 		karray++;
1950Sstevel@tonic-gate 	}
1961450Sjanga 
1971450Sjanga 	if (key[1]) {
1981450Sjanga 		/* We allocated memory for this earlier */
1991450Sjanga 		(void) strlcat(keyfilter, ")", totlen);
2001450Sjanga 	}
2011450Sjanga 
2020Sstevel@tonic-gate 	return (keyfilter);
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate /*
2070Sstevel@tonic-gate  * A special set_key routine for to handle public keys.
2080Sstevel@tonic-gate  * If the key starts with a digiti, view it as a user id.
2090Sstevel@tonic-gate  * Otherwise, view it as a hostname.
2100Sstevel@tonic-gate  * It returns: -1 no keys defined, 0 key defined but none for type
2110Sstevel@tonic-gate  *		specified, n>0 number of matches found.
2120Sstevel@tonic-gate  */
2130Sstevel@tonic-gate int
2140Sstevel@tonic-gate set_keys_publickey(char **key, char *attrtype, int type, char **ret)
2150Sstevel@tonic-gate {
2160Sstevel@tonic-gate 	char	*keyeq = NULL;
2171450Sjanga 	char	*keyfilter = NULL;
2181450Sjanga 	char	*pre_filter = NULL;
2190Sstevel@tonic-gate 	char	*k, **karray;
2200Sstevel@tonic-gate 	int	count = 0;
2211450Sjanga 	int	len, totlen = 1; /* Terminating NULL byte */
2221450Sjanga 	char	*tmpptr;
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate 	if (!key || !key[0]) {	/* should never contain NULL string */
2250Sstevel@tonic-gate 		*ret = NULL;
2260Sstevel@tonic-gate 		return (-1);
2270Sstevel@tonic-gate 	}
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 	karray = key;
2301450Sjanga 	while ((k = *karray) != 0) {
2310Sstevel@tonic-gate 		keyeq = strchr(k, '=');
2321450Sjanga 		if (keyeq) {
2331450Sjanga 			/* make enough room for (%s) */
2341450Sjanga 			totlen += strlen(k) + 2;
2351450Sjanga 		} else {
2361450Sjanga 			if ((type == 0 && isdigit(*k)) ||
2370Sstevel@tonic-gate 				/* user type keys */
2381450Sjanga 			    (type == 1 && (!isdigit(*k)))) {
2390Sstevel@tonic-gate 				/* hosts type keys */
2401450Sjanga 				/* make enough room for (%s=%s) */
2411450Sjanga 				totlen += strlen(k) + strlen(attrtype) + 3;
2420Sstevel@tonic-gate 			} else {
2430Sstevel@tonic-gate 				karray++;
2440Sstevel@tonic-gate 				continue;
2450Sstevel@tonic-gate 			}
2460Sstevel@tonic-gate 		}
2471450Sjanga 
2481450Sjanga 		len = pre_filter ? strlen(pre_filter) : 0;
2491450Sjanga 
2501450Sjanga 		if (!(tmpptr = (char *)realloc(pre_filter, totlen))) {
2511450Sjanga 			if (pre_filter)
2521450Sjanga 				free(pre_filter);
2531450Sjanga 			(void) fprintf(stderr, gettext("out of memory\n"));
2540Sstevel@tonic-gate 			exit(2);
2550Sstevel@tonic-gate 		}
2561450Sjanga 		pre_filter = tmpptr;
2571450Sjanga 
2581450Sjanga 		if (keyeq) {
2591450Sjanga 			(void) snprintf(pre_filter + len, totlen - len,
2601450Sjanga 					"(%s)", k);
2611450Sjanga 		} else {
2621450Sjanga 			(void) snprintf(pre_filter + len, totlen - len,
2631450Sjanga 					"(%s=%s)", attrtype, k);
2641450Sjanga 		}
2650Sstevel@tonic-gate 		karray++;
2660Sstevel@tonic-gate 		count++;
2670Sstevel@tonic-gate 	}
2680Sstevel@tonic-gate 	if (count > 1) {
2691450Sjanga 		len = strlen(pre_filter) + 4;
2701450Sjanga 		if (!(keyfilter = (char *)malloc(len))) {
2711450Sjanga 			(void) fprintf(stderr, gettext("out of memory\n"));
2721450Sjanga 			free(pre_filter);
2730Sstevel@tonic-gate 			exit(2);
2740Sstevel@tonic-gate 		}
2751450Sjanga 		(void) snprintf(keyfilter, len, "(|%s)", pre_filter);
2761450Sjanga 		free(pre_filter);
2770Sstevel@tonic-gate 		*ret = keyfilter;
2780Sstevel@tonic-gate 	} else
2790Sstevel@tonic-gate 		*ret = pre_filter;
2800Sstevel@tonic-gate 	return (count);
2810Sstevel@tonic-gate }
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate /*
2840Sstevel@tonic-gate  * publickey specific set_filter
2850Sstevel@tonic-gate  * type 0 -> check for user publickeys
2860Sstevel@tonic-gate  * type 1 -> check for hosts publickeys
2870Sstevel@tonic-gate  */
2880Sstevel@tonic-gate char *
2890Sstevel@tonic-gate set_filter_publickey(char **key, char *database, int type, char **udata)
2900Sstevel@tonic-gate {
2911450Sjanga 	char 	*filter = NULL;
2920Sstevel@tonic-gate 	char 	*userdata;
2931450Sjanga 	char	*keyfilter = NULL;
2940Sstevel@tonic-gate 	int	rc;
2951450Sjanga 	int	filterlen, udatalen;
2961450Sjanga 	short	nomem = 0;
2970Sstevel@tonic-gate 
2981450Sjanga 	if (!database || !udata) {
2990Sstevel@tonic-gate 		return (NULL);
3000Sstevel@tonic-gate 	}
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate 	if (strcasecmp(database, maplist[PUBLICKEY].database) == SAME) {
3030Sstevel@tonic-gate 		rc = set_keys_publickey(key,
3040Sstevel@tonic-gate 				maplist[PUBLICKEY + type].def_type, type,
3050Sstevel@tonic-gate 				&keyfilter);
3060Sstevel@tonic-gate 		switch (rc) {
3070Sstevel@tonic-gate 		case -1:
3081450Sjanga 			filterlen = strlen(maplist[PUBLICKEY].objectclass) + 13;
3091450Sjanga 			udatalen = 3;
3101450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
3111450Sjanga 						udatalen, nomem);
3121450Sjanga 			if (!nomem) {
3131450Sjanga 				(void) snprintf(filter, filterlen,
3141450Sjanga 					"objectclass=%s",
3151450Sjanga 					maplist[PUBLICKEY].objectclass);
3161450Sjanga 				(void) snprintf(userdata, udatalen, "%%s");
3171450Sjanga 			}
3180Sstevel@tonic-gate 			break;
3190Sstevel@tonic-gate 		case 0:
3200Sstevel@tonic-gate 			return (NULL);
3210Sstevel@tonic-gate 		default:
3221450Sjanga 			filterlen = strlen(maplist[PUBLICKEY].objectclass) +
3231450Sjanga 				strlen(keyfilter) + 18;
3241450Sjanga 			udatalen = strlen(keyfilter) + 8;
3251450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
3261450Sjanga 						udatalen, nomem);
3271450Sjanga 			if (!nomem) {
3281450Sjanga 			    (void) snprintf(filter, filterlen,
3291450Sjanga 				"(&(objectclass=%s)%s)",
3300Sstevel@tonic-gate 				maplist[PUBLICKEY].objectclass, keyfilter);
3311450Sjanga 			    (void) snprintf(userdata, udatalen, "(&(%%s)%s)",
3321450Sjanga 					keyfilter);
3331450Sjanga 			}
3340Sstevel@tonic-gate 		}
3350Sstevel@tonic-gate 	} else {
3360Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "cn")) == NULL) {
3371450Sjanga 			filterlen = 14;
3381450Sjanga 			udatalen = 3;
3391450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
3401450Sjanga 						udatalen, nomem);
3411450Sjanga 			if (!nomem) {
3421450Sjanga 				(void) snprintf(filter, filterlen,
3431450Sjanga 						"objectclass=*");
3441450Sjanga 				(void) snprintf(userdata, udatalen, "%%s");
3451450Sjanga 			}
3460Sstevel@tonic-gate 		} else {
3471450Sjanga 			filterlen = strlen(keyfilter) + 1;
3481450Sjanga 			udatalen = strlen(keyfilter) + 8;
3491450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
3501450Sjanga 						udatalen, nomem);
3511450Sjanga 			if (!nomem) {
3521450Sjanga 				(void) snprintf(filter, filterlen, "%s",
3531450Sjanga 						keyfilter);
3541450Sjanga 				(void) snprintf(userdata, udatalen,
3551450Sjanga 						"(&(%%s)%s)", keyfilter);
3561450Sjanga 			}
3570Sstevel@tonic-gate 		}
3580Sstevel@tonic-gate 	}
3590Sstevel@tonic-gate #ifdef DEBUG
3601450Sjanga 	(void) fprintf(stdout, "set_filter: filter=\"%s\"\n", filter);
3611450Sjanga 	(void) fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata);
3620Sstevel@tonic-gate #endif /* DEBUG */
3631450Sjanga 	if (keyfilter)
3641450Sjanga 		free(keyfilter);
3651450Sjanga 	if (nomem)
3661450Sjanga 		exit(2);
3671450Sjanga 	*udata = userdata;
3680Sstevel@tonic-gate 	return (filter);
3690Sstevel@tonic-gate }
3700Sstevel@tonic-gate 
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate /* generic set_filter, this function is not thread safe */
3730Sstevel@tonic-gate char *
3740Sstevel@tonic-gate set_filter(char **key, char *database, char **udata)
3750Sstevel@tonic-gate {
3761450Sjanga 	char 		*filter = NULL;
3771450Sjanga 	char 		*userdata = NULL;
3780Sstevel@tonic-gate 	char		*keyfilter;
3791450Sjanga 	int		i, filterlen, udatalen;
3800Sstevel@tonic-gate 	int		rc, v2 = 1;
3810Sstevel@tonic-gate 	void		**paramVal = NULL;
3820Sstevel@tonic-gate 	ns_ldap_error_t	*errorp = NULL;
3831450Sjanga 	short		nomem;
3840Sstevel@tonic-gate 
3851450Sjanga 	if (!database || !udata) {
3860Sstevel@tonic-gate 		return (NULL);
3870Sstevel@tonic-gate 	}
3880Sstevel@tonic-gate 
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate 	/*
3910Sstevel@tonic-gate 	 * Check for version of the profile the client is using
3920Sstevel@tonic-gate 	 *
3930Sstevel@tonic-gate 	 * For version 1 profiles we do use nisMap and nisObject schema
3940Sstevel@tonic-gate 	 * for backward compatibility with Solaris 8 clients.
3950Sstevel@tonic-gate 	 *
3960Sstevel@tonic-gate 	 * For version 2 profiles we use automountMap and automount as
3970Sstevel@tonic-gate 	 * default attributes (which can then be overridden in libsldap
3980Sstevel@tonic-gate 	 * if schema mapping is configured in the profile).
3990Sstevel@tonic-gate 	 *
4000Sstevel@tonic-gate 	 * If profile version is not available, use version 2 as default.
4010Sstevel@tonic-gate 	 */
4020Sstevel@tonic-gate 	rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, &paramVal, &errorp);
4030Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS || !paramVal || !*paramVal) {
4040Sstevel@tonic-gate 		/* should print a message here: using v2 defaults */
4050Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
4060Sstevel@tonic-gate 	} else {
4070Sstevel@tonic-gate 		if (strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0)
4080Sstevel@tonic-gate 			v2 = 0;
4090Sstevel@tonic-gate 		(void) __ns_ldap_freeParam(&paramVal);
4100Sstevel@tonic-gate 	}
4110Sstevel@tonic-gate 
4120Sstevel@tonic-gate 	/*
4130Sstevel@tonic-gate 	 * starts at 2 to skip over publickey databases.
4140Sstevel@tonic-gate 	 * These databases are handled separately.
4150Sstevel@tonic-gate 	 */
4160Sstevel@tonic-gate 	for (i = 2; maplist[i].database != NULL; i++) {
4170Sstevel@tonic-gate 		if (strcasecmp(database, maplist[i].database) == SAME) {
4180Sstevel@tonic-gate 			if ((keyfilter = set_keys(key, maplist[i].def_type))
4190Sstevel@tonic-gate 							== NULL) {
4201450Sjanga 				filterlen = strlen(maplist[i].objectclass) + 13;
4211450Sjanga 				udatalen = 3;
4221450Sjanga 				MALLOC_FILTER_UDATA(filter, filterlen, userdata,
4231450Sjanga 						udatalen, nomem);
4241450Sjanga 				if (!nomem) {
4251450Sjanga 					(void) snprintf(filter, filterlen,
4261450Sjanga 						"objectclass=%s",
4271450Sjanga 						maplist[i].objectclass);
4281450Sjanga 					(void) snprintf(userdata, udatalen,
4291450Sjanga 							"%%s");
4301450Sjanga 				}
4310Sstevel@tonic-gate 			} else {
4321450Sjanga 				filterlen = strlen(maplist[i].objectclass) +
4331450Sjanga 					strlen(keyfilter) + 18;
4341450Sjanga 				udatalen = strlen(keyfilter) + 8;
4351450Sjanga 				MALLOC_FILTER_UDATA(filter, filterlen, userdata,
4361450Sjanga 						udatalen, nomem);
4371450Sjanga 				if (!nomem) {
4381450Sjanga 					(void) snprintf(filter, filterlen,
4391450Sjanga 					    "(&(objectclass=%s)%s)",
4401450Sjanga 					    maplist[i].objectclass, keyfilter);
4411450Sjanga 					(void) snprintf(userdata, udatalen,
4421450Sjanga 						"(&(%%s)%s)", keyfilter);
4431450Sjanga 				}
4440Sstevel@tonic-gate 			}
4451450Sjanga 			goto done;
4460Sstevel@tonic-gate 		}
4470Sstevel@tonic-gate 	}
4480Sstevel@tonic-gate 
4490Sstevel@tonic-gate 	/* special cases for automounter and other services */
4500Sstevel@tonic-gate 
4510Sstevel@tonic-gate 	/* auto_* services */
4520Sstevel@tonic-gate 	if (strncasecmp(database, "auto_", 5) == SAME) {
4530Sstevel@tonic-gate 	    if (v2) {
4540Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "automountKey"))
4550Sstevel@tonic-gate 			!= NULL) {
4561450Sjanga 			filterlen = strlen(keyfilter) + 27;
4571450Sjanga 			udatalen = strlen(keyfilter) + 8;
4581450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
4591450Sjanga 					udatalen, nomem);
4601450Sjanga 			if (!nomem) {
4611450Sjanga 				(void) snprintf(filter, filterlen,
4621450Sjanga 				    "(&(objectclass=automount)%s)",
4631450Sjanga 					keyfilter);
4641450Sjanga 				(void) snprintf(userdata, udatalen,
4651450Sjanga 					"(&(%%s)%s)", keyfilter);
4661450Sjanga 			}
4670Sstevel@tonic-gate 		} else {
4681450Sjanga 			filterlen = 22;
4691450Sjanga 			udatalen = 3;
4701450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
4711450Sjanga 					udatalen, nomem);
4721450Sjanga 			if (!nomem) {
4731450Sjanga 				(void) strlcpy(filter, "objectclass=automount",
4741450Sjanga 					filterlen);
4751450Sjanga 				(void) strlcpy(userdata, "%s", udatalen);
4761450Sjanga 			}
4770Sstevel@tonic-gate 		}
4780Sstevel@tonic-gate 	    } else {
4791450Sjanga 		if ((keyfilter = set_keys(key, "cn")) != NULL) {
4801450Sjanga 			filterlen = strlen(keyfilter) + 27;
4811450Sjanga 			udatalen = strlen(keyfilter) + 8;
4821450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
4831450Sjanga 					udatalen, nomem);
4841450Sjanga 			if (!nomem) {
4851450Sjanga 				(void) snprintf(filter, filterlen,
4861450Sjanga 				    "(&(objectclass=nisObject)%s)", keyfilter);
4871450Sjanga 				(void) snprintf(userdata, udatalen,
4881450Sjanga 					"(&(%%s)%s)", keyfilter);
4891450Sjanga 			}
4900Sstevel@tonic-gate 		} else {
4911450Sjanga 			filterlen = 22;
4921450Sjanga 			udatalen = 3;
4931450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
4941450Sjanga 					udatalen, nomem);
4951450Sjanga 			if (!nomem) {
4961450Sjanga 				(void) strlcpy(filter, "objectclass=nisObject",
4971450Sjanga 						filterlen);
4981450Sjanga 				(void) strlcpy(userdata, "%s", udatalen);
4991450Sjanga 			}
5000Sstevel@tonic-gate 		}
5010Sstevel@tonic-gate 	    }
5020Sstevel@tonic-gate 	    goto done;
5030Sstevel@tonic-gate 	}
5040Sstevel@tonic-gate 
5050Sstevel@tonic-gate 	/* automount service */
5060Sstevel@tonic-gate 	if (strcasecmp(database, "automount") == SAME) {
5070Sstevel@tonic-gate 	    if (v2) {
5080Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "automountMapName"))
5090Sstevel@tonic-gate 			!= NULL) {
5101450Sjanga 			filterlen = strlen(keyfilter) + 30;
5111450Sjanga 			udatalen = strlen(keyfilter) + 8;
5121450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5131450Sjanga 					udatalen, nomem);
5141450Sjanga 			if (!nomem) {
5151450Sjanga 				(void) snprintf(filter, filterlen,
5161450Sjanga 					"(&(objectclass=automountMap)%s)",
5171450Sjanga 					keyfilter);
5181450Sjanga 				(void) snprintf(userdata, udatalen,
5191450Sjanga 					"(&(%%s)%s)", keyfilter);
5201450Sjanga 			}
5210Sstevel@tonic-gate 		} else {
5221450Sjanga 			filterlen = 25;
5231450Sjanga 			udatalen = 3;
5241450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5251450Sjanga 					udatalen, nomem);
5261450Sjanga 			if (!nomem) {
5271450Sjanga 				(void) strlcpy(filter,
5281450Sjanga 					"objectclass=automountMap",
5291450Sjanga 					filterlen);
5301450Sjanga 				(void) strlcpy(userdata, "%s", udatalen);
5311450Sjanga 			}
5320Sstevel@tonic-gate 		}
5330Sstevel@tonic-gate 	    } else {
5340Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "nisMapName"))
5350Sstevel@tonic-gate 			!= NULL) {
5361450Sjanga 			filterlen = strlen(keyfilter) + 24;
5371450Sjanga 			udatalen = strlen(keyfilter) + 8;
5381450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5391450Sjanga 					udatalen, nomem);
5401450Sjanga 			if (!nomem) {
5411450Sjanga 				(void) snprintf(filter, filterlen,
5421450Sjanga 					"(&(objectclass=nisMap)%s)",
5431450Sjanga 					keyfilter);
5441450Sjanga 				(void) snprintf(userdata, udatalen,
5451450Sjanga 					"(&(%%s)%s)", keyfilter);
5461450Sjanga 			}
5470Sstevel@tonic-gate 		} else {
5481450Sjanga 			filterlen = 19;
5491450Sjanga 			udatalen = 3;
5501450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5511450Sjanga 					udatalen, nomem);
5521450Sjanga 			if (!nomem) {
5531450Sjanga 			    (void) strlcpy(filter, "objectclass=nisMap",
5541450Sjanga 					filterlen);
5551450Sjanga 			    (void) strlcpy(userdata, "%s", udatalen);
5561450Sjanga 			}
5570Sstevel@tonic-gate 		}
5580Sstevel@tonic-gate 	    }
5590Sstevel@tonic-gate 	    goto done;
5600Sstevel@tonic-gate 	}
5610Sstevel@tonic-gate 
5620Sstevel@tonic-gate 	/* other services (catch all) */
5630Sstevel@tonic-gate 	if ((keyfilter = set_keys(key, "cn")) == NULL) {
5641450Sjanga 		filterlen = 14;
5651450Sjanga 		udatalen = 3;
5661450Sjanga 		MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5671450Sjanga 				udatalen, nomem);
5681450Sjanga 		if (!nomem) {
5691450Sjanga 			(void) snprintf(filter, filterlen, "objectclass=*");
5701450Sjanga 			(void) strlcpy(userdata, "%s", udatalen);
5711450Sjanga 		}
5720Sstevel@tonic-gate 	} else {
5731450Sjanga 		filterlen = strlen(keyfilter) + 1;
5741450Sjanga 		udatalen = strlen(keyfilter) + 8;
5751450Sjanga 		MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5761450Sjanga 				udatalen, nomem);
5771450Sjanga 		if (!nomem) {
5781450Sjanga 			(void) snprintf(filter, filterlen, "%s", keyfilter);
5791450Sjanga 			(void) snprintf(userdata, udatalen, "(&(%%s)%s)",
5801450Sjanga 					keyfilter);
5811450Sjanga 		}
5820Sstevel@tonic-gate 	}
5830Sstevel@tonic-gate 
5840Sstevel@tonic-gate done:
5850Sstevel@tonic-gate #ifdef DEBUG
5861450Sjanga 	(void) fprintf(stdout, "set_filter: filter=\"%s\"\n", filter);
5871450Sjanga 	(void) fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata);
5880Sstevel@tonic-gate #endif /* DEBUG */
5891450Sjanga 	if (keyfilter)
5901450Sjanga 		free(keyfilter);
5911450Sjanga 	if (nomem)
5921450Sjanga 		exit(2);
5931450Sjanga 	*udata = userdata;
5940Sstevel@tonic-gate 	return (filter);
5950Sstevel@tonic-gate }
596