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  */
211676Sjpk 
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>
331676Sjpk #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},
721676Sjpk 	{"tnrhtp", "ipTnetTemplateName", "ipTnetTemplate", NULL},
731676Sjpk 	{"tnrhdb", "ipTnetNumber", "ipTnetHost", NULL},
740Sstevel@tonic-gate 	{NULL, NULL, NULL, NULL}
750Sstevel@tonic-gate };
760Sstevel@tonic-gate 
77*2830Sdjl #define	PROF_ATTR_FILTER \
78*2830Sdjl 	"(&(objectclass=SolarisProfAttr)(!(SolarisKernelSecurityPolicy=*))%s)"
79*2830Sdjl #define	TNRHTP_FILTER \
80*2830Sdjl 	"(&(objectclass=ipTnetTemplate)(!(objectclass=ipTnetHost))%s)"
81*2830Sdjl #define	OC_FILTER	"objectclass=%s"
82*2830Sdjl #define	OC_FLEN		15
83*2830Sdjl #define	OC_FILTER2	"(&(objectclass=%s)%s)"
84*2830Sdjl #define	OC_FLEN2	22
85*2830Sdjl 
861450Sjanga /* Malloc and print error message in case of failure */
871450Sjanga #define	MALLOC(ptr, len) \
881450Sjanga 	if ((ptr = (char *)malloc(len)) == NULL) { \
891450Sjanga 		(void) fprintf(stderr, gettext("out of memory\n")); \
901450Sjanga 	}
911450Sjanga 
921450Sjanga /*
931450Sjanga  * Allocate memory for filter and user data. Set
941450Sjanga  * error to 1 if either of the mallocs fail.
951450Sjanga  * In addition, free the memory allocated for filter,
961450Sjanga  * if memory allocation for user data fails.
971450Sjanga  */
981450Sjanga #define	MALLOC_FILTER_UDATA(ptr1, len1, ptr2, len2, error) \
991450Sjanga 	error = 0; \
1001450Sjanga 	MALLOC(ptr1, len1); \
1011450Sjanga 	if (!ptr1) { \
1021450Sjanga 		error = 1; \
1031450Sjanga 	} \
1041450Sjanga 	else { \
1051450Sjanga 		MALLOC(ptr2, len2); \
1061450Sjanga 		if (!ptr2) { \
1071450Sjanga 			error = 1; \
1081450Sjanga 			free(ptr1); \
1091450Sjanga 		} \
1101450Sjanga 	}
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate void
1130Sstevel@tonic-gate printMapping()
1140Sstevel@tonic-gate {
1150Sstevel@tonic-gate 	int	i;
1160Sstevel@tonic-gate 
1171450Sjanga 	(void) fprintf(stdout,
1180Sstevel@tonic-gate 		gettext("database       default type        objectclass\n"));
1191450Sjanga 	(void) fprintf(stdout,
1200Sstevel@tonic-gate 		gettext("=============  =================   =============\n"));
1210Sstevel@tonic-gate 	/* first dump auto_* and automount which are not in maplist[] */
1221450Sjanga 	(void) fprintf(stdout, "%-15s%-20s%s\n", "auto_*", "automountKey",
1230Sstevel@tonic-gate 		"automount");
1241450Sjanga 	(void) fprintf(stdout, "%-15s%-20s%s\n", "automount",
1251450Sjanga 		"automountMapName",
1260Sstevel@tonic-gate 		"automountMap");
1270Sstevel@tonic-gate 	for (i = 0; maplist[i].database != NULL; i++) {
1281676Sjpk 		/* skip printing shadow */
1291676Sjpk 		if (strcasecmp(maplist[i].database, "shadow") == 0)
1301676Sjpk 			continue;
1311676Sjpk 		if (!is_system_labeled()) {
1321676Sjpk 			/*
1331676Sjpk 			 * do not print tnrhdb and tnrhtp if system is
1341676Sjpk 			 * not configured with Trusted Extensions
1351676Sjpk 			 */
1361676Sjpk 			if ((strcasecmp(maplist[i].database, "tnrhdb") == 0) ||
1371676Sjpk 			    (strcasecmp(maplist[i].database, "tnrhtp") == 0))
1381676Sjpk 				continue;
1391676Sjpk 		}
1401450Sjanga 		(void) fprintf(stdout, "%-15s%-20s%s\n", maplist[i].database,
1411676Sjpk 		    maplist[i].def_type, maplist[i].objectclass);
1420Sstevel@tonic-gate 	}
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate 
1451450Sjanga /*
1461450Sjanga  * set_key routine to handle user specified keys.
1471450Sjanga  * A key can be of the form: attribute=value or value.
1481450Sjanga  * A filter is constructed from a set of keys specified in
1491450Sjanga  * the form (|(key1)(key2)...(keyn))
1501450Sjanga  * It returns: NULL if no keys are defined or
1511450Sjanga  *		the keyfilter as constructed above.
1521450Sjanga  */
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate char *
1550Sstevel@tonic-gate set_keys(char **key, char *attrtype)
1560Sstevel@tonic-gate {
1570Sstevel@tonic-gate 	char	*keyeq = NULL;
1581450Sjanga 	char	*keyfilter = NULL;
1591450Sjanga 	int	len, totlen = 1; /* Terminating NULL byte */
1600Sstevel@tonic-gate 	char	*k, **karray;
1611450Sjanga 	char	*tmpptr;
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 	if (!key || !key[0])	/* should never contain NULL string */
1640Sstevel@tonic-gate 		return (NULL);
1650Sstevel@tonic-gate 
1661450Sjanga 	if (key[1]) {
1671450Sjanga 		totlen += 3;
1681450Sjanga 		/* Allocate memory for '(|)' */
1691450Sjanga 		MALLOC(keyfilter, totlen);
1701450Sjanga 		if (!keyfilter)
1711450Sjanga 			exit(2);
1721450Sjanga 		(void) snprintf(keyfilter, totlen, "(|");
1730Sstevel@tonic-gate 	}
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate 	karray = key;
1761450Sjanga 	while ((k = *karray) != 0) {
1770Sstevel@tonic-gate 		keyeq = strchr(k, '=');
1781450Sjanga 		if (keyeq) {
1791450Sjanga 			/* make enough room for (%s) */
1801450Sjanga 			totlen += strlen(k) + 2;
1811450Sjanga 		} else {
1821450Sjanga 			/* make enough room for (%s=%s) */
1831450Sjanga 			totlen += strlen(attrtype) + strlen(k) + 3;
1841450Sjanga 		}
1851450Sjanga 
1861450Sjanga 		len = keyfilter ? strlen(keyfilter) : 0;
1871450Sjanga 
1881450Sjanga 		if (!(tmpptr = (char *)realloc(keyfilter, totlen))) {
1891450Sjanga 			if (keyfilter)
1901450Sjanga 				free(keyfilter);
1911450Sjanga 			(void) fprintf(stderr, gettext("out of memory\n"));
1920Sstevel@tonic-gate 			exit(2);
1930Sstevel@tonic-gate 		}
1941450Sjanga 		keyfilter = tmpptr;
1951450Sjanga 
1961450Sjanga 		if (keyeq) {
1971450Sjanga 			(void) snprintf(keyfilter + len, totlen - len,
1981450Sjanga 					"(%s)", k);
1991450Sjanga 		} else {
2001450Sjanga 			(void) snprintf(keyfilter + len, totlen - len,
2011450Sjanga 					"(%s=%s)", attrtype, k);
2021450Sjanga 		}
2030Sstevel@tonic-gate 		karray++;
2040Sstevel@tonic-gate 	}
2051450Sjanga 
2061450Sjanga 	if (key[1]) {
2071450Sjanga 		/* We allocated memory for this earlier */
2081450Sjanga 		(void) strlcat(keyfilter, ")", totlen);
2091450Sjanga 	}
2101450Sjanga 
2110Sstevel@tonic-gate 	return (keyfilter);
2120Sstevel@tonic-gate }
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate /*
2160Sstevel@tonic-gate  * A special set_key routine for to handle public keys.
2170Sstevel@tonic-gate  * If the key starts with a digiti, view it as a user id.
2180Sstevel@tonic-gate  * Otherwise, view it as a hostname.
2190Sstevel@tonic-gate  * It returns: -1 no keys defined, 0 key defined but none for type
2200Sstevel@tonic-gate  *		specified, n>0 number of matches found.
2210Sstevel@tonic-gate  */
2220Sstevel@tonic-gate int
2230Sstevel@tonic-gate set_keys_publickey(char **key, char *attrtype, int type, char **ret)
2240Sstevel@tonic-gate {
2250Sstevel@tonic-gate 	char	*keyeq = NULL;
2261450Sjanga 	char	*keyfilter = NULL;
2271450Sjanga 	char	*pre_filter = NULL;
2280Sstevel@tonic-gate 	char	*k, **karray;
2290Sstevel@tonic-gate 	int	count = 0;
2301450Sjanga 	int	len, totlen = 1; /* Terminating NULL byte */
2311450Sjanga 	char	*tmpptr;
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate 	if (!key || !key[0]) {	/* should never contain NULL string */
2340Sstevel@tonic-gate 		*ret = NULL;
2350Sstevel@tonic-gate 		return (-1);
2360Sstevel@tonic-gate 	}
2370Sstevel@tonic-gate 
2380Sstevel@tonic-gate 	karray = key;
2391450Sjanga 	while ((k = *karray) != 0) {
2400Sstevel@tonic-gate 		keyeq = strchr(k, '=');
2411450Sjanga 		if (keyeq) {
2421450Sjanga 			/* make enough room for (%s) */
2431450Sjanga 			totlen += strlen(k) + 2;
2441450Sjanga 		} else {
2451450Sjanga 			if ((type == 0 && isdigit(*k)) ||
2460Sstevel@tonic-gate 				/* user type keys */
2471450Sjanga 			    (type == 1 && (!isdigit(*k)))) {
2480Sstevel@tonic-gate 				/* hosts type keys */
2491450Sjanga 				/* make enough room for (%s=%s) */
2501450Sjanga 				totlen += strlen(k) + strlen(attrtype) + 3;
2510Sstevel@tonic-gate 			} else {
2520Sstevel@tonic-gate 				karray++;
2530Sstevel@tonic-gate 				continue;
2540Sstevel@tonic-gate 			}
2550Sstevel@tonic-gate 		}
2561450Sjanga 
2571450Sjanga 		len = pre_filter ? strlen(pre_filter) : 0;
2581450Sjanga 
2591450Sjanga 		if (!(tmpptr = (char *)realloc(pre_filter, totlen))) {
2601450Sjanga 			if (pre_filter)
2611450Sjanga 				free(pre_filter);
2621450Sjanga 			(void) fprintf(stderr, gettext("out of memory\n"));
2630Sstevel@tonic-gate 			exit(2);
2640Sstevel@tonic-gate 		}
2651450Sjanga 		pre_filter = tmpptr;
2661450Sjanga 
2671450Sjanga 		if (keyeq) {
2681450Sjanga 			(void) snprintf(pre_filter + len, totlen - len,
2691450Sjanga 					"(%s)", k);
2701450Sjanga 		} else {
2711450Sjanga 			(void) snprintf(pre_filter + len, totlen - len,
2721450Sjanga 					"(%s=%s)", attrtype, k);
2731450Sjanga 		}
2740Sstevel@tonic-gate 		karray++;
2750Sstevel@tonic-gate 		count++;
2760Sstevel@tonic-gate 	}
2770Sstevel@tonic-gate 	if (count > 1) {
2781450Sjanga 		len = strlen(pre_filter) + 4;
2791450Sjanga 		if (!(keyfilter = (char *)malloc(len))) {
2801450Sjanga 			(void) fprintf(stderr, gettext("out of memory\n"));
2811450Sjanga 			free(pre_filter);
2820Sstevel@tonic-gate 			exit(2);
2830Sstevel@tonic-gate 		}
2841450Sjanga 		(void) snprintf(keyfilter, len, "(|%s)", pre_filter);
2851450Sjanga 		free(pre_filter);
2860Sstevel@tonic-gate 		*ret = keyfilter;
2870Sstevel@tonic-gate 	} else
2880Sstevel@tonic-gate 		*ret = pre_filter;
2890Sstevel@tonic-gate 	return (count);
2900Sstevel@tonic-gate }
2910Sstevel@tonic-gate 
2920Sstevel@tonic-gate /*
2930Sstevel@tonic-gate  * publickey specific set_filter
2940Sstevel@tonic-gate  * type 0 -> check for user publickeys
2950Sstevel@tonic-gate  * type 1 -> check for hosts publickeys
2960Sstevel@tonic-gate  */
2970Sstevel@tonic-gate char *
2980Sstevel@tonic-gate set_filter_publickey(char **key, char *database, int type, char **udata)
2990Sstevel@tonic-gate {
3001450Sjanga 	char 	*filter = NULL;
3010Sstevel@tonic-gate 	char 	*userdata;
3021450Sjanga 	char	*keyfilter = NULL;
3030Sstevel@tonic-gate 	int	rc;
3041450Sjanga 	int	filterlen, udatalen;
3051450Sjanga 	short	nomem = 0;
3060Sstevel@tonic-gate 
3071450Sjanga 	if (!database || !udata) {
3080Sstevel@tonic-gate 		return (NULL);
3090Sstevel@tonic-gate 	}
3100Sstevel@tonic-gate 
3110Sstevel@tonic-gate 	if (strcasecmp(database, maplist[PUBLICKEY].database) == SAME) {
3120Sstevel@tonic-gate 		rc = set_keys_publickey(key,
3130Sstevel@tonic-gate 				maplist[PUBLICKEY + type].def_type, type,
3140Sstevel@tonic-gate 				&keyfilter);
3150Sstevel@tonic-gate 		switch (rc) {
3160Sstevel@tonic-gate 		case -1:
3171450Sjanga 			filterlen = strlen(maplist[PUBLICKEY].objectclass) + 13;
3181450Sjanga 			udatalen = 3;
3191450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
3201450Sjanga 						udatalen, nomem);
3211450Sjanga 			if (!nomem) {
3221450Sjanga 				(void) snprintf(filter, filterlen,
3231450Sjanga 					"objectclass=%s",
3241450Sjanga 					maplist[PUBLICKEY].objectclass);
3251450Sjanga 				(void) snprintf(userdata, udatalen, "%%s");
3261450Sjanga 			}
3270Sstevel@tonic-gate 			break;
3280Sstevel@tonic-gate 		case 0:
3290Sstevel@tonic-gate 			return (NULL);
3300Sstevel@tonic-gate 		default:
3311450Sjanga 			filterlen = strlen(maplist[PUBLICKEY].objectclass) +
3321450Sjanga 				strlen(keyfilter) + 18;
3331450Sjanga 			udatalen = strlen(keyfilter) + 8;
3341450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
3351450Sjanga 						udatalen, nomem);
3361450Sjanga 			if (!nomem) {
3371450Sjanga 			    (void) snprintf(filter, filterlen,
3381450Sjanga 				"(&(objectclass=%s)%s)",
3390Sstevel@tonic-gate 				maplist[PUBLICKEY].objectclass, keyfilter);
3401450Sjanga 			    (void) snprintf(userdata, udatalen, "(&(%%s)%s)",
3411450Sjanga 					keyfilter);
3421450Sjanga 			}
3430Sstevel@tonic-gate 		}
3440Sstevel@tonic-gate 	} else {
3450Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "cn")) == NULL) {
3461450Sjanga 			filterlen = 14;
3471450Sjanga 			udatalen = 3;
3481450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
3491450Sjanga 						udatalen, nomem);
3501450Sjanga 			if (!nomem) {
3511450Sjanga 				(void) snprintf(filter, filterlen,
3521450Sjanga 						"objectclass=*");
3531450Sjanga 				(void) snprintf(userdata, udatalen, "%%s");
3541450Sjanga 			}
3550Sstevel@tonic-gate 		} else {
3561450Sjanga 			filterlen = strlen(keyfilter) + 1;
3571450Sjanga 			udatalen = strlen(keyfilter) + 8;
3581450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
3591450Sjanga 						udatalen, nomem);
3601450Sjanga 			if (!nomem) {
3611450Sjanga 				(void) snprintf(filter, filterlen, "%s",
3621450Sjanga 						keyfilter);
3631450Sjanga 				(void) snprintf(userdata, udatalen,
3641450Sjanga 						"(&(%%s)%s)", keyfilter);
3651450Sjanga 			}
3660Sstevel@tonic-gate 		}
3670Sstevel@tonic-gate 	}
3680Sstevel@tonic-gate #ifdef DEBUG
3691450Sjanga 	(void) fprintf(stdout, "set_filter: filter=\"%s\"\n", filter);
3701450Sjanga 	(void) fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata);
3710Sstevel@tonic-gate #endif /* DEBUG */
3721450Sjanga 	if (keyfilter)
3731450Sjanga 		free(keyfilter);
3741450Sjanga 	if (nomem)
3751450Sjanga 		exit(2);
3761450Sjanga 	*udata = userdata;
3770Sstevel@tonic-gate 	return (filter);
3780Sstevel@tonic-gate }
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate 
3810Sstevel@tonic-gate /* generic set_filter, this function is not thread safe */
3820Sstevel@tonic-gate char *
3830Sstevel@tonic-gate set_filter(char **key, char *database, char **udata)
3840Sstevel@tonic-gate {
3851450Sjanga 	char 		*filter = NULL;
3861450Sjanga 	char 		*userdata = NULL;
3870Sstevel@tonic-gate 	char		*keyfilter;
3881450Sjanga 	int		i, filterlen, udatalen;
3890Sstevel@tonic-gate 	int		rc, v2 = 1;
390*2830Sdjl 	int		dbpf, dbtp;
3910Sstevel@tonic-gate 	void		**paramVal = NULL;
3920Sstevel@tonic-gate 	ns_ldap_error_t	*errorp = NULL;
3931450Sjanga 	short		nomem;
3940Sstevel@tonic-gate 
3951450Sjanga 	if (!database || !udata) {
3960Sstevel@tonic-gate 		return (NULL);
3970Sstevel@tonic-gate 	}
3980Sstevel@tonic-gate 
3990Sstevel@tonic-gate 
4000Sstevel@tonic-gate 	/*
4010Sstevel@tonic-gate 	 * Check for version of the profile the client is using
4020Sstevel@tonic-gate 	 *
4030Sstevel@tonic-gate 	 * For version 1 profiles we do use nisMap and nisObject schema
4040Sstevel@tonic-gate 	 * for backward compatibility with Solaris 8 clients.
4050Sstevel@tonic-gate 	 *
4060Sstevel@tonic-gate 	 * For version 2 profiles we use automountMap and automount as
4070Sstevel@tonic-gate 	 * default attributes (which can then be overridden in libsldap
4080Sstevel@tonic-gate 	 * if schema mapping is configured in the profile).
4090Sstevel@tonic-gate 	 *
4100Sstevel@tonic-gate 	 * If profile version is not available, use version 2 as default.
4110Sstevel@tonic-gate 	 */
4120Sstevel@tonic-gate 	rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, &paramVal, &errorp);
4130Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS || !paramVal || !*paramVal) {
4140Sstevel@tonic-gate 		/* should print a message here: using v2 defaults */
4150Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
4160Sstevel@tonic-gate 	} else {
4170Sstevel@tonic-gate 		if (strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0)
4180Sstevel@tonic-gate 			v2 = 0;
4190Sstevel@tonic-gate 		(void) __ns_ldap_freeParam(&paramVal);
4200Sstevel@tonic-gate 	}
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 	/*
4230Sstevel@tonic-gate 	 * starts at 2 to skip over publickey databases.
4240Sstevel@tonic-gate 	 * These databases are handled separately.
4250Sstevel@tonic-gate 	 */
4260Sstevel@tonic-gate 	for (i = 2; maplist[i].database != NULL; i++) {
4270Sstevel@tonic-gate 		if (strcasecmp(database, maplist[i].database) == SAME) {
428*2830Sdjl 			dbpf = 0, dbtp = 0;
429*2830Sdjl 			if (strcasecmp(database, "prof_attr") == 0)
430*2830Sdjl 				dbpf = 1;
431*2830Sdjl 			else if (strcasecmp(database, "tnrhtp") == 0)
432*2830Sdjl 				dbtp = 1;
4330Sstevel@tonic-gate 			if ((keyfilter = set_keys(key, maplist[i].def_type))
4340Sstevel@tonic-gate 							== NULL) {
435*2830Sdjl 				filterlen = strlen(maplist[i].objectclass);
4361450Sjanga 				udatalen = 3;
437*2830Sdjl 				if (dbpf)
438*2830Sdjl 					filterlen += strlen(PROF_ATTR_FILTER)
439*2830Sdjl 							+ 1;
440*2830Sdjl 				else if (dbtp)
441*2830Sdjl 					filterlen += strlen(TNRHTP_FILTER) + 1;
442*2830Sdjl 				else
443*2830Sdjl 					filterlen += OC_FLEN;
444*2830Sdjl 
4451450Sjanga 				MALLOC_FILTER_UDATA(filter, filterlen, userdata,
4461450Sjanga 						udatalen, nomem);
447*2830Sdjl 				if (nomem)
448*2830Sdjl 					goto done;
449*2830Sdjl 				if (dbpf)
4501450Sjanga 					(void) snprintf(filter, filterlen,
451*2830Sdjl 						PROF_ATTR_FILTER, "");
452*2830Sdjl 				else if (dbtp)
453*2830Sdjl 					(void) snprintf(filter, filterlen,
454*2830Sdjl 						TNRHTP_FILTER, "");
455*2830Sdjl 				else
456*2830Sdjl 					(void) snprintf(filter, filterlen,
457*2830Sdjl 						OC_FILTER,
4581450Sjanga 						maplist[i].objectclass);
459*2830Sdjl 
460*2830Sdjl 				(void) snprintf(userdata, udatalen, "%%s");
4610Sstevel@tonic-gate 			} else {
4621450Sjanga 				filterlen = strlen(maplist[i].objectclass) +
463*2830Sdjl 					strlen(keyfilter);
464*2830Sdjl 				if (dbpf)
465*2830Sdjl 					filterlen += strlen(PROF_ATTR_FILTER)
466*2830Sdjl 							+ 1;
467*2830Sdjl 				else if (dbtp)
468*2830Sdjl 					filterlen += strlen(TNRHTP_FILTER) + 1;
469*2830Sdjl 				else
470*2830Sdjl 					filterlen += OC_FLEN2;
471*2830Sdjl 
4721450Sjanga 				udatalen = strlen(keyfilter) + 8;
4731450Sjanga 				MALLOC_FILTER_UDATA(filter, filterlen, userdata,
4741450Sjanga 						udatalen, nomem);
475*2830Sdjl 				if (nomem)
476*2830Sdjl 					goto done;
477*2830Sdjl 				if (dbpf)
478*2830Sdjl 					(void) snprintf(filter, filterlen,
479*2830Sdjl 						PROF_ATTR_FILTER, keyfilter);
480*2830Sdjl 				else if (dbtp)
4811450Sjanga 					(void) snprintf(filter, filterlen,
482*2830Sdjl 						TNRHTP_FILTER, keyfilter);
483*2830Sdjl 				else
484*2830Sdjl 					(void) snprintf(filter, filterlen,
485*2830Sdjl 						OC_FILTER2,
486*2830Sdjl 						maplist[i].objectclass,
487*2830Sdjl 						keyfilter);
488*2830Sdjl 
489*2830Sdjl 				(void) snprintf(userdata, udatalen,
490*2830Sdjl 					"(&(%%s)%s)", keyfilter);
4910Sstevel@tonic-gate 			}
4921450Sjanga 			goto done;
4930Sstevel@tonic-gate 		}
4940Sstevel@tonic-gate 	}
4950Sstevel@tonic-gate 
4960Sstevel@tonic-gate 	/* special cases for automounter and other services */
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate 	/* auto_* services */
4990Sstevel@tonic-gate 	if (strncasecmp(database, "auto_", 5) == SAME) {
5000Sstevel@tonic-gate 	    if (v2) {
5010Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "automountKey"))
5020Sstevel@tonic-gate 			!= NULL) {
5031450Sjanga 			filterlen = strlen(keyfilter) + 27;
5041450Sjanga 			udatalen = strlen(keyfilter) + 8;
5051450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5061450Sjanga 					udatalen, nomem);
5071450Sjanga 			if (!nomem) {
5081450Sjanga 				(void) snprintf(filter, filterlen,
5091450Sjanga 				    "(&(objectclass=automount)%s)",
5101450Sjanga 					keyfilter);
5111450Sjanga 				(void) snprintf(userdata, udatalen,
5121450Sjanga 					"(&(%%s)%s)", keyfilter);
5131450Sjanga 			}
5140Sstevel@tonic-gate 		} else {
5151450Sjanga 			filterlen = 22;
5161450Sjanga 			udatalen = 3;
5171450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5181450Sjanga 					udatalen, nomem);
5191450Sjanga 			if (!nomem) {
5201450Sjanga 				(void) strlcpy(filter, "objectclass=automount",
5211450Sjanga 					filterlen);
5221450Sjanga 				(void) strlcpy(userdata, "%s", udatalen);
5231450Sjanga 			}
5240Sstevel@tonic-gate 		}
5250Sstevel@tonic-gate 	    } else {
5261450Sjanga 		if ((keyfilter = set_keys(key, "cn")) != NULL) {
5271450Sjanga 			filterlen = strlen(keyfilter) + 27;
5281450Sjanga 			udatalen = strlen(keyfilter) + 8;
5291450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5301450Sjanga 					udatalen, nomem);
5311450Sjanga 			if (!nomem) {
5321450Sjanga 				(void) snprintf(filter, filterlen,
5331450Sjanga 				    "(&(objectclass=nisObject)%s)", keyfilter);
5341450Sjanga 				(void) snprintf(userdata, udatalen,
5351450Sjanga 					"(&(%%s)%s)", keyfilter);
5361450Sjanga 			}
5370Sstevel@tonic-gate 		} else {
5381450Sjanga 			filterlen = 22;
5391450Sjanga 			udatalen = 3;
5401450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5411450Sjanga 					udatalen, nomem);
5421450Sjanga 			if (!nomem) {
5431450Sjanga 				(void) strlcpy(filter, "objectclass=nisObject",
5441450Sjanga 						filterlen);
5451450Sjanga 				(void) strlcpy(userdata, "%s", udatalen);
5461450Sjanga 			}
5470Sstevel@tonic-gate 		}
5480Sstevel@tonic-gate 	    }
5490Sstevel@tonic-gate 	    goto done;
5500Sstevel@tonic-gate 	}
5510Sstevel@tonic-gate 
5520Sstevel@tonic-gate 	/* automount service */
5530Sstevel@tonic-gate 	if (strcasecmp(database, "automount") == SAME) {
5540Sstevel@tonic-gate 	    if (v2) {
5550Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "automountMapName"))
5560Sstevel@tonic-gate 			!= NULL) {
5571450Sjanga 			filterlen = strlen(keyfilter) + 30;
5581450Sjanga 			udatalen = strlen(keyfilter) + 8;
5591450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5601450Sjanga 					udatalen, nomem);
5611450Sjanga 			if (!nomem) {
5621450Sjanga 				(void) snprintf(filter, filterlen,
5631450Sjanga 					"(&(objectclass=automountMap)%s)",
5641450Sjanga 					keyfilter);
5651450Sjanga 				(void) snprintf(userdata, udatalen,
5661450Sjanga 					"(&(%%s)%s)", keyfilter);
5671450Sjanga 			}
5680Sstevel@tonic-gate 		} else {
5691450Sjanga 			filterlen = 25;
5701450Sjanga 			udatalen = 3;
5711450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5721450Sjanga 					udatalen, nomem);
5731450Sjanga 			if (!nomem) {
5741450Sjanga 				(void) strlcpy(filter,
5751450Sjanga 					"objectclass=automountMap",
5761450Sjanga 					filterlen);
5771450Sjanga 				(void) strlcpy(userdata, "%s", udatalen);
5781450Sjanga 			}
5790Sstevel@tonic-gate 		}
5800Sstevel@tonic-gate 	    } else {
5810Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "nisMapName"))
5820Sstevel@tonic-gate 			!= NULL) {
5831450Sjanga 			filterlen = strlen(keyfilter) + 24;
5841450Sjanga 			udatalen = strlen(keyfilter) + 8;
5851450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5861450Sjanga 					udatalen, nomem);
5871450Sjanga 			if (!nomem) {
5881450Sjanga 				(void) snprintf(filter, filterlen,
5891450Sjanga 					"(&(objectclass=nisMap)%s)",
5901450Sjanga 					keyfilter);
5911450Sjanga 				(void) snprintf(userdata, udatalen,
5921450Sjanga 					"(&(%%s)%s)", keyfilter);
5931450Sjanga 			}
5940Sstevel@tonic-gate 		} else {
5951450Sjanga 			filterlen = 19;
5961450Sjanga 			udatalen = 3;
5971450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
5981450Sjanga 					udatalen, nomem);
5991450Sjanga 			if (!nomem) {
6001450Sjanga 			    (void) strlcpy(filter, "objectclass=nisMap",
6011450Sjanga 					filterlen);
6021450Sjanga 			    (void) strlcpy(userdata, "%s", udatalen);
6031450Sjanga 			}
6040Sstevel@tonic-gate 		}
6050Sstevel@tonic-gate 	    }
6060Sstevel@tonic-gate 	    goto done;
6070Sstevel@tonic-gate 	}
6080Sstevel@tonic-gate 
6090Sstevel@tonic-gate 	/* other services (catch all) */
6100Sstevel@tonic-gate 	if ((keyfilter = set_keys(key, "cn")) == NULL) {
6111450Sjanga 		filterlen = 14;
6121450Sjanga 		udatalen = 3;
6131450Sjanga 		MALLOC_FILTER_UDATA(filter, filterlen, userdata,
6141450Sjanga 				udatalen, nomem);
6151450Sjanga 		if (!nomem) {
6161450Sjanga 			(void) snprintf(filter, filterlen, "objectclass=*");
6171450Sjanga 			(void) strlcpy(userdata, "%s", udatalen);
6181450Sjanga 		}
6190Sstevel@tonic-gate 	} else {
6201450Sjanga 		filterlen = strlen(keyfilter) + 1;
6211450Sjanga 		udatalen = strlen(keyfilter) + 8;
6221450Sjanga 		MALLOC_FILTER_UDATA(filter, filterlen, userdata,
6231450Sjanga 				udatalen, nomem);
6241450Sjanga 		if (!nomem) {
6251450Sjanga 			(void) snprintf(filter, filterlen, "%s", keyfilter);
6261450Sjanga 			(void) snprintf(userdata, udatalen, "(&(%%s)%s)",
6271450Sjanga 					keyfilter);
6281450Sjanga 		}
6290Sstevel@tonic-gate 	}
6300Sstevel@tonic-gate 
6310Sstevel@tonic-gate done:
6320Sstevel@tonic-gate #ifdef DEBUG
6331450Sjanga 	(void) fprintf(stdout, "set_filter: filter=\"%s\"\n", filter);
6341450Sjanga 	(void) fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata);
6350Sstevel@tonic-gate #endif /* DEBUG */
6361450Sjanga 	if (keyfilter)
6371450Sjanga 		free(keyfilter);
6381450Sjanga 	if (nomem)
6391450Sjanga 		exit(2);
6401450Sjanga 	*udata = userdata;
6410Sstevel@tonic-gate 	return (filter);
6420Sstevel@tonic-gate }
643