Ian Kent 36ee82
diff -up autofs-5.0.2/redhat/autofs.sysconfig.in.ldap-search-basedn-list autofs-5.0.2/redhat/autofs.sysconfig.in
Ian Kent 36ee82
--- autofs-5.0.2/redhat/autofs.sysconfig.in.ldap-search-basedn-list	2007-11-20 14:07:52.000000000 +0900
Ian Kent 36ee82
+++ autofs-5.0.2/redhat/autofs.sysconfig.in	2007-11-20 14:08:26.000000000 +0900
Ian Kent 36ee82
@@ -21,6 +21,14 @@ BROWSE_MODE="no"
Ian Kent 36ee82
 #
Ian Kent 36ee82
 #LOGGING="none"
Ian Kent 36ee82
 #
Ian Kent 36ee82
+# Define base dn for map dn lookup.
Ian Kent 36ee82
+#
Ian Kent 36ee82
+# SEARCH_BASE - base dn to use for searching for map search dn.
Ian Kent 36ee82
+# 		Multiple entries can be given and they are checked
Ian Kent 36ee82
+# 		in the order they occur here.
Ian Kent 36ee82
+#
Ian Kent 36ee82
+#SEARCH_BASE=""
Ian Kent 36ee82
+#
Ian Kent 36ee82
 # Define the LDAP schema to used for lookups
Ian Kent 36ee82
 #
Ian Kent 36ee82
 # If no schema is set autofs will check each of the schemas
Ian Kent 36ee82
diff -up autofs-5.0.2/include/lookup_ldap.h.ldap-search-basedn-list autofs-5.0.2/include/lookup_ldap.h
Ian Kent 36ee82
--- autofs-5.0.2/include/lookup_ldap.h.ldap-search-basedn-list	2007-11-20 14:07:52.000000000 +0900
Ian Kent 36ee82
+++ autofs-5.0.2/include/lookup_ldap.h	2007-11-20 14:08:26.000000000 +0900
Ian Kent 36ee82
@@ -18,6 +18,11 @@ struct ldap_schema {
Ian Kent 36ee82
 	char *value_attr;
Ian Kent 36ee82
 };
Ian Kent 36ee82
 
