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