xref: /illumos-gate/usr/src/cmd/ldap/ns_ldap/mapping.c (revision 45916cd2)
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  */
21*45916cd2Sjpk 
227c478bd9Sstevel@tonic-gate /*
23b446700bSjanga  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <ctype.h>
307c478bd9Sstevel@tonic-gate #include <libintl.h>
317c478bd9Sstevel@tonic-gate #include <strings.h>
327c478bd9Sstevel@tonic-gate #include <stdio.h>
33*45916cd2Sjpk #include <tsol/label.h>
347c478bd9Sstevel@tonic-gate #include "../../../lib/libsldap/common/ns_sldap.h"
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #define	SAME	0
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate struct mapping {
407c478bd9Sstevel@tonic-gate 	char *database;
417c478bd9Sstevel@tonic-gate 	char *def_type;
427c478bd9Sstevel@tonic-gate 	char *objectclass;
437c478bd9Sstevel@tonic-gate 	char *actual_db;
447c478bd9Sstevel@tonic-gate };
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #define	PUBLICKEY	0
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate static struct mapping maplist[] = {
497c478bd9Sstevel@tonic-gate 	{"publickey", "uidnumber", "niskeyobject", "passwd"},
507c478bd9Sstevel@tonic-gate 	{"publickey", "cn", "niskeyobject", "host"},
517c478bd9Sstevel@tonic-gate 	{"bootparams", "cn", "bootableDevice", NULL},
527c478bd9Sstevel@tonic-gate 	{"ethers", "cn", "ieee802Device", NULL},
537c478bd9Sstevel@tonic-gate 	{"group", "cn", "posixgroup", NULL},
547c478bd9Sstevel@tonic-gate 	{"hosts", "cn", "iphost", NULL},
557c478bd9Sstevel@tonic-gate 	{"ipnodes", "cn", "iphost", NULL},
567c478bd9Sstevel@tonic-gate 	{"netgroup", "cn", "nisnetgroup", NULL},
577c478bd9Sstevel@tonic-gate 	{"netmasks", "ipnetworknumber", "ipnetwork", NULL},
587c478bd9Sstevel@tonic-gate 	{"networks", "ipnetworknumber", "ipnetwork", NULL},
597c478bd9Sstevel@tonic-gate 	{"passwd", "uid", "posixaccount", NULL},
607c478bd9Sstevel@tonic-gate 	{"protocols", "cn", "ipprotocol", NULL},
617c478bd9Sstevel@tonic-gate 	{"rpc", "cn", "oncrpc", NULL},
627c478bd9Sstevel@tonic-gate 	{"services", "cn", "ipservice", NULL},
637c478bd9Sstevel@tonic-gate 	{"aliases", "cn", "mailGroup", NULL},
647c478bd9Sstevel@tonic-gate 	{"project", "SolarisProjectID", "SolarisProject", NULL},
657c478bd9Sstevel@tonic-gate 	{"printers", "printer-uri", "sunPrinter", NULL},
667c478bd9Sstevel@tonic-gate 	{"shadow", "uid", "shadowaccount", NULL},
677c478bd9Sstevel@tonic-gate 	{"auth_attr", "cn", "SolarisAuthAttr", NULL},
687c478bd9Sstevel@tonic-gate 	{"prof_attr", "cn", "SolarisProfAttr", NULL},
697c478bd9Sstevel@tonic-gate 	{"exec_attr", "cn", "SolarisExecAttr", NULL},
707c478bd9Sstevel@tonic-gate 	{"user_attr", "uid", "SolarisUserAttr", NULL},
717c478bd9Sstevel@tonic-gate 	{"audit_user", "uid", "SolarisAuditUser", NULL},
72*45916cd2Sjpk 	{"tnrhtp", "ipTnetTemplateName", "ipTnetTemplate", NULL},
73*45916cd2Sjpk 	{"tnrhdb", "ipTnetNumber", "ipTnetHost", NULL},
747c478bd9Sstevel@tonic-gate 	{NULL, NULL, NULL, NULL}
757c478bd9Sstevel@tonic-gate };
767c478bd9Sstevel@tonic-gate 
77b446700bSjanga /* Malloc and print error message in case of failure */
78b446700bSjanga #define	MALLOC(ptr, len) \
79b446700bSjanga 	if ((ptr = (char *)malloc(len)) == NULL) { \
80b446700bSjanga 		(void) fprintf(stderr, gettext("out of memory\n")); \
81b446700bSjanga 	}
82b446700bSjanga 
83b446700bSjanga /*
84b446700bSjanga  * Allocate memory for filter and user data. Set
85b446700bSjanga  * error to 1 if either of the mallocs fail.
86b446700bSjanga  * In addition, free the memory allocated for filter,
87b446700bSjanga  * if memory allocation for user data fails.
88b446700bSjanga  */
89b446700bSjanga #define	MALLOC_FILTER_UDATA(ptr1, len1, ptr2, len2, error) \
90b446700bSjanga 	error = 0; \
91b446700bSjanga 	MALLOC(ptr1, len1); \
92b446700bSjanga 	if (!ptr1) { \
93b446700bSjanga 		error = 1; \
94b446700bSjanga 	} \
95b446700bSjanga 	else { \
96b446700bSjanga 		MALLOC(ptr2, len2); \
97b446700bSjanga 		if (!ptr2) { \
98b446700bSjanga 			error = 1; \
99b446700bSjanga 			free(ptr1); \
100b446700bSjanga 		} \
101b446700bSjanga 	}
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate void
1047c478bd9Sstevel@tonic-gate printMapping()
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate 	int	i;
1077c478bd9Sstevel@tonic-gate 
108b446700bSjanga 	(void) fprintf(stdout,
1097c478bd9Sstevel@tonic-gate 		gettext("database       default type        objectclass\n"));
110b446700bSjanga 	(void) fprintf(stdout,
1117c478bd9Sstevel@tonic-gate 		gettext("=============  =================   =============\n"));
1127c478bd9Sstevel@tonic-gate 	/* first dump auto_* and automount which are not in maplist[] */
113b446700bSjanga 	(void) fprintf(stdout, "%-15s%-20s%s\n", "auto_*", "automountKey",
1147c478bd9Sstevel@tonic-gate 		"automount");
115b446700bSjanga 	(void) fprintf(stdout, "%-15s%-20s%s\n", "automount",
116b446700bSjanga 		"automountMapName",
1177c478bd9Sstevel@tonic-gate 		"automountMap");
1187c478bd9Sstevel@tonic-gate 	for (i = 0; maplist[i].database != NULL; i++) {
119*45916cd2Sjpk 		/* skip printing shadow */
120*45916cd2Sjpk 		if (strcasecmp(maplist[i].database, "shadow") == 0)
121*45916cd2Sjpk 			continue;
122*45916cd2Sjpk 		if (!is_system_labeled()) {
123*45916cd2Sjpk 			/*
124*45916cd2Sjpk 			 * do not print tnrhdb and tnrhtp if system is
125*45916cd2Sjpk 			 * not configured with Trusted Extensions
126*45916cd2Sjpk 			 */
127*45916cd2Sjpk 			if ((strcasecmp(maplist[i].database, "tnrhdb") == 0) ||
128*45916cd2Sjpk 			    (strcasecmp(maplist[i].database, "tnrhtp") == 0))
129*45916cd2Sjpk 				continue;
130*45916cd2Sjpk 		}
131b446700bSjanga 		(void) fprintf(stdout, "%-15s%-20s%s\n", maplist[i].database,
132*45916cd2Sjpk 		    maplist[i].def_type, maplist[i].objectclass);
1337c478bd9Sstevel@tonic-gate 	}
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate 
136b446700bSjanga /*
137b446700bSjanga  * set_key routine to handle user specified keys.
138b446700bSjanga  * A key can be of the form: attribute=value or value.
139b446700bSjanga  * A filter is constructed from a set of keys specified in
140b446700bSjanga  * the form (|(key1)(key2)...(keyn))
141b446700bSjanga  * It returns: NULL if no keys are defined or
142b446700bSjanga  *		the keyfilter as constructed above.
143b446700bSjanga  */
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate char *
1467c478bd9Sstevel@tonic-gate set_keys(char **key, char *attrtype)
1477c478bd9Sstevel@tonic-gate {
1487c478bd9Sstevel@tonic-gate 	char	*keyeq = NULL;
149b446700bSjanga 	char	*keyfilter = NULL;
150b446700bSjanga 	int	len, totlen = 1; /* Terminating NULL byte */
1517c478bd9Sstevel@tonic-gate 	char	*k, **karray;
152b446700bSjanga 	char	*tmpptr;
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 	if (!key || !key[0])	/* should never contain NULL string */
1557c478bd9Sstevel@tonic-gate 		return (NULL);
1567c478bd9Sstevel@tonic-gate 
157b446700bSjanga 	if (key[1]) {
158b446700bSjanga 		totlen += 3;
159b446700bSjanga 		/* Allocate memory for '(|)' */
160b446700bSjanga 		MALLOC(keyfilter, totlen);
161b446700bSjanga 		if (!keyfilter)
162b446700bSjanga 			exit(2);
163b446700bSjanga 		(void) snprintf(keyfilter, totlen, "(|");
1647c478bd9Sstevel@tonic-gate 	}
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 	karray = key;
167b446700bSjanga 	while ((k = *karray) != 0) {
1687c478bd9Sstevel@tonic-gate 		keyeq = strchr(k, '=');
169b446700bSjanga 		if (keyeq) {
170b446700bSjanga 			/* make enough room for (%s) */
171b446700bSjanga 			totlen += strlen(k) + 2;
172b446700bSjanga 		} else {
173b446700bSjanga 			/* make enough room for (%s=%s) */
174b446700bSjanga 			totlen += strlen(attrtype) + strlen(k) + 3;
175b446700bSjanga 		}
176b446700bSjanga 
177b446700bSjanga 		len = keyfilter ? strlen(keyfilter) : 0;
178b446700bSjanga 
179b446700bSjanga 		if (!(tmpptr = (char *)realloc(keyfilter, totlen))) {
180b446700bSjanga 			if (keyfilter)
181b446700bSjanga 				free(keyfilter);
182b446700bSjanga 			(void) fprintf(stderr, gettext("out of memory\n"));
1837c478bd9Sstevel@tonic-gate 			exit(2);
1847c478bd9Sstevel@tonic-gate 		}
185b446700bSjanga 		keyfilter = tmpptr;
186b446700bSjanga 
187b446700bSjanga 		if (keyeq) {
188b446700bSjanga 			(void) snprintf(keyfilter + len, totlen - len,
189b446700bSjanga 					"(%s)", k);
190b446700bSjanga 		} else {
191b446700bSjanga 			(void) snprintf(keyfilter + len, totlen - len,
192b446700bSjanga 					"(%s=%s)", attrtype, k);
193b446700bSjanga 		}
1947c478bd9Sstevel@tonic-gate 		karray++;
1957c478bd9Sstevel@tonic-gate 	}
196b446700bSjanga 
197b446700bSjanga 	if (key[1]) {
198b446700bSjanga 		/* We allocated memory for this earlier */
199b446700bSjanga 		(void) strlcat(keyfilter, ")", totlen);
200b446700bSjanga 	}
201b446700bSjanga 
2027c478bd9Sstevel@tonic-gate 	return (keyfilter);
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate /*
2077c478bd9Sstevel@tonic-gate  * A special set_key routine for to handle public keys.
2087c478bd9Sstevel@tonic-gate  * If the key starts with a digiti, view it as a user id.
2097c478bd9Sstevel@tonic-gate  * Otherwise, view it as a hostname.
2107c478bd9Sstevel@tonic-gate  * It returns: -1 no keys defined, 0 key defined but none for type
2117c478bd9Sstevel@tonic-gate  *		specified, n>0 number of matches found.
2127c478bd9Sstevel@tonic-gate  */
2137c478bd9Sstevel@tonic-gate int
2147c478bd9Sstevel@tonic-gate set_keys_publickey(char **key, char *attrtype, int type, char **ret)
2157c478bd9Sstevel@tonic-gate {
2167c478bd9Sstevel@tonic-gate 	char	*keyeq = NULL;
217b446700bSjanga 	char	*keyfilter = NULL;
218b446700bSjanga 	char	*pre_filter = NULL;
2197c478bd9Sstevel@tonic-gate 	char	*k, **karray;
2207c478bd9Sstevel@tonic-gate 	int	count = 0;
221b446700bSjanga 	int	len, totlen = 1; /* Terminating NULL byte */
222b446700bSjanga 	char	*tmpptr;
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	if (!key || !key[0]) {	/* should never contain NULL string */
2257c478bd9Sstevel@tonic-gate 		*ret = NULL;
2267c478bd9Sstevel@tonic-gate 		return (-1);
2277c478bd9Sstevel@tonic-gate 	}
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	karray = key;
230b446700bSjanga 	while ((k = *karray) != 0) {
2317c478bd9Sstevel@tonic-gate 		keyeq = strchr(k, '=');
232b446700bSjanga 		if (keyeq) {
233b446700bSjanga 			/* make enough room for (%s) */
234b446700bSjanga 			totlen += strlen(k) + 2;
235b446700bSjanga 		} else {
236b446700bSjanga 			if ((type == 0 && isdigit(*k)) ||
2377c478bd9Sstevel@tonic-gate 				/* user type keys */
238b446700bSjanga 			    (type == 1 && (!isdigit(*k)))) {
2397c478bd9Sstevel@tonic-gate 				/* hosts type keys */
240b446700bSjanga 				/* make enough room for (%s=%s) */
241b446700bSjanga 				totlen += strlen(k) + strlen(attrtype) + 3;
2427c478bd9Sstevel@tonic-gate 			} else {
2437c478bd9Sstevel@tonic-gate 				karray++;
2447c478bd9Sstevel@tonic-gate 				continue;
2457c478bd9Sstevel@tonic-gate 			}
2467c478bd9Sstevel@tonic-gate 		}
247b446700bSjanga 
248b446700bSjanga 		len = pre_filter ? strlen(pre_filter) : 0;
249b446700bSjanga 
250b446700bSjanga 		if (!(tmpptr = (char *)realloc(pre_filter, totlen))) {
251b446700bSjanga 			if (pre_filter)
252b446700bSjanga 				free(pre_filter);
253b446700bSjanga 			(void) fprintf(stderr, gettext("out of memory\n"));
2547c478bd9Sstevel@tonic-gate 			exit(2);
2557c478bd9Sstevel@tonic-gate 		}
256b446700bSjanga 		pre_filter = tmpptr;
257b446700bSjanga 
258b446700bSjanga 		if (keyeq) {
259b446700bSjanga 			(void) snprintf(pre_filter + len, totlen - len,
260b446700bSjanga 					"(%s)", k);
261b446700bSjanga 		} else {
262b446700bSjanga 			(void) snprintf(pre_filter + len, totlen - len,
263b446700bSjanga 					"(%s=%s)", attrtype, k);
264b446700bSjanga 		}
2657c478bd9Sstevel@tonic-gate 		karray++;
2667c478bd9Sstevel@tonic-gate 		count++;
2677c478bd9Sstevel@tonic-gate 	}
2687c478bd9Sstevel@tonic-gate 	if (count > 1) {
269b446700bSjanga 		len = strlen(pre_filter) + 4;
270b446700bSjanga 		if (!(keyfilter = (char *)malloc(len))) {
271b446700bSjanga 			(void) fprintf(stderr, gettext("out of memory\n"));
272b446700bSjanga 			free(pre_filter);
2737c478bd9Sstevel@tonic-gate 			exit(2);
2747c478bd9Sstevel@tonic-gate 		}
275b446700bSjanga 		(void) snprintf(keyfilter, len, "(|%s)", pre_filter);
276b446700bSjanga 		free(pre_filter);
2777c478bd9Sstevel@tonic-gate 		*ret = keyfilter;
2787c478bd9Sstevel@tonic-gate 	} else
2797c478bd9Sstevel@tonic-gate 		*ret = pre_filter;
2807c478bd9Sstevel@tonic-gate 	return (count);
2817c478bd9Sstevel@tonic-gate }
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate /*
2847c478bd9Sstevel@tonic-gate  * publickey specific set_filter
2857c478bd9Sstevel@tonic-gate  * type 0 -> check for user publickeys
2867c478bd9Sstevel@tonic-gate  * type 1 -> check for hosts publickeys
2877c478bd9Sstevel@tonic-gate  */
2887c478bd9Sstevel@tonic-gate char *
2897c478bd9Sstevel@tonic-gate set_filter_publickey(char **key, char *database, int type, char **udata)
2907c478bd9Sstevel@tonic-gate {
291b446700bSjanga 	char 	*filter = NULL;
2927c478bd9Sstevel@tonic-gate 	char 	*userdata;
293b446700bSjanga 	char	*keyfilter = NULL;
2947c478bd9Sstevel@tonic-gate 	int	rc;
295b446700bSjanga 	int	filterlen, udatalen;
296b446700bSjanga 	short	nomem = 0;
2977c478bd9Sstevel@tonic-gate 
298b446700bSjanga 	if (!database || !udata) {
2997c478bd9Sstevel@tonic-gate 		return (NULL);
3007c478bd9Sstevel@tonic-gate 	}
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 	if (strcasecmp(database, maplist[PUBLICKEY].database) == SAME) {
3037c478bd9Sstevel@tonic-gate 		rc = set_keys_publickey(key,
3047c478bd9Sstevel@tonic-gate 				maplist[PUBLICKEY + type].def_type, type,
3057c478bd9Sstevel@tonic-gate 				&keyfilter);
3067c478bd9Sstevel@tonic-gate 		switch (rc) {
3077c478bd9Sstevel@tonic-gate 		case -1:
308b446700bSjanga 			filterlen = strlen(maplist[PUBLICKEY].objectclass) + 13;
309b446700bSjanga 			udatalen = 3;
310b446700bSjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
311b446700bSjanga 						udatalen, nomem);
312b446700bSjanga 			if (!nomem) {
313b446700bSjanga 				(void) snprintf(filter, filterlen,
314b446700bSjanga 					"objectclass=%s",
315b446700bSjanga 					maplist[PUBLICKEY].objectclass);
316b446700bSjanga 				(void) snprintf(userdata, udatalen, "%%s");
317b446700bSjanga 			}
3187c478bd9Sstevel@tonic-gate 			break;
3197c478bd9Sstevel@tonic-gate 		case 0:
3207c478bd9Sstevel@tonic-gate 			return (NULL);
3217c478bd9Sstevel@tonic-gate 		default:
322b446700bSjanga 			filterlen = strlen(maplist[PUBLICKEY].objectclass) +
323b446700bSjanga 				strlen(keyfilter) + 18;
324b446700bSjanga 			udatalen = strlen(keyfilter) + 8;
325b446700bSjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
326b446700bSjanga 						udatalen, nomem);
327b446700bSjanga 			if (!nomem) {
328b446700bSjanga 			    (void) snprintf(filter, filterlen,
329b446700bSjanga 				"(&(objectclass=%s)%s)",
3307c478bd9Sstevel@tonic-gate 				maplist[PUBLICKEY].objectclass, keyfilter);
331b446700bSjanga 			    (void) snprintf(userdata, udatalen, "(&(%%s)%s)",
332b446700bSjanga 					keyfilter);
333b446700bSjanga 			}
3347c478bd9Sstevel@tonic-gate 		}
3357c478bd9Sstevel@tonic-gate 	} else {
3367c478bd9Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "cn")) == NULL) {
337b446700bSjanga 			filterlen = 14;
338b446700bSjanga 			udatalen = 3;
339b446700bSjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
340b446700bSjanga 						udatalen, nomem);
341b446700bSjanga 			if (!nomem) {
342b446700bSjanga 				(void) snprintf(filter, filterlen,
343b446700bSjanga 						"objectclass=*");
344b446700bSjanga 				(void) snprintf(userdata, udatalen, "%%s");
345b446700bSjanga 			}
3467c478bd9Sstevel@tonic-gate 		} else {
347b446700bSjanga 			filterlen = strlen(keyfilter) + 1;
348b446700bSjanga 			udatalen = strlen(keyfilter) + 8;
349b446700bSjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
350b446700bSjanga 						udatalen, nomem);
351b446700bSjanga 			if (!nomem) {
352b446700bSjanga 				(void) snprintf(filter, filterlen, "%s",
353b446700bSjanga 						keyfilter);
354b446700bSjanga 				(void) snprintf(userdata, udatalen,
355b446700bSjanga 						"(&(%%s)%s)", keyfilter);
356b446700bSjanga 			}
3577c478bd9Sstevel@tonic-gate 		}
3587c478bd9Sstevel@tonic-gate 	}
3597c478bd9Sstevel@tonic-gate #ifdef DEBUG
360b446700bSjanga 	(void) fprintf(stdout, "set_filter: filter=\"%s\"\n", filter);
361b446700bSjanga 	(void) fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata);
3627c478bd9Sstevel@tonic-gate #endif /* DEBUG */
363b446700bSjanga 	if (keyfilter)
364b446700bSjanga 		free(keyfilter);
365b446700bSjanga 	if (nomem)
366b446700bSjanga 		exit(2);
367b446700bSjanga 	*udata = userdata;
3687c478bd9Sstevel@tonic-gate 	return (filter);
3697c478bd9Sstevel@tonic-gate }
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate /* generic set_filter, this function is not thread safe */
3737c478bd9Sstevel@tonic-gate char *
3747c478bd9Sstevel@tonic-gate set_filter(char **key, char *database, char **udata)
3757c478bd9Sstevel@tonic-gate {
376b446700bSjanga 	char 		*filter = NULL;
377b446700bSjanga 	char 		*userdata = NULL;
3787c478bd9Sstevel@tonic-gate 	char		*keyfilter;
379b446700bSjanga 	int		i, filterlen, udatalen;
3807c478bd9Sstevel@tonic-gate 	int		rc, v2 = 1;
3817c478bd9Sstevel@tonic-gate 	void		**paramVal = NULL;
3827c478bd9Sstevel@tonic-gate 	ns_ldap_error_t	*errorp = NULL;
383b446700bSjanga 	short		nomem;
3847c478bd9Sstevel@tonic-gate 
385b446700bSjanga 	if (!database || !udata) {
3867c478bd9Sstevel@tonic-gate 		return (NULL);
3877c478bd9Sstevel@tonic-gate 	}
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate 	/*
3917c478bd9Sstevel@tonic-gate 	 * Check for version of the profile the client is using
3927c478bd9Sstevel@tonic-gate 	 *
3937c478bd9Sstevel@tonic-gate 	 * For version 1 profiles we do use nisMap and nisObject schema
3947c478bd9Sstevel@tonic-gate 	 * for backward compatibility with Solaris 8 clients.
3957c478bd9Sstevel@tonic-gate 	 *
3967c478bd9Sstevel@tonic-gate 	 * For version 2 profiles we use automountMap and automount as
3977c478bd9Sstevel@tonic-gate 	 * default attributes (which can then be overridden in libsldap
3987c478bd9Sstevel@tonic-gate 	 * if schema mapping is configured in the profile).
3997c478bd9Sstevel@tonic-gate 	 *
4007c478bd9Sstevel@tonic-gate 	 * If profile version is not available, use version 2 as default.
4017c478bd9Sstevel@tonic-gate 	 */
4027c478bd9Sstevel@tonic-gate 	rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, &paramVal, &errorp);
4037c478bd9Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS || !paramVal || !*paramVal) {
4047c478bd9Sstevel@tonic-gate 		/* should print a message here: using v2 defaults */
4057c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
4067c478bd9Sstevel@tonic-gate 	} else {
4077c478bd9Sstevel@tonic-gate 		if (strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0)
4087c478bd9Sstevel@tonic-gate 			v2 = 0;
4097c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeParam(&paramVal);
4107c478bd9Sstevel@tonic-gate 	}
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	/*
4137c478bd9Sstevel@tonic-gate 	 * starts at 2 to skip over publickey databases.
4147c478bd9Sstevel@tonic-gate 	 * These databases are handled separately.
4157c478bd9Sstevel@tonic-gate 	 */
4167c478bd9Sstevel@tonic-gate 	for (i = 2; maplist[i].database != NULL; i++) {
4177c478bd9Sstevel@tonic-gate 		if (strcasecmp(database, maplist[i].database) == SAME) {
4187c478bd9Sstevel@tonic-gate 			if ((keyfilter = set_keys(key, maplist[i].def_type))
4197c478bd9Sstevel@tonic-gate 							== NULL) {
420b446700bSjanga 				filterlen = strlen(maplist[i].objectclass) + 13;
421b446700bSjanga 				udatalen = 3;
422b446700bSjanga 				MALLOC_FILTER_UDATA(filter, filterlen, userdata,
423b446700bSjanga 						udatalen, nomem);
424b446700bSjanga 				if (!nomem) {
425b446700bSjanga 					(void) snprintf(filter, filterlen,
426b446700bSjanga 						"objectclass=%s",
427b446700bSjanga 						maplist[i].objectclass);
428b446700bSjanga 					(void) snprintf(userdata, udatalen,
429b446700bSjanga 							"%%s");
430b446700bSjanga 				}
4317c478bd9Sstevel@tonic-gate 			} else {
432b446700bSjanga 				filterlen = strlen(maplist[i].objectclass) +
433b446700bSjanga 					strlen(keyfilter) + 18;
434b446700bSjanga 				udatalen = strlen(keyfilter) + 8;
435b446700bSjanga 				MALLOC_FILTER_UDATA(filter, filterlen, userdata,
436b446700bSjanga 						udatalen, nomem);
437b446700bSjanga 				if (!nomem) {
438b446700bSjanga 					(void) snprintf(filter, filterlen,
439b446700bSjanga 					    "(&(objectclass=%s)%s)",
440b446700bSjanga 					    maplist[i].objectclass, keyfilter);
441b446700bSjanga 					(void) snprintf(userdata, udatalen,
442b446700bSjanga 						"(&(%%s)%s)", keyfilter);
443b446700bSjanga 				}
4447c478bd9Sstevel@tonic-gate 			}
445b446700bSjanga 			goto done;
4467c478bd9Sstevel@tonic-gate 		}
4477c478bd9Sstevel@tonic-gate 	}
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate 	/* special cases for automounter and other services */
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 	/* auto_* services */
4527c478bd9Sstevel@tonic-gate 	if (strncasecmp(database, "auto_", 5) == SAME) {
4537c478bd9Sstevel@tonic-gate 	    if (v2) {
4547c478bd9Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "automountKey"))
4557c478bd9Sstevel@tonic-gate 			!= NULL) {
456b446700bSjanga 			filterlen = strlen(keyfilter) + 27;
457b446700bSjanga 			udatalen = strlen(keyfilter) + 8;
458b446700bSjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
459b446700bSjanga 					udatalen, nomem);
460b446700bSjanga 			if (!nomem) {
461b446700bSjanga 				(void) snprintf(filter, filterlen,
462b446700bSjanga 				    "(&(objectclass=automount)%s)",
463b446700bSjanga 					keyfilter);
464b446700bSjanga 				(void) snprintf(userdata, udatalen,
465b446700bSjanga 					"(&(%%s)%s)", keyfilter);
466b446700bSjanga 			}
4677c478bd9Sstevel@tonic-gate 		} else {
468b446700bSjanga 			filterlen = 22;
469b446700bSjanga 			udatalen = 3;
470b446700bSjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
471b446700bSjanga 					udatalen, nomem);
472b446700bSjanga 			if (!nomem) {
473b446700bSjanga 				(void) strlcpy(filter, "objectclass=automount",
474b446700bSjanga 					filterlen);
475b446700bSjanga 				(void) strlcpy(userdata, "%s", udatalen);
476b446700bSjanga 			}
4777c478bd9Sstevel@tonic-gate 		}
4787c478bd9Sstevel@tonic-gate 	    } else {
479b446700bSjanga 		if ((keyfilter = set_keys(key, "cn")) != NULL) {
480b446700bSjanga 			filterlen = strlen(keyfilter) + 27;
481b446700bSjanga 			udatalen = strlen(keyfilter) + 8;
482b446700bSjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
483b446700bSjanga 					udatalen, nomem);
484b446700bSjanga 			if (!nomem) {
485b446700bSjanga 				(void) snprintf(filter, filterlen,
486b446700bSjanga 				    "(&(objectclass=nisObject)%s)", keyfilter);
487b446700bSjanga 				(void) snprintf(userdata, udatalen,
488b446700bSjanga 					"(&(%%s)%s)", keyfilter);
489b446700bSjanga 			}
4907c478bd9Sstevel@tonic-gate 		} else {
491b446700bSjanga 			filterlen = 22;
492b446700bSjanga 			udatalen = 3;
493b446700bSjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
494b446700bSjanga 					udatalen, nomem);
495b446700bSjanga 			if (!nomem) {
496b446700bSjanga 				(void) strlcpy(filter, "objectclass=nisObject",
497b446700bSjanga 						filterlen);
498b446700bSjanga 				(void) strlcpy(userdata, "%s", udatalen);
499b446700bSjanga 			}
5007c478bd9Sstevel@tonic-gate 		}
5017c478bd9Sstevel@tonic-gate 	    }
5027c478bd9Sstevel@tonic-gate 	    goto done;
5037c478bd9Sstevel@tonic-gate 	}
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate 	/* automount service */
5067c478bd9Sstevel@tonic-gate 	if (strcasecmp(database, "automount") == SAME) {
5077c478bd9Sstevel@tonic-gate 	    if (v2) {
5087c478bd9Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "automountMapName"))
5097c478bd9Sstevel@tonic-gate 			!= NULL) {
510b446700bSjanga 			filterlen = strlen(keyfilter) + 30;
511b446700bSjanga 			udatalen = strlen(keyfilter) + 8;
512b446700bSjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
513b446700bSjanga 					udatalen, nomem);
514b446700bSjanga 			if (!nomem) {
515b446700bSjanga 				(void) snprintf(filter, filterlen,
516b446700bSjanga 					"(&(objectclass=automountMap)%s)",
517b446700bSjanga 					keyfilter);
518b446700bSjanga 				(void) snprintf(userdata, udatalen,
519b446700bSjanga 					"(&(%%s)%s)", keyfilter);
520b446700bSjanga 			}
5217c478bd9Sstevel@tonic-gate 		} else {
522b446700bSjanga 			filterlen = 25;
523b446700bSjanga 			udatalen = 3;
524b446700bSjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
525b446700bSjanga 					udatalen, nomem);
526b446700bSjanga 			if (!nomem) {
527b446700bSjanga 				(void) strlcpy(filter,
528b446700bSjanga 					"objectclass=automountMap",
529b446700bSjanga 					filterlen);
530b446700bSjanga 				(void) strlcpy(userdata, "%s", udatalen);
531b446700bSjanga 			}
5327c478bd9Sstevel@tonic-gate 		}
5337c478bd9Sstevel@tonic-gate 	    } else {
5347c478bd9Sstevel@tonic-gate 		if ((keyfilter = set_keys(key, "nisMapName"))
5357c478bd9Sstevel@tonic-gate 			!= NULL) {
536b446700bSjanga 			filterlen = strlen(keyfilter) + 24;
537b446700bSjanga 			udatalen = strlen(keyfilter) + 8;
538b446700bSjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
539b446700bSjanga 					udatalen, nomem);
540b446700bSjanga 			if (!nomem) {
541b446700bSjanga 				(void) snprintf(filter, filterlen,
542b446700bSjanga 					"(&(objectclass=nisMap)%s)",
543b446700bSjanga 					keyfilter);
544b446700bSjanga 				(void) snprintf(userdata, udatalen,
545b446700bSjanga 					"(&(%%s)%s)", keyfilter);
546b446700bSjanga 			}
5477c478bd9Sstevel@tonic-gate 		} else {
548b446700bSjanga 			filterlen = 19;
549b446700bSjanga 			udatalen = 3;
550b446700bSjanga 			MALLOC_FILTER_UDATA(filter, filterlen, userdata,
551b446700bSjanga 					udatalen, nomem);
552b446700bSjanga 			if (!nomem) {
553b446700bSjanga 			    (void) strlcpy(filter, "objectclass=nisMap",
554b446700bSjanga 					filterlen);
555b446700bSjanga 			    (void) strlcpy(userdata, "%s", udatalen);
556b446700bSjanga 			}
5577c478bd9Sstevel@tonic-gate 		}
5587c478bd9Sstevel@tonic-gate 	    }
5597c478bd9Sstevel@tonic-gate 	    goto done;
5607c478bd9Sstevel@tonic-gate 	}
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate 	/* other services (catch all) */
5637c478bd9Sstevel@tonic-gate 	if ((keyfilter = set_keys(key, "cn")) == NULL) {
564b446700bSjanga 		filterlen = 14;
565b446700bSjanga 		udatalen = 3;
566b446700bSjanga 		MALLOC_FILTER_UDATA(filter, filterlen, userdata,
567b446700bSjanga 				udatalen, nomem);
568b446700bSjanga 		if (!nomem) {
569b446700bSjanga 			(void) snprintf(filter, filterlen, "objectclass=*");
570b446700bSjanga 			(void) strlcpy(userdata, "%s", udatalen);
571b446700bSjanga 		}
5727c478bd9Sstevel@tonic-gate 	} else {
573b446700bSjanga 		filterlen = strlen(keyfilter) + 1;
574b446700bSjanga 		udatalen = strlen(keyfilter) + 8;
575b446700bSjanga 		MALLOC_FILTER_UDATA(filter, filterlen, userdata,
576b446700bSjanga 				udatalen, nomem);
577b446700bSjanga 		if (!nomem) {
578b446700bSjanga 			(void) snprintf(filter, filterlen, "%s", keyfilter);
579b446700bSjanga 			(void) snprintf(userdata, udatalen, "(&(%%s)%s)",
580b446700bSjanga 					keyfilter);
581b446700bSjanga 		}
5827c478bd9Sstevel@tonic-gate 	}
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate done:
5857c478bd9Sstevel@tonic-gate #ifdef DEBUG
586b446700bSjanga 	(void) fprintf(stdout, "set_filter: filter=\"%s\"\n", filter);
587b446700bSjanga 	(void) fprintf(stdout, "set_filter: userdata=\"%s\"\n", userdata);
5887c478bd9Sstevel@tonic-gate #endif /* DEBUG */
589b446700bSjanga 	if (keyfilter)
590b446700bSjanga 		free(keyfilter);
591b446700bSjanga 	if (nomem)
592b446700bSjanga 		exit(2);
593b446700bSjanga 	*udata = userdata;
5947c478bd9Sstevel@tonic-gate 	return (filter);
5957c478bd9Sstevel@tonic-gate }
596