- check for "*" when looking up wildcard in LDAP.
- fix couple of edge case parse fails of timeout option.
- add SEARCH_BASE configuration option.
- add random selection as a master map entry option.
- re-read config on HUP signal.
- add LDAP_URI, LDAP_TIMEOUT and LDAP_NETWORK_TIMEOUT configuration
options.
- fix deadlock in submount mount module.
- fix lack of ferror() checking when reading files.
- fix typo in autofs(5) man page.
- fix map entry expansion when undefined macro is present.
- remove unused export validation code.
- add dynamic logging (adapted from v4 patch from Jeff Moyer).
- fix recursive loopback mounts (Matthias Koenig).
- add map re-load to verbose logging.
- fix handling of LDAP base dns with spaces.
- handle MTAB_NOTUPDATED status return from mount.
- when default master map, auto.master, is used also check for auto_master.
- update negative mount timeout handling.
- fix large group handling (Ryan Thomas).
- fix for dynamic logging breaking non-sasl build (Guillaume Rousse).
- eliminate NULL proc ping for singleton host or local mounts.
817 lines
20 KiB
Diff
817 lines
20 KiB
Diff
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
|