Ian Kent 36ee82
+struct ldap_searchdn {
Ian Kent 36ee82
+	char *basedn;
Ian Kent 36ee82
+	struct ldap_searchdn *next;
Ian Kent 36ee82
+};
Ian Kent 36ee82
+
Ian Kent 36ee82
 struct lookup_context {
Ian Kent 36ee82
 	char *mapname;
Ian Kent 36ee82
 
Ian Kent 36ee82
@@ -32,6 +37,10 @@ struct lookup_context {
Ian Kent 36ee82
 	/* LDAP lookup configuration */
Ian Kent 36ee82
 	struct ldap_schema *schema;
Ian Kent 36ee82
 
Ian Kent 36ee82
+	/* List of base dns for searching */
Ian Kent 36ee82
+	char *cur_host;
Ian Kent 36ee82
+	struct ldap_searchdn *sdns;
Ian Kent 36ee82
+
Ian Kent 36ee82
 	/* TLS and SASL authentication information */
Ian Kent 36ee82
 	char        *auth_conf;
Ian Kent 36ee82
 	unsigned     use_tls;
Ian Kent 36ee82
diff -up autofs-5.0.2/include/defaults.h.ldap-search-basedn-list autofs-5.0.2/include/defaults.h
Ian Kent 36ee82
--- autofs-5.0.2/include/defaults.h.ldap-search-basedn-list	2007-11-20 14:07:52.000000000 +0900
Ian Kent 36ee82
+++ autofs-5.0.2/include/defaults.h	2007-11-20 14:08:26.000000000 +0900
Ian Kent 36ee82
@@ -37,6 +37,9 @@
Ian Kent 36ee82
 #define DEFAULT_APPEND_OPTIONS		1
Ian Kent 36ee82
 #define DEFAULT_AUTH_CONF_FILE		AUTOFS_MAP_DIR "/autofs_ldap_auth.conf"
Ian Kent 36ee82
 
Ian Kent 36ee82
+struct ldap_schema;
Ian Kent 36ee82
+struct ldap_searchdn;
Ian Kent 36ee82
+
Ian Kent 36ee82
 unsigned int defaults_read_config(void);
Ian Kent 36ee82
 const char *defaults_get_master_map(void);
Ian Kent 36ee82
 unsigned int defaults_get_timeout(void);
Ian Kent 36ee82
@@ -45,6 +48,8 @@ unsigned int defaults_get_logging(void);
Ian Kent 36ee82
 const char *defaults_get_ldap_server(void);
Ian Kent 36ee82
 struct ldap_schema *defaults_get_default_schema(void);
Ian Kent 36ee82
 struct ldap_schema *defaults_get_schema(void);
Ian Kent 36ee82
+struct ldap_searchdn *defaults_get_searchdns(void);
Ian Kent 36ee82
+void defaults_free_searchdns(struct ldap_searchdn *);
Ian Kent 36ee82
 unsigned int defaults_get_append_options(void);
Ian Kent 36ee82
 const char *defaults_get_auth_conf_file(void);
Ian Kent 36ee82
 
Ian Kent 36ee82
diff -up autofs-5.0.2/modules/lookup_ldap.c.ldap-search-basedn-list autofs-5.0.2/modules/lookup_ldap.c
Ian Kent 36ee82
--- autofs-5.0.2/modules/lookup_ldap.c.ldap-search-basedn-list	2007-11-20 14:07:52.000000000 +0900
Ian Kent 36ee82
+++ autofs-5.0.2/modules/lookup_ldap.c	2007-11-20 14:09:58.000000000 +0900
Ian Kent 36ee82
@@ -171,10 +171,207 @@ LDAP *init_ldap_connection(struct lookup
Ian Kent 36ee82
 	return ldap;
Ian Kent 36ee82
 }
Ian Kent 36ee82
 
Ian Kent 36ee82
+static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key)
Ian Kent 36ee82
+{
Ian Kent 36ee82
+	char buf[PARSE_MAX_BUF];
Ian Kent 36ee82
+	char *query, *dn;
Ian Kent 36ee82
+	LDAPMessage *result = NULL, *e;
Ian Kent 36ee82
+	struct ldap_searchdn *sdns = NULL;
Ian Kent 36ee82
+	char *attrs[2];
Ian Kent 36ee82
+	int scope;
Ian Kent 36ee82
+	int rv, l;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	attrs[0] = LDAP_NO_ATTRS;
Ian Kent 36ee82
+	attrs[1] = NULL;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	if (!ctxt->mapname && !ctxt->base) {
Ian Kent 36ee82
+		error(LOGOPT_ANY, MODPREFIX "no master map to lookup");
Ian Kent 36ee82
+		return 0;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	/* Build a query string. */
Ian Kent 36ee82
+	l = strlen("(objectclass=)") + strlen(class) + 1;
Ian Kent 36ee82
+	if (ctxt->mapname)
Ian Kent 36ee82
+		l += strlen(key) + strlen(ctxt->mapname) + strlen("(&(=))");
Ian Kent 36ee82
+
Ian Kent 36ee82
+	query = alloca(l);
Ian Kent 36ee82
+	if (query == NULL) {
Ian Kent 36ee82
+		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
Ian Kent 36ee82
+		crit(LOGOPT_ANY, MODPREFIX "alloca: %s", estr);
Ian Kent 36ee82
+		return NSS_STATUS_UNAVAIL;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	/*
Ian Kent 36ee82
+	 * If we have a master mapname construct a query using it
Ian Kent 36ee82
+	 * otherwise assume the base dn will catch it.
Ian Kent 36ee82
+	 */
Ian Kent 36ee82
+	if (ctxt->mapname) {
Ian Kent 36ee82
+		if (sprintf(query, "(&(objectclass=%s)(%s=%.*s))", class,
Ian Kent 36ee82
+		     key, (int) strlen(ctxt->mapname), ctxt->mapname) >= l) {
Ian Kent 36ee82
+			debug(LOGOPT_NONE,
Ian Kent 36ee82
+			      MODPREFIX "error forming query string");
Ian Kent 36ee82
+			return 0;
Ian Kent 36ee82
+		}
Ian Kent 36ee82
+		scope = LDAP_SCOPE_SUBTREE;
Ian Kent 36ee82
+	} else {
Ian Kent 36ee82
+		if (sprintf(query, "(objectclass=%s)", class) >= l) {
Ian Kent 36ee82
+			debug(LOGOPT_NONE,
Ian Kent 36ee82
+			      MODPREFIX "error forming query string");
Ian Kent 36ee82
+			return 0;
Ian Kent 36ee82
+		}
Ian Kent 36ee82
+		scope = LDAP_SCOPE_SUBTREE;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+	query[l] = '\0';
Ian Kent 36ee82
+
Ian Kent 36ee82
+	if (!ctxt->base) {
Ian Kent 36ee82
+		sdns = defaults_get_searchdns();
Ian Kent 36ee82
+		if (sdns)
Ian Kent 36ee82
+			ctxt->sdns = sdns;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	if (!sdns)
Ian Kent 36ee82
+		rv = ldap_search_s(ldap, ctxt->base,
Ian Kent 36ee82
+				   scope, query, attrs, 0, &result);
Ian Kent 36ee82
+	else {
Ian Kent 36ee82
+		struct ldap_searchdn *this = sdns;
Ian Kent 36ee82
+
Ian Kent 36ee82
+		debug(LOGOPT_NONE, MODPREFIX
Ian Kent 36ee82
+			      "check search base list");
Ian Kent 36ee82
+
Ian Kent 36ee82
+		while (this) {
Ian Kent 36ee82
+			rv = ldap_search_s(ldap, this->basedn,
Ian Kent 36ee82
+					   scope, query, attrs, 0, &result);
Ian Kent 36ee82
+
Ian Kent 36ee82
+			if ((rv == LDAP_SUCCESS) && result) {
Ian Kent 36ee82
+				debug(LOGOPT_NONE, MODPREFIX
Ian Kent 36ee82
+				      "found search base under %s",
Ian Kent 36ee82
+				      this->basedn);
Ian Kent 36ee82
+				break;
Ian Kent 36ee82
+			}
Ian Kent 36ee82
+
Ian Kent 36ee82
+			this = this->next;
Ian Kent 36ee82
+
Ian Kent 36ee82
+			if (result) {
Ian Kent 36ee82
+				ldap_msgfree(result);
Ian Kent 36ee82
+				result = NULL;
Ian Kent 36ee82
+			}
Ian Kent 36ee82
+		}
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	if ((rv != LDAP_SUCCESS) || !result) {
Ian Kent 36ee82
+		error(LOGOPT_NONE,
Ian Kent 36ee82
+		      MODPREFIX "query failed for %s: %s",
Ian Kent 36ee82
+		      query, ldap_err2string(rv));
Ian Kent 36ee82
+		return 0;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	e = ldap_first_entry(ldap, result);
Ian Kent 36ee82
+	if (e) {
Ian Kent 36ee82
+		dn = ldap_get_dn(ldap, e);
Ian Kent 36ee82
+		debug(LOGOPT_NONE, MODPREFIX "query dn %s", dn);
Ian Kent 36ee82
+		ldap_msgfree(result);
Ian Kent 36ee82
+	} else {
Ian Kent 36ee82
+		debug(LOGOPT_NONE,
Ian Kent 36ee82
+		      MODPREFIX "query succeeded, no matches for %s",
Ian Kent 36ee82
+		      query);
Ian Kent 36ee82
+		ldap_msgfree(result);
Ian Kent 36ee82
+		return 0;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	ctxt->qdn = dn;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	return 1;
Ian Kent 36ee82
+}
Ian Kent 36ee82
+
Ian Kent 36ee82
+static struct ldap_schema *alloc_common_schema(struct ldap_schema *s)
Ian Kent 36ee82
+{
Ian Kent 36ee82
+	struct ldap_schema *schema;
Ian Kent 36ee82
+	char *mc, *ma, *ec, *ea, *va;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	mc = strdup(s->map_class);
Ian Kent 36ee82
+	if (!mc)
Ian Kent 36ee82
+		return NULL;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	ma = strdup(s->map_attr);
Ian Kent 36ee82
+	if (!ma) {
Ian Kent 36ee82
+		free(mc);
Ian Kent 36ee82
+		return NULL;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	ec = strdup(s->entry_class);
Ian Kent 36ee82
+	if (!ec) {
Ian Kent 36ee82
+		free(mc);
Ian Kent 36ee82
+		free(ma);
Ian Kent 36ee82
+		return NULL;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	ea = strdup(s->entry_attr);
Ian Kent 36ee82
+	if (!ea) {
Ian Kent 36ee82
+		free(mc);
Ian Kent 36ee82
+		free(ma);
Ian Kent 36ee82
+		free(ec);
Ian Kent 36ee82
+		return NULL;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	va = strdup(s->value_attr);
Ian Kent 36ee82
+	if (!va) {
Ian Kent 36ee82
+		free(mc);
Ian Kent 36ee82
+		free(ma);
Ian Kent 36ee82
+		free(ec);
Ian Kent 36ee82
+		free(ea);
Ian Kent 36ee82
+		return NULL;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	schema = malloc(sizeof(struct ldap_schema));
Ian Kent 36ee82
+	if (!schema) {
Ian Kent 36ee82
+		free(mc);
Ian Kent 36ee82
+		free(ma);
Ian Kent 36ee82
+		free(ec);
Ian Kent 36ee82
+		free(ea);
Ian Kent 36ee82
+		free(va);
Ian Kent 36ee82
+		return NULL;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	schema->map_class = mc;
Ian Kent 36ee82
+	schema->map_attr = ma;
Ian Kent 36ee82
+	schema->entry_class = ec;
Ian Kent 36ee82
+	schema->entry_attr = ea;
Ian Kent 36ee82
+	schema->value_attr = va;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	return schema;
Ian Kent 36ee82
+}
Ian Kent 36ee82
+
Ian Kent 36ee82
+static int find_query_dn(LDAP *ldap, struct lookup_context *ctxt)
Ian Kent 36ee82
+{
Ian Kent 36ee82
+	struct ldap_schema *schema;
Ian Kent 36ee82
+	unsigned int i;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	if (ctxt->schema)
Ian Kent 36ee82
+		return 0;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	for (i = 0; i < common_schema_count; i++) {
Ian Kent 36ee82
+		const char *class = common_schema[i].map_class;
Ian Kent 36ee82
+		const char *key = common_schema[i].map_attr;
Ian Kent 36ee82
+		if (get_query_dn(ldap, ctxt, class, key)) {
Ian Kent 36ee82
+			schema = alloc_common_schema(&common_schema[i]);
Ian Kent 36ee82
+			if (!schema) {
Ian Kent 36ee82
+				error(LOGOPT_ANY,
Ian Kent 36ee82
+				      MODPREFIX "failed to allocate schema");
Ian Kent 36ee82
+				return 0;
Ian Kent 36ee82
+			}
Ian Kent 36ee82
+			ctxt->schema = schema;
Ian Kent 36ee82
+			return 1;
Ian Kent 36ee82
+		}
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	return 0;
Ian Kent 36ee82
+}
Ian Kent 36ee82
+
Ian Kent 36ee82
 static LDAP *do_connect(struct lookup_context *ctxt)
Ian Kent 36ee82
 {
Ian Kent 36ee82
 	LDAP *ldap;
Ian Kent 36ee82
-	int rv;
Ian Kent 36ee82
+	char *host = NULL, *nhost;
Ian Kent 36ee82
+	int rv, need_base = 1;
Ian Kent 36ee82
 
Ian Kent 36ee82
 	ldap = init_ldap_connection(ctxt);
Ian Kent 36ee82
 	if (!ldap)
Ian Kent 36ee82
@@ -204,6 +401,61 @@ static LDAP *do_connect(struct lookup_co
Ian Kent 36ee82
 		return NULL;
Ian Kent 36ee82
 	}
Ian Kent 36ee82
 
Ian Kent 36ee82
+	rv = ldap_get_option(ldap, LDAP_OPT_HOST_NAME, &host);
Ian Kent 36ee82
+        if (rv != LDAP_SUCCESS || !host) {
Ian Kent 36ee82
+		unbind_ldap_connection(ldap, ctxt);
Ian Kent 36ee82
+		debug(LOGOPT_ANY, "failed to get hostname for connection");
Ian Kent 36ee82
+		return NULL;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	nhost = strdup(host);
Ian Kent 36ee82
+	if (!nhost) {
Ian Kent 36ee82
+		unbind_ldap_connection(ldap, ctxt);
Ian Kent 36ee82
+		debug(LOGOPT_ANY, "failed to alloc context for hostname");
Ian Kent 36ee82
+		return NULL;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+	ldap_memfree(host);
Ian Kent 36ee82
+
Ian Kent 36ee82
+	if (!ctxt->cur_host) {
Ian Kent 36ee82
+		ctxt->cur_host = nhost;
Ian Kent 36ee82
+		/* Check if schema defined in conf first time only */
Ian Kent 36ee82
+		ctxt->schema = defaults_get_schema();
Ian Kent 36ee82
+	} else {
Ian Kent 36ee82
+		/* If connection host has changed update */
Ian Kent 36ee82
+		if (strcmp(ctxt->cur_host, nhost)) {
Ian Kent 36ee82
+			free(ctxt->cur_host);
Ian Kent 36ee82
+			ctxt->cur_host = nhost;
Ian Kent 36ee82
+		} else {
Ian Kent 36ee82
+			free(nhost);
Ian Kent 36ee82
+			need_base = 0;
Ian Kent 36ee82
+		}
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	if (!need_base)
Ian Kent 36ee82
+		return ldap;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	/*
Ian Kent 36ee82
+	 * If the schema isn't defined in the configuration then check for
Ian Kent 36ee82
+	 * presence of a map dn with a the common schema. Then calculate the
Ian Kent 36ee82
+	 * base dn for searches.
Ian Kent 36ee82
+	 */
Ian Kent 36ee82
+	if (!ctxt->schema) {
Ian Kent 36ee82
+		if (!find_query_dn(ldap, ctxt)) {
Ian Kent 36ee82
+			unbind_ldap_connection(ldap, ctxt);
Ian Kent 36ee82
+			error(LOGOPT_ANY,
Ian Kent 36ee82
+		      	      MODPREFIX "failed to find valid query dn");
Ian Kent 36ee82
+			return NULL;
Ian Kent 36ee82
+		}
Ian Kent 36ee82
+	} else {
Ian Kent 36ee82
+		const char *class = ctxt->schema->map_class;
Ian Kent 36ee82
+		const char *key = ctxt->schema->map_attr;
Ian Kent 36ee82
+		if (!get_query_dn(ldap, ctxt, class, key)) {
Ian Kent 36ee82
+			unbind_ldap_connection(ldap, ctxt);
Ian Kent 36ee82
+			error(LOGOPT_ANY, MODPREFIX "failed to get query dn");
Ian Kent 36ee82
+			return NULL;
Ian Kent 36ee82
+		}
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
 	return ldap;
Ian Kent 36ee82
 }
Ian Kent 36ee82
 
Ian Kent 36ee82
@@ -769,177 +1021,17 @@ static void free_context(struct lookup_c
Ian Kent 36ee82
 		ldap_memfree(ctxt->qdn);
Ian Kent 36ee82
 	if (ctxt->server)
Ian Kent 36ee82
 		free(ctxt->server);
Ian Kent 36ee82
+	if (ctxt->cur_host)
Ian Kent 36ee82
+		free(ctxt->cur_host);
Ian Kent 36ee82
 	if (ctxt->base)
Ian Kent 36ee82
 		free(ctxt->base);
Ian Kent 36ee82
+	if (ctxt->sdns)
Ian Kent 36ee82
+		defaults_free_searchdns(ctxt->sdns);
Ian Kent 36ee82
 	free(ctxt);
Ian Kent 36ee82
 
Ian Kent 36ee82
 	return;
Ian Kent 36ee82
 }
Ian Kent 36ee82
 
Ian Kent 36ee82
-static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key)
Ian Kent 36ee82
-{
Ian Kent 36ee82
-	char buf[PARSE_MAX_BUF];
Ian Kent 36ee82
-	char *query, *dn;
Ian Kent 36ee82
-	LDAPMessage *result, *e;
Ian Kent 36ee82
-	char *attrs[2];
Ian Kent 36ee82
-	struct berval **value;
Ian Kent 36ee82
-	int scope;
Ian Kent 36ee82
-	int rv, l;
Ian Kent 36ee82
-
Ian Kent 36ee82
-	attrs[0] = (char *) key;
Ian Kent 36ee82
-	attrs[1] = NULL;
Ian Kent 36ee82
-
Ian Kent 36ee82
-	if (!ctxt->mapname && !ctxt->base) {
Ian Kent 36ee82
-		error(LOGOPT_ANY, MODPREFIX "no master map to lookup");
Ian Kent 36ee82
-		return 0;
Ian Kent 36ee82
-	}
Ian Kent 36ee82
-
Ian Kent 36ee82
-	/* Build a query string. */
Ian Kent 36ee82
-	l = strlen("(objectclass=)") + strlen(class) + 1;
Ian Kent 36ee82
-	if (ctxt->mapname)
Ian Kent 36ee82
-		l += strlen(key) + strlen(ctxt->mapname) + strlen("(&(=))");
Ian Kent 36ee82
-
Ian Kent 36ee82
-	query = alloca(l);
Ian Kent 36ee82
-	if (query == NULL) {
Ian Kent 36ee82
-		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
Ian Kent 36ee82
-		crit(LOGOPT_ANY, MODPREFIX "alloca: %s", estr);
Ian Kent 36ee82
-		return NSS_STATUS_UNAVAIL;
Ian Kent 36ee82
-	}
Ian Kent 36ee82
-
Ian Kent 36ee82
-	/*
Ian Kent 36ee82
-	 * If we have a master mapname construct a query using it
Ian Kent 36ee82
-	 * otherwise assume the base dn will catch it.
Ian Kent 36ee82
-	 */
Ian Kent 36ee82
-	if (ctxt->mapname) {
Ian Kent 36ee82
-		if (sprintf(query, "(&(objectclass=%s)(%s=%.*s))", class,
Ian Kent 36ee82
-		     key, (int) strlen(ctxt->mapname), ctxt->mapname) >= l) {
Ian Kent 36ee82
-			debug(LOGOPT_NONE,
Ian Kent 36ee82
-			      MODPREFIX "error forming query string");
Ian Kent 36ee82
-			return 0;
Ian Kent 36ee82
-		}
Ian Kent 36ee82
-		scope = LDAP_SCOPE_SUBTREE;
Ian Kent 36ee82
-	} else {
Ian Kent 36ee82
-		if (sprintf(query, "(objectclass=%s)", class) >= l) {
Ian Kent 36ee82
-			debug(LOGOPT_NONE,
Ian Kent 36ee82
-			      MODPREFIX "error forming query string");
Ian Kent 36ee82
-			return 0;
Ian Kent 36ee82
-		}
Ian Kent 36ee82
-		scope = LDAP_SCOPE_SUBTREE;
Ian Kent 36ee82
-	}
Ian Kent 36ee82
-	query[l] = '\0';
Ian Kent 36ee82
-
Ian Kent 36ee82
-	rv = ldap_search_s(ldap, ctxt->base, scope, query, attrs, 0, &result);
Ian Kent 36ee82
-
Ian Kent 36ee82
-	if ((rv != LDAP_SUCCESS) || !result) {
Ian Kent 36ee82
-		error(LOGOPT_NONE,
Ian Kent 36ee82
-		      MODPREFIX "query failed for %s: %s",
Ian Kent 36ee82
-		      query, ldap_err2string(rv));
Ian Kent 36ee82
-		return 0;
Ian Kent 36ee82
-	}
Ian Kent 36ee82
-
Ian Kent 36ee82
-	e = ldap_first_entry(ldap, result);
Ian Kent 36ee82
-	if (e && (value = ldap_get_values_len(ldap, e, key))) {
Ian Kent 36ee82
-		ldap_value_free_len(value);
Ian Kent 36ee82
-		dn = ldap_get_dn(ldap, e);
Ian Kent 36ee82
-		debug(LOGOPT_NONE, MODPREFIX "query dn %s", dn);
Ian Kent 36ee82
-		ldap_msgfree(result);
Ian Kent 36ee82
-	} else {
Ian Kent 36ee82
-		debug(LOGOPT_NONE,
Ian Kent 36ee82
-		      MODPREFIX "query succeeded, no matches for %s",
Ian Kent 36ee82
-		      query);
Ian Kent 36ee82
-		ldap_msgfree(result);
Ian Kent 36ee82
-		return 0;
Ian Kent 36ee82
-	}
Ian Kent 36ee82
-
Ian Kent 36ee82
-	ctxt->qdn = dn;
Ian Kent 36ee82
-
Ian Kent 36ee82
-	return 1;
Ian Kent 36ee82
-}
Ian Kent 36ee82
-
Ian Kent 36ee82
-static struct ldap_schema *alloc_common_schema(struct ldap_schema *s)
Ian Kent 36ee82
-{
Ian Kent 36ee82
-	struct ldap_schema *schema;
Ian Kent 36ee82
-	char *mc, *ma, *ec, *ea, *va;
Ian Kent 36ee82
-
Ian Kent 36ee82
-	mc = strdup(s->map_class);
Ian Kent 36ee82
-	if (!mc)
Ian Kent 36ee82
-		return NULL;
Ian Kent 36ee82
-
Ian Kent 36ee82
-	ma = strdup(s->map_attr);
Ian Kent 36ee82
-	if (!ma) {
Ian Kent 36ee82
-		free(mc);
Ian Kent 36ee82
-		return NULL;
Ian Kent 36ee82
-	}
Ian Kent 36ee82
-
Ian Kent 36ee82
-	ec = strdup(s->entry_class);
Ian Kent 36ee82
-	if (!ec) {
Ian Kent 36ee82
-		free(mc);
Ian Kent 36ee82
-		free(ma);
Ian Kent 36ee82
-		return NULL;
Ian Kent 36ee82
-	}
Ian Kent 36ee82
-
Ian Kent 36ee82
-	ea = strdup(s->entry_attr);
Ian Kent 36ee82
-	if (!ea) {
Ian Kent 36ee82
-		free(mc);
Ian Kent 36ee82
-		free(ma);
Ian Kent 36ee82
-		free(ec);
Ian Kent 36ee82
-		return NULL;
Ian Kent 36ee82
-	}
Ian Kent 36ee82
-
Ian Kent 36ee82
-	va = strdup(s->value_attr);
Ian Kent 36ee82
-	if (!va) {
Ian Kent 36ee82
-		free(mc);
Ian Kent 36ee82
-		free(ma);
Ian Kent 36ee82
-		free(ec);
Ian Kent 36ee82
-		free(ea);
Ian Kent 36ee82
-		return NULL;
Ian Kent 36ee82
-	}
Ian Kent 36ee82
-
Ian Kent 36ee82
-	schema = malloc(sizeof(struct ldap_schema));
Ian Kent 36ee82
-	if (!schema) {
Ian Kent 36ee82
-		free(mc);
Ian Kent 36ee82
-		free(ma);
Ian Kent 36ee82
-		free(ec);
Ian Kent 36ee82
-		free(ea);
Ian Kent 36ee82
-		free(va);
Ian Kent 36ee82
-		return NULL;
Ian Kent 36ee82
-	}
Ian Kent 36ee82
-
Ian Kent 36ee82
-	schema->map_class = mc;
Ian Kent 36ee82
-	schema->map_attr = ma;
Ian Kent 36ee82
-	schema->entry_class = ec;
Ian Kent 36ee82
-	schema->entry_attr = ea;
Ian Kent 36ee82
-	schema->value_attr = va;
Ian Kent 36ee82
-
Ian Kent 36ee82
-	return schema;
Ian Kent 36ee82
-}
Ian Kent 36ee82
-
Ian Kent 36ee82
-static int find_query_dn(LDAP *ldap, struct lookup_context *ctxt)
Ian Kent 36ee82
-{
Ian Kent 36ee82
-	struct ldap_schema *schema;
Ian Kent 36ee82
-	unsigned int i;
Ian Kent 36ee82
-
Ian Kent 36ee82
-	if (ctxt->schema)
Ian Kent 36ee82
-		return 0;
Ian Kent 36ee82
-
Ian Kent 36ee82
-	for (i = 0; i < common_schema_count; i++) {
Ian Kent 36ee82
-		const char *class = common_schema[i].map_class;
Ian Kent 36ee82
-		const char *key = common_schema[i].map_attr;
Ian Kent 36ee82
-		if (get_query_dn(ldap, ctxt, class, key)) {
Ian Kent 36ee82
-			schema = alloc_common_schema(&common_schema[i]);
Ian Kent 36ee82
-			if (!schema) {
Ian Kent 36ee82
-				error(LOGOPT_ANY,
Ian Kent 36ee82
-				      MODPREFIX "failed to allocate schema");
Ian Kent 36ee82
-				return 0;
Ian Kent 36ee82
-			}
Ian Kent 36ee82
-			ctxt->schema = schema;
Ian Kent 36ee82
-			return 1;
Ian Kent 36ee82
-		}
Ian Kent 36ee82
-	}
Ian Kent 36ee82
-
Ian Kent 36ee82
-	return 0;
Ian Kent 36ee82
-}
Ian Kent 36ee82
-
Ian Kent 36ee82
 /*
Ian Kent 36ee82
  * This initializes a context (persistent non-global data) for queries to
Ian Kent 36ee82
  * this module.  Return zero if we succeed.
Ian Kent 36ee82
@@ -996,31 +1088,6 @@ int lookup_init(const char *mapfmt, int 
Ian Kent 36ee82
 		free_context(ctxt);
Ian Kent 36ee82
 		return 1;
Ian Kent 36ee82
 	}
Ian Kent 36ee82
-
Ian Kent 36ee82
-	/*
Ian Kent 36ee82
-	 * Get default schema for queries.
Ian Kent 36ee82
-	 * If the schema isn't defined in the configuration then check for
Ian Kent 36ee82
-	 * presence of a map dn in the common schemas.
Ian Kent 36ee82
-	 */
Ian Kent 36ee82
-	ctxt->schema = defaults_get_schema();
Ian Kent 36ee82
-	if (!ctxt->schema) {
Ian Kent 36ee82
-		if (!find_query_dn(ldap, ctxt)) {
Ian Kent 36ee82
-			unbind_ldap_connection(ldap, ctxt);
Ian Kent 36ee82
-			error(LOGOPT_ANY,
Ian Kent 36ee82
-			      MODPREFIX "failed to find valid query dn");
Ian Kent 36ee82
-			free_context(ctxt);
Ian Kent 36ee82
-			return 1;
Ian Kent 36ee82
-		}
Ian Kent 36ee82
-	} else {
Ian Kent 36ee82
-		const char *class = ctxt->schema->map_class;
Ian Kent 36ee82
-		const char *key = ctxt->schema->map_attr;
Ian Kent 36ee82
-		if (!get_query_dn(ldap, ctxt, class, key)) {
Ian Kent 36ee82
-			unbind_ldap_connection(ldap, ctxt);
Ian Kent 36ee82
-			error(LOGOPT_ANY, MODPREFIX "failed to get query dn");
Ian Kent 36ee82
-			free_context(ctxt);
Ian Kent 36ee82
-			return 1;
Ian Kent 36ee82
-		}
Ian Kent 36ee82
-	}
Ian Kent 36ee82
 	unbind_ldap_connection(ldap, ctxt);
Ian Kent 36ee82
 
Ian Kent 36ee82
 	/* Open the parser, if we can. */
Ian Kent 36ee82
diff -up autofs-5.0.2/samples/autofs.conf.default.in.ldap-search-basedn-list autofs-5.0.2/samples/autofs.conf.default.in
Ian Kent 36ee82
--- autofs-5.0.2/samples/autofs.conf.default.in.ldap-search-basedn-list	2007-11-20 14:07:52.000000000 +0900
Ian Kent 36ee82
+++ autofs-5.0.2/samples/autofs.conf.default.in	2007-11-20 14:08:26.000000000 +0900
Ian Kent 36ee82
@@ -21,6 +21,14 @@ BROWSE_MODE="no"
Ian Kent 36ee82
 #
Ian Kent 36ee82
 #LOGGING="none"
Ian Kent 36ee82
 #
Ian Kent 36ee82
+# Define base dn for map dn lookup.
Ian Kent 36ee82
+#
Ian Kent 36ee82
+# SEARCH_BASE - base dn to use for searching for map search dn.
Ian Kent 36ee82
+# 		Multiple entries can be given and they are checked
Ian Kent 36ee82
+# 		in the order they occur here.
Ian Kent 36ee82
+#
Ian Kent 36ee82
+#SEARCH_BASE=""
Ian Kent 36ee82
+#
Ian Kent 36ee82
 # Define the LDAP schema to used for lookups
Ian Kent 36ee82
 #
Ian Kent 36ee82
 # If no schema is set autofs will check each of the schemas
Ian Kent 36ee82
diff -up autofs-5.0.2/lib/defaults.c.ldap-search-basedn-list autofs-5.0.2/lib/defaults.c
Ian Kent 36ee82
--- autofs-5.0.2/lib/defaults.c.ldap-search-basedn-list	2007-11-20 14:07:52.000000000 +0900
Ian Kent 36ee82
+++ autofs-5.0.2/lib/defaults.c	2007-11-20 14:08:26.000000000 +0900
Ian Kent 36ee82
@@ -32,6 +32,8 @@
Ian Kent 36ee82
 
Ian Kent 36ee82
 #define ENV_LDAP_SERVER			"LDAP_SERVER"
Ian Kent 36ee82
 
Ian Kent 36ee82
+#define SEARCH_BASE			"SEARCH_BASE"
Ian Kent 36ee82
+
Ian Kent 36ee82
 #define ENV_NAME_MAP_OBJ_CLASS		"MAP_OBJECT_CLASS"
Ian Kent 36ee82
 #define ENV_NAME_ENTRY_OBJ_CLASS	"ENTRY_OBJECT_CLASS"
Ian Kent 36ee82
 #define ENV_NAME_MAP_ATTR		"MAP_ATTRIBUTE"
Ian Kent 36ee82
@@ -130,6 +132,52 @@ static int check_set_config_value(const 
Ian Kent 36ee82
 	return 0;
Ian Kent 36ee82
 }
Ian Kent 36ee82
 
Ian Kent 36ee82
+static int parse_line(char *line, char **res, char **value)
Ian Kent 36ee82
+{
Ian Kent 36ee82
+	char *key, *val, *trailer;
Ian Kent 36ee82
+	int len;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	key = line;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	if (*key == '#' || !isalpha(*key))
Ian Kent 36ee82
+		return 0;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	while (*key && *key == ' ')
Ian Kent 36ee82
+		key++;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	if (!key)
Ian Kent 36ee82
+		return 0;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	if (!(val = strchr(key, '=')))
Ian Kent 36ee82
+		return 0;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	*val++ = '\0';
Ian Kent 36ee82
+
Ian Kent 36ee82
+	while (*val && (*val == '"' || isblank(*val)))
Ian Kent 36ee82
+		val++;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	len = strlen(val);
Ian Kent 36ee82
+
Ian Kent 36ee82
+	if (val[len - 1] == '\n') {
Ian Kent 36ee82
+		val[len - 1] = '\0';
Ian Kent 36ee82
+		len--;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	trailer = strchr(val, '#');
Ian Kent 36ee82
+	if (!trailer)
Ian Kent 36ee82
+		trailer = val + len - 1;
Ian Kent 36ee82
+	else
Ian Kent 36ee82
+		trailer--;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	while (*trailer && (*trailer == '"' || isblank(*trailer)))
Ian Kent 36ee82
+		*(trailer--) = '\0';;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	*res = key;
Ian Kent 36ee82
+	*value = val;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	return 1;
Ian Kent 36ee82
+}
Ian Kent 36ee82
+
Ian Kent 36ee82
 /*
Ian Kent 36ee82
  * Read config env variables and check they have been set.
Ian Kent 36ee82
  *
Ian Kent 36ee82
@@ -141,61 +189,30 @@ unsigned int defaults_read_config(void)
Ian Kent 36ee82
 {
Ian Kent 36ee82
 	FILE *f;
Ian Kent 36ee82
 	char buf[MAX_LINE_LEN];
Ian Kent 36ee82
-	char *res, *value;
Ian Kent 36ee82
+	char *res;
Ian Kent 36ee82
 
Ian Kent 36ee82
 	f = fopen(DEFAULTS_CONFIG_FILE, "r");
Ian Kent 36ee82
 	if (!f)
Ian Kent 36ee82
 		return 0;
Ian Kent 36ee82
 
Ian Kent 36ee82
 	while ((res = fgets(buf, MAX_LINE_LEN, f))) {
Ian Kent 36ee82
-		char *trailer;
Ian Kent 36ee82
-		int len;
Ian Kent 36ee82
-
Ian Kent 36ee82
-		if (*res == '#' || !isalpha(*res))
Ian Kent 36ee82
-			continue;
Ian Kent 36ee82
-
Ian Kent 36ee82
-		while (*res && *res == ' ')
Ian Kent 36ee82
-			res++;
Ian Kent 36ee82
-
Ian Kent 36ee82
-		if (!res)
Ian Kent 36ee82
-			continue;
Ian Kent 36ee82
+		char *key, *value;
Ian Kent 36ee82
 
Ian Kent 36ee82
-		if (!(value = strchr(res, '=')))
Ian Kent 36ee82
+		if (!parse_line(res, &key, &value))
Ian Kent 36ee82
 			continue;
Ian Kent 36ee82
 
Ian Kent 36ee82
-		*value++ = '\0';
Ian Kent 36ee82
-
Ian Kent 36ee82
-		while (*value && (*value == '"' || isblank(*value)))
Ian Kent 36ee82
-			value++;
Ian Kent 36ee82
-
Ian Kent 36ee82
-		len = strlen(value);
Ian Kent 36ee82
-
Ian Kent 36ee82
-		if (value[len - 1] == '\n') {
Ian Kent 36ee82
-			value[len - 1] = '\0';
Ian Kent 36ee82
-			len--;
Ian Kent 36ee82
-		}
Ian Kent 36ee82
-
Ian Kent 36ee82
-		trailer = strchr(value, '#');
Ian Kent 36ee82
-		if (!trailer)
Ian Kent 36ee82
-			trailer = value + len - 1;
Ian Kent 36ee82
-		else
Ian Kent 36ee82
-			trailer--;
Ian Kent 36ee82
-
Ian Kent 36ee82
-		while (*trailer && (*trailer == '"' || isblank(*trailer)))
Ian Kent 36ee82
-			*(trailer--) = '\0';;
Ian Kent 36ee82
-
Ian Kent 36ee82
-		if (check_set_config_value(res, ENV_NAME_MASTER_MAP, value) ||
Ian Kent 36ee82
-		    check_set_config_value(res, ENV_NAME_TIMEOUT, value) ||
Ian Kent 36ee82
-		    check_set_config_value(res, ENV_NAME_BROWSE_MODE, value) ||
Ian Kent 36ee82
-		    check_set_config_value(res, ENV_NAME_LOGGING, value) ||
Ian Kent 36ee82
-		    check_set_config_value(res, ENV_LDAP_SERVER, value) ||
Ian Kent 36ee82
-		    check_set_config_value(res, ENV_NAME_MAP_OBJ_CLASS, value) ||
Ian Kent 36ee82
-		    check_set_config_value(res, ENV_NAME_ENTRY_OBJ_CLASS, value) ||
Ian Kent 36ee82
-		    check_set_config_value(res, ENV_NAME_MAP_ATTR, value) ||
Ian Kent 36ee82
-		    check_set_config_value(res, ENV_NAME_ENTRY_ATTR, value) ||
Ian Kent 36ee82
-		    check_set_config_value(res, ENV_NAME_VALUE_ATTR, value) ||
Ian Kent 36ee82
-		    check_set_config_value(res, ENV_APPEND_OPTIONS, value) ||
Ian Kent 36ee82
-		    check_set_config_value(res, ENV_AUTH_CONF_FILE, value))
Ian Kent 36ee82
+		if (check_set_config_value(key, ENV_NAME_MASTER_MAP, value) ||
Ian Kent 36ee82
+		    check_set_config_value(key, ENV_NAME_TIMEOUT, value) ||
Ian Kent 36ee82
+		    check_set_config_value(key, ENV_NAME_BROWSE_MODE, value) ||
Ian Kent 36ee82
+		    check_set_config_value(key, ENV_NAME_LOGGING, value) ||
Ian Kent 36ee82
+		    check_set_config_value(key, ENV_LDAP_SERVER, value) ||
Ian Kent 36ee82
+		    check_set_config_value(key, ENV_NAME_MAP_OBJ_CLASS, value) ||
Ian Kent 36ee82
+		    check_set_config_value(key, ENV_NAME_ENTRY_OBJ_CLASS, value) ||
Ian Kent 36ee82
+		    check_set_config_value(key, ENV_NAME_MAP_ATTR, value) ||
Ian Kent 36ee82
+		    check_set_config_value(key, ENV_NAME_ENTRY_ATTR, value) ||
Ian Kent 36ee82
+		    check_set_config_value(key, ENV_NAME_VALUE_ATTR, value) ||
Ian Kent 36ee82
+		    check_set_config_value(key, ENV_APPEND_OPTIONS, value) ||
Ian Kent 36ee82
+		    check_set_config_value(key, ENV_AUTH_CONF_FILE, value))
Ian Kent 36ee82
 			;
Ian Kent 36ee82
 	}
Ian Kent 36ee82
 
Ian Kent 36ee82
@@ -336,6 +353,86 @@ struct ldap_schema *defaults_get_default
Ian Kent 36ee82
 	return schema;
Ian Kent 36ee82
 }
Ian Kent 36ee82
 
Ian Kent 36ee82
+static struct ldap_searchdn *alloc_searchdn(const char *value)
Ian Kent 36ee82
+{
Ian Kent 36ee82
+	struct ldap_searchdn *sdn;
Ian Kent 36ee82
+	char *val;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	sdn = malloc(sizeof(struct ldap_searchdn));
Ian Kent 36ee82
+	if (!sdn)
Ian Kent 36ee82
+		return NULL;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	val = strdup(value);
Ian Kent 36ee82
+	if (!val) {
Ian Kent 36ee82
+		free(sdn);
Ian Kent 36ee82
+		return NULL;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	sdn->basedn = val;
Ian Kent 36ee82
+	sdn->next = NULL;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	return sdn;
Ian Kent 36ee82
+}
Ian Kent 36ee82
+
Ian Kent 36ee82
+void defaults_free_searchdns(struct ldap_searchdn *sdn)
Ian Kent 36ee82
+{
Ian Kent 36ee82
+	struct ldap_searchdn *this = sdn;
Ian Kent 36ee82
+	struct ldap_searchdn *next;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	next = this;
Ian Kent 36ee82
+	while (this) {
Ian Kent 36ee82
+		next = this->next;
Ian Kent 36ee82
+		free(this->basedn);
Ian Kent 36ee82
+		free(this);
Ian Kent 36ee82
+		this = next;
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	return;
Ian Kent 36ee82
+}
Ian Kent 36ee82
+
Ian Kent 36ee82
+struct ldap_searchdn *defaults_get_searchdns(void)
Ian Kent 36ee82
+{
Ian Kent 36ee82
+	FILE *f;
Ian Kent 36ee82
+	char buf[MAX_LINE_LEN];
Ian Kent 36ee82
+	char *res;
Ian Kent 36ee82
+	struct ldap_searchdn *sdn, *last;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	f = fopen(DEFAULTS_CONFIG_FILE, "r");
Ian Kent 36ee82
+	if (!f)
Ian Kent 36ee82
+		return NULL;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	sdn = last = NULL;
Ian Kent 36ee82
+
Ian Kent 36ee82
+	while ((res = fgets(buf, MAX_LINE_LEN, f))) {
Ian Kent 36ee82
+		char *key, *value;
Ian Kent 36ee82
+
Ian Kent 36ee82
+		if (!parse_line(res, &key, &value))
Ian Kent 36ee82
+			continue;
Ian Kent 36ee82
+
Ian Kent 36ee82
+		if (!strcasecmp(key, SEARCH_BASE)) {
Ian Kent 36ee82
+			struct ldap_searchdn *new = alloc_searchdn(value);
Ian Kent 36ee82
+
Ian Kent 36ee82
+			if (!new) {
Ian Kent 36ee82
+				defaults_free_searchdns(sdn);
Ian Kent 36ee82
+				return NULL;
Ian Kent 36ee82
+			}
Ian Kent 36ee82
+
Ian Kent 36ee82
+			if (!last)
Ian Kent 36ee82
+				last = new;
Ian Kent 36ee82
+			else {
Ian Kent 36ee82
+				last->next = new;
Ian Kent 36ee82
+				last = new;
Ian Kent 36ee82
+			}
Ian Kent 36ee82
+
Ian Kent 36ee82
+			if (!sdn)
Ian Kent 36ee82
+				sdn = new;
Ian Kent 36ee82
+		}
Ian Kent 36ee82
+	}
Ian Kent 36ee82
+
Ian Kent 36ee82
+	fclose(f);
Ian Kent 36ee82
+	return sdn;
Ian Kent 36ee82
+}
Ian Kent 36ee82
+
Ian Kent 36ee82
 struct ldap_schema *defaults_get_schema(void)
Ian Kent 36ee82
 {
Ian Kent 36ee82
 	struct ldap_schema *schema;
Ian Kent 36ee82
diff -up autofs-5.0.2/man/auto.master.5.in.ldap-search-basedn-list autofs-5.0.2/man/auto.master.5.in
Ian Kent 36ee82
--- autofs-5.0.2/man/auto.master.5.in.ldap-search-basedn-list	2007-11-20 14:07:52.000000000 +0900
Ian Kent 36ee82
+++ autofs-5.0.2/man/auto.master.5.in	2007-11-20 14:08:26.000000000 +0900
Ian Kent 36ee82
@@ -224,6 +224,11 @@ values must be set, any partial schema s
Ian Kent 36ee82
 .P
Ian Kent 36ee82
 The configuration settings available are:
Ian Kent 36ee82
 .TP
Ian Kent 36ee82
+.B SEARCH_BASE
Ian Kent 36ee82
+The base dn to use when searching for amap base dn. This entry may be
Ian Kent 36ee82
+given multiple times and each will be checked for a map base dn in
Ian Kent 36ee82
+the order they occur in the configuration.
Ian Kent 36ee82
+.TP
Ian Kent 36ee82
 .B MAP_OBJECT_CLASS
Ian Kent 36ee82
 The map object class. In the \fBnisMap\fP schema this corresponds to the class
Ian Kent 36ee82
 \fBnisMap\fP and in the \fBautomountMap\fP schema it corresponds to the class