xref: /onnv-gate/usr/src/cmd/ldap/ns_ldap/mapping.c (revision 1450:e71a639e7827)
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
5*1450Sjanga  * Common Development and Distribution License (the "License").
6*1450Sjanga  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*1450Sjanga  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <ctype.h>
290Sstevel@tonic-gate #include <libintl.h>
300Sstevel@tonic-gate #include <strings.h>
310Sstevel@tonic-gate #include <stdio.h>
320Sstevel@tonic-gate #include "../../../lib/libsldap/common/ns_sldap.h"
330Sstevel@tonic-gate 
340Sstevel@tonic-gate 
350Sstevel@tonic-gate #define	SAME	0
360Sstevel@tonic-gate 
370Sstevel@tonic-gate struct mapping {
380Sstevel@tonic-gate 	char *database;
390Sstevel@tonic-gate 	char *def_type;
400Sstevel@tonic-gate 	char *objectclass;
410Sstevel@tonic-gate 	char *actual_db;
420Sstevel@tonic-gate };
430Sstevel@tonic-gate 
440Sstevel@tonic-gate #define	PUBLICKEY	0
450Sstevel@tonic-gate 
460Sstevel@tonic-gate static struct mapping maplist[] = {
470Sstevel@tonic-gate 	{"publickey", "uidnumber", "niskeyobject", "passwd"},
480Sstevel@tonic-gate 	{"publickey", "cn", "niskeyobject", "host"},
490Sstevel@tonic-gate 	{"bootparams", "cn", "bootableDevice", NULL},
500Sstevel@tonic-gate 	{"ethers", "cn", "ieee802Device", NULL},
510Sstevel@tonic-gate 	{"group", "cn", "posixgroup", NULL},
520Sstevel@tonic-gate 	{"hosts", "cn", "iphost", NULL},
530Sstevel@tonic-gate 	{"ipnodes", "cn", "iphost", NULL},
540Sstevel@tonic-gate 	{"netgroup", "cn", "nisnetgroup", NULL},
550Sstevel@tonic-gate 	{"netmasks", "ipnetworknumber", "ipnetwork", NULL},
560Sstevel@tonic-gate 	{"networks", "ipnetworknumber", "ipnetwork", NULL},
570Sstevel@tonic-gate 	{"passwd", "uid", "posixaccount", NULL},
580Sstevel@tonic-gate 	{"protocols", "cn", "ipprotocol", NULL},
590Sstevel@tonic-gate 	{"rpc", "cn", "oncrpc", NULL},
600Sstevel@tonic-gate 	{"services", "cn", "ipservice", NULL},
610Sstevel@tonic-gate 	{"aliases", "cn", "mailGroup", NULL},
620Sstevel@tonic-gate 	{"project", "SolarisProjectID", "SolarisProject", NULL},
630Sstevel@tonic-gate 	{"printers", "printer-uri", "sunPrinter", NULL},
640Sstevel@tonic-gate 	{"shadow", "uid", "shadowaccount", NULL},
650Sstevel@tonic-gate 	{"auth_attr", "cn", "SolarisAuthAttr", NULL},
660Sstevel@tonic-gate 	{"prof_attr", "cn", "SolarisProfAttr", NULL},
670Sstevel@tonic-gate 	{"exec_attr", "cn", "SolarisExecAttr", NULL},
680Sstevel@tonic-gate 	{"user_attr", "uid", "SolarisUserAttr", NULL},
690Sstevel@tonic-gate 	{"audit_user", "uid", "SolarisAuditUser", NULL},
700Sstevel@tonic-gate 	{NULL, NULL, NULL, NULL}
710Sstevel@tonic-gate };
720Sstevel@tonic-gate 
73*1450Sjanga /* Malloc and print error message in case of failure */
74*1450Sjanga #define	MALLOC(ptr, len) \
75*1450Sjanga 	if ((ptr = (char *)malloc(len)) == NULL) { \
76*1450Sjanga 		(void) fprintf(stderr, gettext("out of memory\n")); \
77*1450Sjanga 	}
78*1450Sjanga 
79*1450Sjanga /*
80*1450Sjanga  * Allocate memory for filter and user data. Set
81*1450Sjanga  * error to 1 if either of the mallocs fail.
82*1450Sjanga  * In addition, free the memory allocated for filter,
83*1450Sjanga  * if memory allocation for user data fails.
84*1450Sjanga  */
85*1450Sjanga #define	MALLOC_FILTER_UDATA(ptr1, len1, ptr2, len2, error) \
86*1450Sjanga 	error = 0; \
87*1450Sjanga 	MALLOC(ptr1, len1); \
88*1450Sjanga 	if (!ptr1) { \
89*1450Sjanga 		error = 1; \
90*1450Sjanga 	} \
91*1450Sjanga 	else { \
92*1450Sjanga 		MALLOC(ptr2, len2); \
93*1450Sjanga 		if (!ptr2) { \
94*1450Sjanga 			error = 1; \
95*1450Sjanga 			free(ptr1); \
96*1450Sjanga 		} \
97*1450Sjanga 	}
980Sstevel@tonic-gate 
990Sstevel@tonic-gate void
1000Sstevel@tonic-gate printMapping()
1010Sstevel@tonic-gate {
1020Sstevel@tonic-gate 	int	i;
1030Sstevel@tonic-gate 
104*1450Sjanga 	(void) fprintf(stdout,
1050Sstevel@tonic-gate 		gettext("database       default type        objectclass\n"));
106*1450Sjanga 	(void) fprintf(stdout,
1070Sstevel@tonic-gate 		gettext("=============  =================   =============\n"));
1080Sstevel@tonic-gate 	/* first dump auto_* and automount which are not in maplist[] */
109*1450Sjanga 	(void) fprintf(stdout, "%-15s%-20s%s\n", "auto_*", "automountKey",
1100Sstevel@tonic-gate 		"automount");
111*1450Sjanga 	(void) fprintf(stdout, "%-15s%-20s%s\n", "automount",
112*1450Sjanga 		"automountMapName",
1130Sstevel@tonic-gate 		"automountMap");
1140Sstevel@tonic-gate 	for (i = 0; maplist[i].database != NULL; i++) {
1150Sstevel@tonic-gate 	/* skip printing shadow */
1160Sstevel@tonic-gate 	if (strcasecmp(maplist[i].database, "shadow") != 0)
117*1450Sjanga 		(void) fprintf(stdout, "%-15s%-20s%s\n", maplist[i].database,
1180Sstevel@tonic-gate 			maplist[i].def_type, maplist[i].objectclass);
1190Sstevel@tonic-gate 	}
1200Sstevel@tonic-gate }
1210Sstevel@tonic-gate 
122*1450Sjanga /*
123*1450Sjanga  * set_key routine to handle user specified keys.
124*1450Sjanga  * A key can be of the form: attribute=value or value.
125*1450Sjanga  * A filter is constructed from a set of keys specified in
126*1450Sjanga  * the form (|(key1)(key2)...(keyn))
127*1450Sjanga  * It returns: NULL if no keys are defined or
128*1450Sjanga  *		the keyfilter as constructed above.
129*1450Sjanga  */
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate char *
1320Sstevel@tonic-gate set_keys(char **key, char *attrtype)
1330Sstevel@tonic-gate {
1340Sstevel@tonic-gate 	char	*keyeq = NULL;
135*1450Sjanga 	char	*keyfilter = NULL;
136*1450Sjanga 	int	len, totlen = 1; /* Terminating NULL byte */
1370Sstevel@tonic-gate 	char	*k, **karray;
138*1450Sjanga 	char	*tmpptr;
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate 	if (!key || !key[0])	/* should never contain NULL string */
1410Sstevel@tonic-gate 		return (NULL);
1420Sstevel@tonic-gate 
143*1450Sjanga 	if (key[1]) {
144*1450Sjanga 		totlen += 3;
145*1450Sjanga 		/* Allocate memory for '(|)' */
146*1450Sjanga 		MALLOC(keyfilter, totlen);
147*1450Sjanga 		if (!keyfilter)
148*1450Sjanga 			exit(2);
149*1450Sjanga 		(void) snprintf(keyfilter, totlen, "(|");
1500Sstevel@tonic-gate 	}
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate 	karray = key;
153*1450Sjanga 	while ((k = *karray) != 0) {
1540Sstevel@tonic-gate 		keyeq = strchr(k, '=');
155*1450Sjanga 		if (keyeq) {
156*1450Sjanga 			/* make enough room for (%s) */
157*1450Sjanga 			totlen += strlen(k) + 2;
158*1450Sjanga 		} else {
159*1450Sjanga 			/* make enough room for (%s=%s) */
160*1450Sjanga 			totlen += strlen(attrtype) + strlen(k) + 3;
161*1450Sjanga 		}
162*1450Sjanga 
163*1450Sjanga 		len = keyfilter ? strlen(keyfilter) : 0;
164*1450Sjanga 
165*1450Sjanga 		if (!(tmpptr = (char *)realloc(keyfilter, totlen))) {
166*1450Sjanga 			if (keyfilter)
167*1450Sjanga 				free(keyfilter);
168*1450Sjanga 			(void) fprintf(stderr, gettext("out of memory\n"));
1690Sstevel@tonic-gate 			exit(2);
1700Sstevel@tonic-gate 		}
171*1450Sjanga 		keyfilter = tmpptr;
172*1450Sjanga 
173*1450Sjanga 		if (keyeq) {
174*1450Sjanga 			(void) snprintf(keyfilter + len, totlen - len,
175*1450Sjanga 					"(%s)", k);
176*1450Sjanga 		} else {
177*1450Sjanga 			(void) snprintf(keyfilter + len, totlen - len,
178*1450Sjanga 					"(%s=%s)", attrtype, k);
179*1450Sjanga 		}
1800Sstevel@tonic-gate 		karray++;
1810Sstevel@tonic-gate 	}
182*1450Sjanga 
183*1450Sjanga 	if (key[1]) {
184*1450Sjanga 		/* We allocated memory for this earlier */
185*1450Sjanga 		(void) strlcat(keyfilter, ")", totlen);
186*1450Sjanga 	}
187*1450Sjanga 
1880Sstevel@tonic-gate 	return (keyfilter);
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate /*
1930Sstevel@tonic-gate  * A special set_key routine for to handle public keys.
1940Sstevel@tonic-gate  * If the key starts with a digiti, view it as a user id.
1950Sstevel@tonic-gate  * Otherwise, view it as a hostname.
1960Sstevel@tonic-gate  * It returns: -1 no keys defined, 0 key defined but none for type
1970Sstevel@tonic-gate  *		specified, n>0 number of matches found.
1980Sstevel@tonic-gate  */
1990Sstevel@tonic-gate int
2000Sstevel@tonic-gate set_keys_publickey(char **key, char *attrtype, int type, char **ret)
2010Sstevel@tonic-gate {
2020Sstevel@tonic-gate 	char	*keyeq = NULL;
203*1450Sjanga 	char	*keyfilter = NULL;
204*1450Sjanga 	char	*pre_filter = NULL;
2050Sstevel@tonic-gate 	char	*k, **karray;
2060Sstevel@tonic-gate 	int	count = 0;
207*1450Sjanga 	int	len, totlen = 1; /* Terminating NULL byte */
208*1450Sjanga 	char	*tmpptr;
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate 	if (!key || !key[0]) {	/* should never contain NULL string */
2110Sstevel@tonic-gate 		*ret = NULL;
2120Sstevel@tonic-gate 		return (-1);
2130Sstevel@tonic-gate 	}
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 	karray = key;
216*1450Sjanga 	while ((k = *karray) != 0) {
2170Sstevel@tonic-gate 		keyeq = strchr(k, '=');
218*1450Sjanga 		if (keyeq) {
219*1450Sjanga 			/* make enough room for (%s) */
220*1450Sjanga 			totlen += strlen(k) + 2;
221*1450Sjanga 		} else {
222*1450Sjanga 			if ((type == 0 && isdigit(*k)) ||
2230Sstevel@tonic-gate 				/* user type keys */
224*1450Sjanga 			    (type == 1 && (!isdigit(*k)))) {
2250Sstevel@tonic-gate 				/* hosts type keys */
226*1450Sjanga 				/* make enough room for (%s=%s) */
227*1450Sjanga 				totlen += strlen(k) + strlen(attrtype) + 3;
2280Sstevel@tonic-gate 			} else {
2290Sstevel@tonic-gate 				karray++;
2300Sstevel@tonic-gate 				continue;
2310Sstevel@tonic-gate 			}
2320Sstevel@tonic-gate 		}
233*1450Sjanga 
234*1450Sjanga 		len = pre_filter ? strlen(pre_filter) : 0;
235*1450Sjanga 
236*1450Sjanga 		if (!(tmpptr = (char *)realloc(pre_filter, totlen))) {
237*1450Sjanga 			if (pre_filter)
238*1450Sjanga 				free(pre_filter);
239*1450Sjanga 			(void) fprintf(stderr, gettext("out of memory\n"));
2400Sstevel@tonic-gate 			exit(2);
2410Sstevel@tonic-gate 		}
242*1450Sjanga 		pre_filter = tmpptr;
243*1450Sjanga 
244*1450Sjanga 		if (keyeq) {
245*1450Sjanga 			(void) snprintf(pre_filter + len, totlen - len,
246*1450Sjanga 					"(%s)", k);
247*1450Sjanga 		} else {
248*1450Sjanga 			(void) snprintf(pre_filter + len, totlen - len,
249*1450Sjanga 					"(%s=%s)", attrtype, k);
250*1450Sjanga 		}
2510Sstevel@tonic-gate 		karray++;
2520Sstevel@tonic-gate 		count++;
2530Sstevel@tonic-gate 	}
2540Sstevel@tonic-gate 	if (count > 1) {
255*1450Sjanga 		len = strlen(pre_filter) + 4;
256*1450Sjanga 		if (!(keyfilter = (char *)malloc(len))) {
257*1450Sjanga 			(void) fprintf(stderr, gettext("out of memory\n"));
258*1450Sjanga 			free(pre_filter);
2590Sstevel@tonic-gate 			exit(2);
2600Sstevel@tonic-gate 		}
261*1450Sjanga 		(void) snprintf(keyfilter, len, "(|%s)", pre_filter);
262*1450Sjanga 		free(pre_filter);
2630Sstevel@tonic-gate 		*ret = keyfilter;
2640Sstevel@tonic-gate 	} else
2650Sstevel@tonic-gate 		*ret = pre_filter;
2660Sstevel@tonic-gate 	return (count);
2670Sstevel@tonic-gate }
2680Sstevel@tonic-gate 
2690Sstevel@tonic-gate /*
2700Sstevel@tonic-gate  * publickey specific set_filter
2710Sstevel@tonic-gate  * type 0 -> check for user publickeys
2720Sstevel@tonic-gate  * type 1 -> check for hosts publickeys
2730Sstevel@tonic-gate  */
2740Sstevel@tonic-gate char *
2750Sstevel@tonic-gate set_filter_publickey(char **key, char *database, int type, char **udata)
2760Sstevel@tonic-gate {
277*1450Sjanga 	char 	*filter = NULL;
2780Sstevel@tonic-gate 	char 	*userdata;
279*1450Sjanga 	char	*keyfilter = NULL;
2800Sstevel@tonic-gate 	int	rc;
281*1450Sjanga 	int	filterlen, udatalen;
282*1450Sjanga 	short	nomem = 0;
2830Sstevel@tonic-gate 
284*1450Sjanga 	if (!database || !udata) {
2850Sstevel@tonic-gate 		return (NULL);
2860Sstevel@tonic-gate 	}
2870Sstevel@tonic-gate 
2880Sstevel@tonic-gate 	if (strcasecmp(database, maplist[PUBLICKEY].database) == SAME) {
2890Sstevel@tonic-gate 		rc = set_keys_publickey(key,
2900Sstevel@tonic-gate 				maplist[PUBLICKEY + type].def_type, type,
2910Sstevel@tonic-gate 				&keyfilter);
2920Sstevel@tonic-gate 		switch (rc) {
2930Sstevel@tonic-gate 		case -1:
294*1450Sjanga 			filterlen = strlen(maplist[PUBLICKEY].objectclass) + 13;
295*1450Sjanga 			udatalen = 3;
296*1450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
297*1450Sjanga 						udatalen, nomem);
298*1450Sjanga 			if (!nomem) {
299*1450Sjanga 				(void) snprintf(filter, filterlen,
300*1450Sjanga 					"objectclass=%s",
301*1450Sjanga 					maplist[PUBLICKEY].objectclass);
302*1450Sjanga 				(void) snprintf(userdata, udatalen, "%%s");
303*1450Sjanga 			}
3040Sstevel@tonic-gate 			break;
3050Sstevel@tonic-gate 		case 0:
3060Sstevel@tonic-gate 			return (NULL);
3070Sstevel@tonic-gate 		default:
308*1450Sjanga 			filterlen = strlen(maplist[PUBLICKEY].objectclass) +
309*1450Sjanga 				strlen(keyfilter) + 18;
310*1450Sjanga 			udatalen = strlen(keyfilter) + 8;
311*1450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
312*1450Sjanga 						udatalen, nomem);
313*1450Sjanga 			if (!nomem) {
314*1450Sjanga 			    (void) snprintf(filter, filterlen,
315*1450Sjanga 				"(&(objectclass=%s)%s)",
3160Sstevel@tonic-gate 				maplist[PUBLICKEY].objectclass, keyfilter);
317*1450Sjanga 			    (void) snprintf(userdata, udatalen, "(&(%%s)%s)",
318*1450Sjanga 					keyfilter);
319*1450Sjanga 			}
3200Sstevel@tonic-gate 		}
3210Sstevel@tonic-gate 	} else {
3220Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "cn")) == NULL) {
323*1450Sjanga 			filterlen = 14;
324*1450Sjanga 			udatalen = 3;
325*1450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
326*1450Sjanga 						udatalen, nomem);
327*1450Sjanga 			if (!nomem) {
328*1450Sjanga 				(void) snprintf(filter, filterlen,
329*1450Sjanga 						"objectclass=*");
330*1450Sjanga 				(void) snprintf(userdata, udatalen, "%%s");
331*1450Sjanga 			}
3320Sstevel@tonic-gate 		} else {
333*1450Sjanga 			filterlen = strlen(keyfilter) + 1;
334*1450Sjanga 			udatalen = strlen(keyfilter) + 8;
335*1450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
336*1450Sjanga 						udatalen, nomem);
337*1450Sjanga 			if (!nomem) {
338*1450Sjanga 				(void) snprintf(filter, filterlen, "%s",
339*1450Sjanga 						keyfilter);
340*1450Sjanga 				(void) snprintf(userdata, udatalen,
341*1450Sjanga 						"(&(%%s)%s)", keyfilter);
342*1450Sjanga 			}
3430Sstevel@tonic-gate 		}
3440Sstevel@tonic-gate 	}
3450Sstevel@tonic-gate #ifdef DEBUG
346*1450Sjanga 	(void) fprintf(stdout, "set_filter: filter=\"%s\"\n", filter);
347*1450Sjanga 	(void) fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata);
3480Sstevel@tonic-gate #endif /* DEBUG */
349*1450Sjanga 	if (keyfilter)
350*1450Sjanga 		free(keyfilter);
351*1450Sjanga 	if (nomem)
352*1450Sjanga 		exit(2);
353*1450Sjanga 	*udata = userdata;
3540Sstevel@tonic-gate 	return (filter);
3550Sstevel@tonic-gate }
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate /* generic set_filter, this function is not thread safe */
3590Sstevel@tonic-gate char *
3600Sstevel@tonic-gate set_filter(char **key, char *database, char **udata)
3610Sstevel@tonic-gate {
362*1450Sjanga 	char 		*filter = NULL;
363*1450Sjanga 	char 		*userdata = NULL;
3640Sstevel@tonic-gate 	char		*keyfilter;
365*1450Sjanga 	int		i, filterlen, udatalen;
3660Sstevel@tonic-gate 	int		rc, v2 = 1;
3670Sstevel@tonic-gate 	void		**paramVal = NULL;
3680Sstevel@tonic-gate 	ns_ldap_error_t	*errorp = NULL;
369*1450Sjanga 	short		nomem;
3700Sstevel@tonic-gate 
371*1450Sjanga 	if (!database || !udata) {
3720Sstevel@tonic-gate 		return (NULL);
3730Sstevel@tonic-gate 	}
3740Sstevel@tonic-gate 
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate 	/*
3770Sstevel@tonic-gate 	 * Check for version of the profile the client is using
3780Sstevel@tonic-gate 	 *
3790Sstevel@tonic-gate 	 * For version 1 profiles we do use nisMap and nisObject schema
3800Sstevel@tonic-gate 	 * for backward compatibility with Solaris 8 clients.
3810Sstevel@tonic-gate 	 *
3820Sstevel@tonic-gate 	 * For version 2 profiles we use automountMap and automount as
3830Sstevel@tonic-gate 	 * default attributes (which can then be overridden in libsldap
3840Sstevel@tonic-gate 	 * if schema mapping is configured in the profile).
3850Sstevel@tonic-gate 	 *
3860Sstevel@tonic-gate 	 * If profile version is not available, use version 2 as default.
3870Sstevel@tonic-gate 	 */
3880Sstevel@tonic-gate 	rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, &paramVal, &errorp);
3890Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS || !paramVal || !*paramVal) {
3900Sstevel@tonic-gate 		/* should print a message here: using v2 defaults */
3910Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
3920Sstevel@tonic-gate 	} else {
3930Sstevel@tonic-gate 		if (strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0)
3940Sstevel@tonic-gate 			v2 = 0;
3950Sstevel@tonic-gate 		(void) __ns_ldap_freeParam(&paramVal);
3960Sstevel@tonic-gate 	}
3970Sstevel@tonic-gate 
3980Sstevel@tonic-gate 	/*
3990Sstevel@tonic-gate 	 * starts at 2 to skip over publickey databases.
4000Sstevel@tonic-gate 	 * These databases are handled separately.
4010Sstevel@tonic-gate 	 */
4020Sstevel@tonic-gate 	for (i = 2; maplist[i].database != NULL; i++) {
4030Sstevel@tonic-gate 		if (strcasecmp(database, maplist[i].database) == SAME) {
4040Sstevel@tonic-gate 			if ((keyfilter = set_keys(key, maplist[i].def_type))
4050Sstevel@tonic-gate 							== NULL) {
406*1450Sjanga 				filterlen = strlen(maplist[i].objectclass) + 13;
407*1450Sjanga 				udatalen = 3;
408*1450Sjanga 				MALLOC_FILTER_UDATA(filter, filterlen, userdata,
409*1450Sjanga 						udatalen, nomem);
410*1450Sjanga 				if (!nomem) {
411*1450Sjanga 					(void) snprintf(filter, filterlen,
412*1450Sjanga 						"objectclass=%s",
413*1450Sjanga 						maplist[i].objectclass);
414*1450Sjanga 					(void) snprintf(userdata, udatalen,
415*1450Sjanga 							"%%s");
416*1450Sjanga 				}
4170Sstevel@tonic-gate 			} else {
418*1450Sjanga 				filterlen = strlen(maplist[i].objectclass) +
419*1450Sjanga 					strlen(keyfilter) + 18;
420*1450Sjanga 				udatalen = strlen(keyfilter) + 8;
421*1450Sjanga 				MALLOC_FILTER_UDATA(filter, filterlen, userdata,
422*1450Sjanga 						udatalen, nomem);
423*1450Sjanga 				if (!nomem) {
424*1450Sjanga 					(void) snprintf(filter, filterlen,
425*1450Sjanga 					    "(&(objectclass=%s)%s)",
426*1450Sjanga 					    maplist[i].objectclass, keyfilter);
427*1450Sjanga 					(void) snprintf(userdata, udatalen,
428*1450Sjanga 						"(&(%%s)%s)", keyfilter);
429*1450Sjanga 				}
4300Sstevel@tonic-gate 			}
431*1450Sjanga 			goto done;
4320Sstevel@tonic-gate 		}
4330Sstevel@tonic-gate 	}
4340Sstevel@tonic-gate 
4350Sstevel@tonic-gate 	/* special cases for automounter and other services */
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate 	/* auto_* services */
4380Sstevel@tonic-gate 	if (strncasecmp(database, "auto_", 5) == SAME) {
4390Sstevel@tonic-gate 	    if (v2) {
4400Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "automountKey"))
4410Sstevel@tonic-gate 			!= NULL) {
442*1450Sjanga 			filterlen = strlen(keyfilter) + 27;
443*1450Sjanga 			udatalen = strlen(keyfilter) + 8;
444*1450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
445*1450Sjanga 					udatalen, nomem);
446*1450Sjanga 			if (!nomem) {
447*1450Sjanga 				(void) snprintf(filter, filterlen,
448*1450Sjanga 				    "(&(objectclass=automount)%s)",
449*1450Sjanga 					keyfilter);
450*1450Sjanga 				(void) snprintf(userdata, udatalen,
451*1450Sjanga 					"(&(%%s)%s)", keyfilter);
452*1450Sjanga 			}
4530Sstevel@tonic-gate 		} else {
454*1450Sjanga 			filterlen = 22;
455*1450Sjanga 			udatalen = 3;
456*1450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
457*1450Sjanga 					udatalen, nomem);
458*1450Sjanga 			if (!nomem) {
459*1450Sjanga 				(void) strlcpy(filter, "objectclass=automount",
460*1450Sjanga 					filterlen);
461*1450Sjanga 				(void) strlcpy(userdata, "%s", udatalen);
462*1450Sjanga 			}
4630Sstevel@tonic-gate 		}
4640Sstevel@tonic-gate 	    } else {
465*1450Sjanga 		if ((keyfilter = set_keys(key, "cn")) != NULL) {
466*1450Sjanga 			filterlen = strlen(keyfilter) + 27;
467*1450Sjanga 			udatalen = strlen(keyfilter) + 8;
468*1450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
469*1450Sjanga 					udatalen, nomem);
470*1450Sjanga 			if (!nomem) {
471*1450Sjanga 				(void) snprintf(filter, filterlen,
472*1450Sjanga 				    "(&(objectclass=nisObject)%s)", keyfilter);
473*1450Sjanga 				(void) snprintf(userdata, udatalen,
474*1450Sjanga 					"(&(%%s)%s)", keyfilter);
475*1450Sjanga 			}
4760Sstevel@tonic-gate 		} else {
477*1450Sjanga 			filterlen = 22;
478*1450Sjanga 			udatalen = 3;
479*1450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
480*1450Sjanga 					udatalen, nomem);
481*1450Sjanga 			if (!nomem) {
482*1450Sjanga 				(void) strlcpy(filter, "objectclass=nisObject",
483*1450Sjanga 						filterlen);
484*1450Sjanga 				(void) strlcpy(userdata, "%s", udatalen);
485*1450Sjanga 			}
4860Sstevel@tonic-gate 		}
4870Sstevel@tonic-gate 	    }
4880Sstevel@tonic-gate 	    goto done;
4890Sstevel@tonic-gate 	}
4900Sstevel@tonic-gate 
4910Sstevel@tonic-gate 	/* automount service */
4920Sstevel@tonic-gate 	if (strcasecmp(database, "automount") == SAME) {
4930Sstevel@tonic-gate 	    if (v2) {
4940Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "automountMapName"))
4950Sstevel@tonic-gate 			!= NULL) {
496*1450Sjanga 			filterlen = strlen(keyfilter) + 30;
497*1450Sjanga 			udatalen = strlen(keyfilter) + 8;
498*1450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
499*1450Sjanga 					udatalen, nomem);
500*1450Sjanga 			if (!nomem) {
501*1450Sjanga 				(void) snprintf(filter, filterlen,
502*1450Sjanga 					"(&(objectclass=automountMap)%s)",
503*1450Sjanga 					keyfilter);
504*1450Sjanga 				(void) snprintf(userdata, udatalen,
505*1450Sjanga 					"(&(%%s)%s)", keyfilter);
506*1450Sjanga 			}
5070Sstevel@tonic-gate 		} else {
508*1450Sjanga 			filterlen = 25;
509*1450Sjanga 			udatalen = 3;
510*1450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
511*1450Sjanga 					udatalen, nomem);
512*1450Sjanga 			if (!nomem) {
513*1450Sjanga 				(void) strlcpy(filter,
514*1450Sjanga 					"objectclass=automountMap",
515*1450Sjanga 					filterlen);
516*1450Sjanga 				(void) strlcpy(userdata, "%s", udatalen);
517*1450Sjanga 			}
5180Sstevel@tonic-gate 		}
5190Sstevel@tonic-gate 	    } else {
5200Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "nisMapName"))
5210Sstevel@tonic-gate 			!= NULL) {
522*1450Sjanga 			filterlen = strlen(keyfilter) + 24;
523*1450Sjanga 			udatalen = strlen(keyfilter) + 8;
524*1450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
525*1450Sjanga 					udatalen, nomem);
526*1450Sjanga 			if (!nomem) {
527*1450Sjanga 				(void) snprintf(filter, filterlen,
528*1450Sjanga 					"(&(objectclass=nisMap)%s)",
529*1450Sjanga 					keyfilter);
530*1450Sjanga 				(void) snprintf(userdata, udatalen,
531*1450Sjanga 					"(&(%%s)%s)", keyfilter);
532*1450Sjanga 			}
5330Sstevel@tonic-gate 		} else {
534*1450Sjanga 			filterlen = 19;
535*1450Sjanga 			udatalen = 3;
536*1450Sjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
537*1450Sjanga 					udatalen, nomem);
538*1450Sjanga 			if (!nomem) {
539*1450Sjanga 			    (void) strlcpy(filter, "objectclass=nisMap",
540*1450Sjanga 					filterlen);
541*1450Sjanga 			    (void) strlcpy(userdata, "%s", udatalen);
542*1450Sjanga 			}
5430Sstevel@tonic-gate 		}
5440Sstevel@tonic-gate 	    }
5450Sstevel@tonic-gate 	    goto done;
5460Sstevel@tonic-gate 	}
5470Sstevel@tonic-gate 
5480Sstevel@tonic-gate 	/* other services (catch all) */
5490Sstevel@tonic-gate 	if ((keyfilter = set_keys(key, "cn")) == NULL) {
550*1450Sjanga 		filterlen = 14;
551*1450Sjanga 		udatalen = 3;
552*1450Sjanga 		MALLOC_FILTER_UDATA(filter, filterlen, userdata,
553*1450Sjanga 				udatalen, nomem);
554*1450Sjanga 		if (!nomem) {
555*1450Sjanga 			(void) snprintf(filter, filterlen, "objectclass=*");
556*1450Sjanga 			(void) strlcpy(userdata, "%s", udatalen);
557*1450Sjanga 		}
5580Sstevel@tonic-gate 	} else {
559*1450Sjanga 		filterlen = strlen(keyfilter) + 1;
560*1450Sjanga 		udatalen = strlen(keyfilter) + 8;
561*1450Sjanga 		MALLOC_FILTER_UDATA(filter, filterlen, userdata,
562*1450Sjanga 				udatalen, nomem);
563*1450Sjanga 		if (!nomem) {
564*1450Sjanga 			(void) snprintf(filter, filterlen, "%s", keyfilter);
565*1450Sjanga 			(void) snprintf(userdata, udatalen, "(&(%%s)%s)",
566*1450Sjanga 					keyfilter);
567*1450Sjanga 		}
5680Sstevel@tonic-gate 	}
5690Sstevel@tonic-gate 
5700Sstevel@tonic-gate done:
5710Sstevel@tonic-gate #ifdef DEBUG
572*1450Sjanga 	(void) fprintf(stdout, "set_filter: filter=\"%s\"\n", filter);
573*1450Sjanga 	(void) fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata);
5740Sstevel@tonic-gate #endif /* DEBUG */
575*1450Sjanga 	if (keyfilter)
576*1450Sjanga 		free(keyfilter);
577*1450Sjanga 	if (nomem)
578*1450Sjanga 		exit(2);
579*1450Sjanga 	*udata = userdata;
5800Sstevel@tonic-gate 	return (filter);
5810Sstevel@tonic-gate }
582