- update source to version 5.0.3.
This commit is contained in:
parent
41a12c29f1
commit
4e3326018a
@ -1 +1 @@
|
|||||||
autofs-5.0.2.tar.bz2
|
autofs-5.0.3.tar.bz2
|
||||||
|
@ -1,122 +0,0 @@
|
|||||||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|
||||||
index 930b13f..70a3b9d 100644
|
|
||||||
--- a/daemon/automount.c
|
|
||||||
+++ b/daemon/automount.c
|
|
||||||
@@ -978,7 +978,7 @@ static void *do_read_master(void *arg)
|
|
||||||
if (status)
|
|
||||||
fatal(status);
|
|
||||||
|
|
||||||
- defaults_read_config();
|
|
||||||
+ defaults_read_config(1);
|
|
||||||
|
|
||||||
status = master_read_master(master, age, readall);
|
|
||||||
|
|
||||||
@@ -1465,7 +1465,7 @@ int main(int argc, char *argv[])
|
|
||||||
|
|
||||||
program = argv[0];
|
|
||||||
|
|
||||||
- defaults_read_config();
|
|
||||||
+ defaults_read_config(0);
|
|
||||||
|
|
||||||
kpkt_len = get_kpkt_len();
|
|
||||||
timeout = defaults_get_timeout();
|
|
||||||
diff --git a/include/defaults.h b/include/defaults.h
|
|
||||||
index 46393d9..0e0e2a5 100644
|
|
||||||
--- a/include/defaults.h
|
|
||||||
+++ b/include/defaults.h
|
|
||||||
@@ -41,7 +41,7 @@
|
|
||||||
struct ldap_schema;
|
|
||||||
struct ldap_searchdn;
|
|
||||||
|
|
||||||
-unsigned int defaults_read_config(void);
|
|
||||||
+unsigned int defaults_read_config(unsigned int);
|
|
||||||
const char *defaults_get_master_map(void);
|
|
||||||
unsigned int defaults_get_timeout(void);
|
|
||||||
unsigned int defaults_get_browse_mode(void);
|
|
||||||
diff --git a/lib/defaults.c b/lib/defaults.c
|
|
||||||
index bf1ceed..2cccf20 100644
|
|
||||||
--- a/lib/defaults.c
|
|
||||||
+++ b/lib/defaults.c
|
|
||||||
@@ -280,7 +280,7 @@ struct list_head *defaults_get_uris(void)
|
|
||||||
* is valid bourne shell script without spaces around "="
|
|
||||||
* and that it has valid values.
|
|
||||||
*/
|
|
||||||
-unsigned int defaults_read_config(void)
|
|
||||||
+unsigned int defaults_read_config(unsigned int to_syslog)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
char buf[MAX_LINE_LEN];
|
|
||||||
@@ -312,9 +312,16 @@ unsigned int defaults_read_config(void)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!feof(f)) {
|
|
||||||
- fprintf(stderr, "fgets returned error %d while reading %s\n",
|
|
||||||
- ferror(f), DEFAULTS_CONFIG_FILE);
|
|
||||||
+ if (!feof(f) || ferror(f)) {
|
|
||||||
+ if (!to_syslog) {
|
|
||||||
+ fprintf(stderr,
|
|
||||||
+ "fgets returned error %d while reading %s\n",
|
|
||||||
+ ferror(f), DEFAULTS_CONFIG_FILE);
|
|
||||||
+ } else {
|
|
||||||
+ error(LOGOPT_ANY,
|
|
||||||
+ "fgets returned error %d while reading %s",
|
|
||||||
+ ferror(f), DEFAULTS_CONFIG_FILE);
|
|
||||||
+ }
|
|
||||||
fclose(f);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
|
|
||||||
index 6346602..31ee0fb 100644
|
|
||||||
--- a/modules/lookup_file.c
|
|
||||||
+++ b/modules/lookup_file.c
|
|
||||||
@@ -442,6 +442,11 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
|
||||||
if (!entry) {
|
|
||||||
if (feof(f))
|
|
||||||
break;
|
|
||||||
+ if (ferror(f)) {
|
|
||||||
+ warn(LOGOPT_ANY, MODPREFIX
|
|
||||||
+ "error reading map %s", ctxt->mapname);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -683,6 +688,11 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
|
||||||
if (!entry) {
|
|
||||||
if (feof(f))
|
|
||||||
break;
|
|
||||||
+ if (ferror(f)) {
|
|
||||||
+ warn(LOGOPT_ANY, MODPREFIX
|
|
||||||
+ "error reading map %s", ctxt->mapname);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -848,6 +858,12 @@ static int lookup_one(struct autofs_point *ap,
|
|
||||||
|
|
||||||
if (feof(f))
|
|
||||||
break;
|
|
||||||
+
|
|
||||||
+ if (ferror(f)) {
|
|
||||||
+ warn(LOGOPT_ANY, MODPREFIX
|
|
||||||
+ "error reading map %s", ctxt->mapname);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
@@ -907,6 +923,12 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt)
|
|
||||||
|
|
||||||
if (feof(f))
|
|
||||||
break;
|
|
||||||
+
|
|
||||||
+ if (ferror(f)) {
|
|
||||||
+ warn(LOGOPT_ANY, MODPREFIX
|
|
||||||
+ "error reading map %s", ctxt->mapname);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
@ -1,12 +0,0 @@
|
|||||||
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
|
|
||||||
index e1c5b4e..0a9deca 100644
|
|
||||||
--- a/include/lookup_ldap.h
|
|
||||||
+++ b/include/lookup_ldap.h
|
|
||||||
@@ -7,6 +7,7 @@
|
|
||||||
#include <openssl/err.h>
|
|
||||||
#include <sasl/sasl.h>
|
|
||||||
#include <libxml/tree.h>
|
|
||||||
+#include <krb5.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct lookup_context {
|
|
@ -1,27 +0,0 @@
|
|||||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
|
||||||
index dfb3054..8719af9 100644
|
|
||||||
--- a/modules/lookup_ldap.c
|
|
||||||
+++ b/modules/lookup_ldap.c
|
|
||||||
@@ -193,10 +193,11 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt
|
|
||||||
LDAPMessage *result = NULL, *e;
|
|
||||||
struct ldap_searchdn *sdns = NULL;
|
|
||||||
char *attrs[2];
|
|
||||||
+ struct berval **value;
|
|
||||||
int scope;
|
|
||||||
int rv, l;
|
|
||||||
|
|
||||||
- attrs[0] = LDAP_NO_ATTRS;
|
|
||||||
+ attrs[0] = (char *) key;
|
|
||||||
attrs[1] = NULL;
|
|
||||||
|
|
||||||
if (!ctxt->mapname && !ctxt->base) {
|
|
||||||
@@ -283,7 +284,8 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt
|
|
||||||
}
|
|
||||||
|
|
||||||
e = ldap_first_entry(ldap, result);
|
|
||||||
- if (e) {
|
|
||||||
+ if (e && (value = ldap_get_values_len(ldap, e, key))) {
|
|
||||||
+ ldap_value_free_len(value);
|
|
||||||
dn = ldap_get_dn(ldap, e);
|
|
||||||
debug(logopt, MODPREFIX "found query dn %s", dn);
|
|
||||||
} else {
|
|
@ -1,653 +0,0 @@
|
|||||||
diff -up autofs-5.0.2/include/lookup_ldap.h.add-ldap-schema-discovery autofs-5.0.2/include/lookup_ldap.h
|
|
||||||
--- autofs-5.0.2/include/lookup_ldap.h.add-ldap-schema-discovery 2007-09-05 12:52:35.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/include/lookup_ldap.h 2007-09-05 12:52:35.000000000 +0800
|
|
||||||
@@ -10,6 +10,14 @@
|
|
||||||
#include <krb5.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+struct ldap_schema {
|
|
||||||
+ char *map_class;
|
|
||||||
+ char *map_attr;
|
|
||||||
+ char *entry_class;
|
|
||||||
+ char *entry_attr;
|
|
||||||
+ char *value_attr;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
struct lookup_context {
|
|
||||||
char *mapname;
|
|
||||||
|
|
||||||
@@ -22,11 +30,7 @@ struct lookup_context {
|
|
||||||
int version;
|
|
||||||
|
|
||||||
/* LDAP lookup configuration */
|
|
||||||
- char *map_obj_class;
|
|
||||||
- char *entry_obj_class;
|
|
||||||
- char *map_attr;
|
|
||||||
- char *entry_attr;
|
|
||||||
- char *value_attr;
|
|
||||||
+ struct ldap_schema *schema;
|
|
||||||
|
|
||||||
/* TLS and SASL authentication information */
|
|
||||||
char *auth_conf;
|
|
||||||
diff -up autofs-5.0.2/include/defaults.h.add-ldap-schema-discovery autofs-5.0.2/include/defaults.h
|
|
||||||
--- autofs-5.0.2/include/defaults.h.add-ldap-schema-discovery 2007-06-18 15:18:08.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/include/defaults.h 2007-09-05 12:52:35.000000000 +0800
|
|
||||||
@@ -43,11 +43,8 @@ unsigned int defaults_get_timeout(void);
|
|
||||||
unsigned int defaults_get_browse_mode(void);
|
|
||||||
unsigned int defaults_get_logging(void);
|
|
||||||
const char *defaults_get_ldap_server(void);
|
|
||||||
-const char *defaults_get_map_obj_class(void);
|
|
||||||
-const char *defaults_get_entry_obj_class(void);
|
|
||||||
-const char *defaults_get_map_attr(void);
|
|
||||||
-const char *defaults_get_entry_attr(void);
|
|
||||||
-const char *defaults_get_value_attr(void);
|
|
||||||
+struct ldap_schema *defaults_get_default_schema(void);
|
|
||||||
+struct ldap_schema *defaults_get_schema(void);
|
|
||||||
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.add-ldap-schema-discovery autofs-5.0.2/modules/lookup_ldap.c
|
|
||||||
--- autofs-5.0.2/modules/lookup_ldap.c.add-ldap-schema-discovery 2007-09-05 12:52:35.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/modules/lookup_ldap.c 2007-09-05 12:53:10.000000000 +0800
|
|
||||||
@@ -42,6 +42,13 @@
|
|
||||||
|
|
||||||
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
|
|
||||||
|
|
||||||
+static struct ldap_schema common_schema[] = {
|
|
||||||
+ {"nisMap", "nisMapName", "nisObject", "cn", "nisMapEntry"},
|
|
||||||
+ {"automountMap", "ou", "automount", "cn", "automountInformation"},
|
|
||||||
+ {"automountMap", "automountMapName", "automount", "automountKey", "automountInformation"},
|
|
||||||
+};
|
|
||||||
+static unsigned int common_schema_count = sizeof(common_schema)/sizeof(struct ldap_schema);
|
|
||||||
+
|
|
||||||
int bind_ldap_anonymous(LDAP *ldap, struct lookup_context *ctxt)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
@@ -738,54 +745,15 @@ done:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int get_default_schema(struct lookup_context *ctxt)
|
|
||||||
-{
|
|
||||||
- ctxt->map_obj_class = (char *) defaults_get_map_obj_class();
|
|
||||||
- if (!ctxt->map_obj_class)
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- ctxt->entry_obj_class = (char *) defaults_get_entry_obj_class();
|
|
||||||
- if (!ctxt->entry_obj_class)
|
|
||||||
- goto free_moc;
|
|
||||||
-
|
|
||||||
- ctxt->map_attr = (char *) defaults_get_map_attr();
|
|
||||||
- if (!ctxt->map_attr)
|
|
||||||
- goto free_eoc;
|
|
||||||
-
|
|
||||||
- ctxt->entry_attr = (char *) defaults_get_entry_attr();
|
|
||||||
- if (!ctxt->entry_attr)
|
|
||||||
- goto free_ma;
|
|
||||||
-
|
|
||||||
- ctxt->value_attr = (char *) defaults_get_value_attr();
|
|
||||||
- if (!ctxt->value_attr)
|
|
||||||
- goto free_ea;
|
|
||||||
-
|
|
||||||
- return 1;
|
|
||||||
-
|
|
||||||
-free_ea:
|
|
||||||
- free(ctxt->entry_attr);
|
|
||||||
-free_ma:
|
|
||||||
- free(ctxt->map_attr);
|
|
||||||
-free_eoc:
|
|
||||||
- free(ctxt->entry_obj_class);
|
|
||||||
-free_moc:
|
|
||||||
- free(ctxt->map_obj_class);
|
|
||||||
-
|
|
||||||
- ctxt->map_obj_class = NULL;
|
|
||||||
- ctxt->entry_obj_class = NULL;
|
|
||||||
- ctxt->map_attr = NULL;
|
|
||||||
- ctxt->entry_attr = NULL;
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static void free_context(struct lookup_context *ctxt)
|
|
||||||
{
|
|
||||||
- if (ctxt->map_obj_class) {
|
|
||||||
- free(ctxt->map_obj_class);
|
|
||||||
- free(ctxt->entry_obj_class);
|
|
||||||
- free(ctxt->map_attr);
|
|
||||||
- free(ctxt->entry_attr);
|
|
||||||
+ if (ctxt->schema) {
|
|
||||||
+ free(ctxt->schema->map_class);
|
|
||||||
+ free(ctxt->schema->map_attr);
|
|
||||||
+ free(ctxt->schema->entry_class);
|
|
||||||
+ free(ctxt->schema->entry_attr);
|
|
||||||
+ free(ctxt->schema->value_attr);
|
|
||||||
+ free(ctxt->schema);
|
|
||||||
}
|
|
||||||
if (ctxt->auth_conf)
|
|
||||||
free(ctxt->auth_conf);
|
|
||||||
@@ -808,19 +776,15 @@ static void free_context(struct lookup_c
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt)
|
|
||||||
+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 *class, *key;
|
|
||||||
char *attrs[2];
|
|
||||||
int scope;
|
|
||||||
int rv, l;
|
|
||||||
|
|
||||||
- class = ctxt->map_obj_class;
|
|
||||||
- key = ctxt->map_attr;
|
|
||||||
-
|
|
||||||
attrs[0] = LDAP_NO_ATTRS;
|
|
||||||
attrs[1] = NULL;
|
|
||||||
|
|
||||||
@@ -890,6 +854,90 @@ static int get_query_dn(LDAP *ldap, stru
|
|
||||||
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.
|
|
||||||
@@ -926,13 +974,6 @@ int lookup_init(const char *mapfmt, int
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* Get default schema for queries */
|
|
||||||
- if (!get_default_schema(ctxt)) {
|
|
||||||
- error(LOGOPT_ANY, MODPREFIX "cannot set default schema");
|
|
||||||
- free_context(ctxt);
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
#ifdef WITH_SASL
|
|
||||||
/*
|
|
||||||
* Determine which authentication mechanism to use. We sanity-
|
|
||||||
@@ -954,13 +995,31 @@ int lookup_init(const char *mapfmt, int
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = get_query_dn(ldap, ctxt);
|
|
||||||
- unbind_ldap_connection(ldap, ctxt);
|
|
||||||
- if (!ret) {
|
|
||||||
- error(LOGOPT_ANY, MODPREFIX "failed to get query dn");
|
|
||||||
- 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. */
|
|
||||||
ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
|
|
||||||
@@ -990,9 +1049,9 @@ int lookup_read_master(struct master *ma
|
|
||||||
int scope = LDAP_SCOPE_SUBTREE;
|
|
||||||
LDAP *ldap;
|
|
||||||
|
|
||||||
- class = ctxt->entry_obj_class;
|
|
||||||
- entry = ctxt->entry_attr;
|
|
||||||
- info = ctxt->value_attr;
|
|
||||||
+ class = ctxt->schema->entry_class;
|
|
||||||
+ entry = ctxt->schema->entry_attr;
|
|
||||||
+ info = ctxt->schema->value_attr;
|
|
||||||
|
|
||||||
attrs[0] = entry;
|
|
||||||
attrs[1] = info;
|
|
||||||
@@ -1141,9 +1200,9 @@ static int read_one_map(struct autofs_po
|
|
||||||
|
|
||||||
mc = source->mc;
|
|
||||||
|
|
||||||
- class = ctxt->entry_obj_class;
|
|
||||||
- entry = ctxt->entry_attr;
|
|
||||||
- info = ctxt->value_attr;
|
|
||||||
+ class = ctxt->schema->entry_class;
|
|
||||||
+ entry = ctxt->schema->entry_attr;
|
|
||||||
+ info = ctxt->schema->value_attr;
|
|
||||||
|
|
||||||
attrs[0] = entry;
|
|
||||||
attrs[1] = info;
|
|
||||||
@@ -1438,9 +1497,9 @@ static int lookup_one(struct autofs_poin
|
|
||||||
return CHE_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- class = ctxt->entry_obj_class;
|
|
||||||
- entry = ctxt->entry_attr;
|
|
||||||
- info = ctxt->value_attr;
|
|
||||||
+ class = ctxt->schema->entry_class;
|
|
||||||
+ entry = ctxt->schema->entry_attr;
|
|
||||||
+ info = ctxt->schema->value_attr;
|
|
||||||
|
|
||||||
attrs[0] = entry;
|
|
||||||
attrs[1] = info;
|
|
||||||
diff -up autofs-5.0.2/lib/defaults.c.add-ldap-schema-discovery autofs-5.0.2/lib/defaults.c
|
|
||||||
--- autofs-5.0.2/lib/defaults.c.add-ldap-schema-discovery 2007-06-18 15:18:08.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/lib/defaults.c 2007-09-05 12:52:35.000000000 +0800
|
|
||||||
@@ -18,6 +18,7 @@
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "defaults.h"
|
|
||||||
+#include "lookup_ldap.h"
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#define DEFAULTS_CONFIG_FILE AUTOFS_CONF_DIR "/autofs"
|
|
||||||
@@ -41,16 +42,8 @@
|
|
||||||
#define ENV_AUTH_CONF_FILE "AUTH_CONF_FILE"
|
|
||||||
|
|
||||||
static const char *default_master_map_name = DEFAULT_MASTER_MAP_NAME;
|
|
||||||
-
|
|
||||||
-static const char *default_ldap_server = DEFAULT_LDAP_SERVER;
|
|
||||||
-
|
|
||||||
-static const char *default_map_obj_class = DEFAULT_MAP_OBJ_CLASS;
|
|
||||||
-static const char *default_entry_obj_class = DEFAULT_ENTRY_OBJ_CLASS;
|
|
||||||
-static const char *default_map_attr = DEFAULT_MAP_ATTR;
|
|
||||||
-static const char *default_entry_attr = DEFAULT_ENTRY_ATTR;
|
|
||||||
-static const char *default_value_attr = DEFAULT_VALUE_ATTR;
|
|
||||||
-
|
|
||||||
-static const char *default_auth_conf_file = DEFAULT_AUTH_CONF_FILE;
|
|
||||||
+static const char *default_ldap_server = DEFAULT_LDAP_SERVER;
|
|
||||||
+static const char *default_auth_conf_file = DEFAULT_AUTH_CONF_FILE;
|
|
||||||
|
|
||||||
static char *get_env_string(const char *name)
|
|
||||||
{
|
|
||||||
@@ -285,59 +278,120 @@ const char *defaults_get_ldap_server(voi
|
|
||||||
return (const char *) server;
|
|
||||||
}
|
|
||||||
|
|
||||||
-const char *defaults_get_map_obj_class(void)
|
|
||||||
+struct ldap_schema *defaults_get_default_schema(void)
|
|
||||||
{
|
|
||||||
- char *moc;
|
|
||||||
+ struct ldap_schema *schema;
|
|
||||||
+ char *mc, *ma, *ec, *ea, *va;
|
|
||||||
|
|
||||||
- moc = get_env_string(ENV_NAME_MAP_OBJ_CLASS);
|
|
||||||
- if (!moc)
|
|
||||||
- return strdup(default_map_obj_class);
|
|
||||||
+ mc = strdup(DEFAULT_MAP_OBJ_CLASS);
|
|
||||||
+ if (!mc)
|
|
||||||
+ return NULL;
|
|
||||||
|
|
||||||
- return (const char *) moc;
|
|
||||||
-}
|
|
||||||
+ ma = strdup(DEFAULT_MAP_ATTR);
|
|
||||||
+ if (!ma) {
|
|
||||||
+ free(mc);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
-const char *defaults_get_entry_obj_class(void)
|
|
||||||
-{
|
|
||||||
- char *eoc;
|
|
||||||
+ ec = strdup(DEFAULT_ENTRY_OBJ_CLASS);
|
|
||||||
+ if (!ec) {
|
|
||||||
+ free(mc);
|
|
||||||
+ free(ma);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- eoc = get_env_string(ENV_NAME_ENTRY_OBJ_CLASS);
|
|
||||||
- if (!eoc)
|
|
||||||
- return strdup(default_entry_obj_class);
|
|
||||||
+ ea = strdup(DEFAULT_ENTRY_ATTR);
|
|
||||||
+ if (!ea) {
|
|
||||||
+ free(mc);
|
|
||||||
+ free(ma);
|
|
||||||
+ free(ec);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- return (const char *) eoc;
|
|
||||||
-}
|
|
||||||
+ va = strdup(DEFAULT_VALUE_ATTR);
|
|
||||||
+ if (!va) {
|
|
||||||
+ free(mc);
|
|
||||||
+ free(ma);
|
|
||||||
+ free(ec);
|
|
||||||
+ free(ea);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
-const char *defaults_get_map_attr(void)
|
|
||||||
-{
|
|
||||||
- char *ma;
|
|
||||||
+ schema = malloc(sizeof(struct ldap_schema));
|
|
||||||
+ if (!schema) {
|
|
||||||
+ free(mc);
|
|
||||||
+ free(ma);
|
|
||||||
+ free(ec);
|
|
||||||
+ free(ea);
|
|
||||||
+ free(va);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- ma = get_env_string(ENV_NAME_MAP_ATTR);
|
|
||||||
- if (!ma)
|
|
||||||
- return strdup(default_map_attr);
|
|
||||||
+ schema->map_class = mc;
|
|
||||||
+ schema->map_attr = ma;
|
|
||||||
+ schema->entry_class = ec;
|
|
||||||
+ schema->entry_attr = ea;
|
|
||||||
+ schema->value_attr = va;
|
|
||||||
|
|
||||||
- return (const char *) ma;
|
|
||||||
+ return schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
-const char *defaults_get_entry_attr(void)
|
|
||||||
+struct ldap_schema *defaults_get_schema(void)
|
|
||||||
{
|
|
||||||
- char *ea;
|
|
||||||
+ struct ldap_schema *schema;
|
|
||||||
+ char *mc, *ma, *ec, *ea, *va;
|
|
||||||
|
|
||||||
- ea = get_env_string(ENV_NAME_ENTRY_ATTR);
|
|
||||||
- if (!ea)
|
|
||||||
- return strdup(default_entry_attr);
|
|
||||||
+ mc = get_env_string(ENV_NAME_MAP_OBJ_CLASS);
|
|
||||||
+ if (!mc)
|
|
||||||
+ return NULL;
|
|
||||||
|
|
||||||
- return (const char *) ea;
|
|
||||||
-}
|
|
||||||
+ ma = get_env_string(ENV_NAME_MAP_ATTR);
|
|
||||||
+ if (!ma) {
|
|
||||||
+ free(mc);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
-const char *defaults_get_value_attr(void)
|
|
||||||
-{
|
|
||||||
- char *va;
|
|
||||||
+ ec = get_env_string(ENV_NAME_ENTRY_OBJ_CLASS);
|
|
||||||
+ if (!ec) {
|
|
||||||
+ free(mc);
|
|
||||||
+ free(ma);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ea = get_env_string(ENV_NAME_ENTRY_ATTR);
|
|
||||||
+ if (!ea) {
|
|
||||||
+ free(mc);
|
|
||||||
+ free(ma);
|
|
||||||
+ free(ec);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
va = get_env_string(ENV_NAME_VALUE_ATTR);
|
|
||||||
- if (!va)
|
|
||||||
- return strdup(default_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 (const char *) va;
|
|
||||||
+ return schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int defaults_get_append_options(void)
|
|
||||||
diff -up autofs-5.0.2/man/auto.master.5.in.add-ldap-schema-discovery autofs-5.0.2/man/auto.master.5.in
|
|
||||||
--- autofs-5.0.2/man/auto.master.5.in.add-ldap-schema-discovery 2007-09-05 12:52:35.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/man/auto.master.5.in 2007-09-05 12:52:35.000000000 +0800
|
|
||||||
@@ -191,17 +191,25 @@ The old style
|
|
||||||
is also understood. Alternatively, the type can be obtained from the Name Service Switch
|
|
||||||
configuration, in which case the map name alone must be given.
|
|
||||||
.P
|
|
||||||
-The default LDAP schema is the NIS schema described in RFC 2307.
|
|
||||||
-Entries in the nisMap schema are \fBnisObject\fP objects in
|
|
||||||
+If no schema is set in the autofs configuration then autofs will check
|
|
||||||
+each of the commonly used schema for a valid entry and if one is found
|
|
||||||
+it will used for subsequent lookups.
|
|
||||||
+.P
|
|
||||||
+There are three common schemas in use:
|
|
||||||
+.TP
|
|
||||||
+.I nisMap
|
|
||||||
+Entries in the \fBnisMap\fP schema are \fBnisObject\fP objects in
|
|
||||||
the specified subtree, where the \fBcn\fP attribute is the key
|
|
||||||
(the wildcard key is "/"), and the \fBnisMapEntry\fP attribute
|
|
||||||
contains the information used by the automounter.
|
|
||||||
-.P
|
|
||||||
-Entries in the automountMap schema are \fBautomount\fP objects in
|
|
||||||
-the specified subtree, where the \fBcn\fP or \fBautomountKey\fP attribute
|
|
||||||
-(depending on local usage) is the key (the wildcard key is "/"), and the
|
|
||||||
-\fBautomountInformation\fP attribute contains the information used by the
|
|
||||||
-automounter.
|
|
||||||
+.TP
|
|
||||||
+.I automountMap
|
|
||||||
+The \fBautomountMap\fP schema has two variations that differ in the attribute
|
|
||||||
+used for the map key. Entries in the automountMap schema are \fBautomount\fP
|
|
||||||
+objects in the specified subtree, where the \fBcn\fP or \fBautomountKey\fP
|
|
||||||
+attribute (depending on local usage) is the key (the wildcard key is "/"),
|
|
||||||
+and the \fBautomountInformation\fP attribute contains the information used
|
|
||||||
+by the automounter. Note that the \fBcn\fP attribute is case insensitive.
|
|
||||||
.P
|
|
||||||
The object classes and attributes used for accessing automount maps in
|
|
||||||
LDAP can be changed by setting entries in the autofs configuration
|
|
||||||
@@ -209,61 +217,44 @@ located in
|
|
||||||
.nh
|
|
||||||
.BR @@autofsconfdir@@/autofs .
|
|
||||||
.hy
|
|
||||||
+.TP
|
|
||||||
+.B NOTE:
|
|
||||||
+If a schema is given in the configuration then all the schema configuration
|
|
||||||
+values must be set, any partial schema specification will be ignored.
|
|
||||||
.P
|
|
||||||
The configuration settings available are:
|
|
||||||
.TP
|
|
||||||
-\fBMAP_OBJECT_CLASS\fP
|
|
||||||
-The map object class. Its Default value is "nisMap". In the
|
|
||||||
-.nh
|
|
||||||
-automountMap
|
|
||||||
-.hy
|
|
||||||
-schema this corresponds to the class
|
|
||||||
-.nh
|
|
||||||
-.BR automountMap .
|
|
||||||
-.hy
|
|
||||||
+.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
|
|
||||||
+\fBautomountMap\fP.
|
|
||||||
.TP
|
|
||||||
.B ENTRY_OBJECT_CLASS
|
|
||||||
-The map entry object class. Its default value is \fBnisObject\fP.
|
|
||||||
-In the automountMap schema this corresponds to the class
|
|
||||||
-.nh
|
|
||||||
-.BR automount .
|
|
||||||
-.hy
|
|
||||||
+The map entry object class. In the \fBnisMap\fP schema this corresponds
|
|
||||||
+to the class \fBnisObject\fP and in the \fBautomountMap\fP schema it
|
|
||||||
+corresponds to the class \fBautomount\fP.
|
|
||||||
.TP
|
|
||||||
.B MAP_ATTRIBUTE
|
|
||||||
The attribute used to identify the name of the map to which this
|
|
||||||
-entry belongs. Its default value is
|
|
||||||
-.nh
|
|
||||||
-.BR nisMapName .
|
|
||||||
-.hy
|
|
||||||
-In the
|
|
||||||
-.nh
|
|
||||||
-automountMap
|
|
||||||
-.hy
|
|
||||||
-schema this corresponds to the attributes \fBou\fP or
|
|
||||||
-.nh
|
|
||||||
-.BR automountMapName .
|
|
||||||
-.hy
|
|
||||||
+entry belongs. In the \fBnisMap\fP schema this corresponds to the attribute
|
|
||||||
+\fBnisMapName\fP and in the \fBautomountMap\fP schema it corresponds to the
|
|
||||||
+attribute \fBou\fP or \fBautomountMapName\fP.
|
|
||||||
.TP
|
|
||||||
.B ENTRY_ATTRIBUTE
|
|
||||||
-The attribute used to identify a map key. Its default value is
|
|
||||||
-In the
|
|
||||||
-.nh
|
|
||||||
-automountMap
|
|
||||||
-.hy
|
|
||||||
-schema this corresponds to the attribute
|
|
||||||
-.nh
|
|
||||||
-.BR automountKey .
|
|
||||||
-.hy
|
|
||||||
+The attribute used to identify a map key. In the \fBnisMap\fP schema this
|
|
||||||
+corresponds to the attribute \fBcn\fP and in the \fBautomountMap\fP schema
|
|
||||||
+it corresponds to the attribute \fBautomountKey\fP.
|
|
||||||
.TP
|
|
||||||
.B VALUE_ATTRIBUTE
|
|
||||||
-The attribute used to identify the value of the map entry. Its default
|
|
||||||
-value is
|
|
||||||
-.nh
|
|
||||||
-.BR BnisMapEntry .
|
|
||||||
-.hy
|
|
||||||
-In the automountMap schema this corresponds to the attribute
|
|
||||||
-.nh
|
|
||||||
-.BR automountInformation .
|
|
||||||
+The attribute used to identify the value of the map entry. In the \fBnisMap\fP
|
|
||||||
+schema this corresponds to the attribute \fBnisMapEntry\fP and in the \fBautomountMap\fP
|
|
||||||
+schema it corresponds to the attribute \fBautomountInformation\fP.
|
|
||||||
+.TP
|
|
||||||
+.B NOTE:
|
|
||||||
+It is essential that entries use class and attribute in a consistent
|
|
||||||
+manner for correct operation of autofs. For example mixing \fBcn\fP and
|
|
||||||
+\fBautomountKey\fP attributes in \fBautomount\fP schema map entries won't
|
|
||||||
+work as expected.
|
|
||||||
.SH LDAP AUTHENTICATION, ENCRYPTED AND CERTIFIED CONNECTIONS
|
|
||||||
LDAP authenticated binds, TLS encrypted connections and certification
|
|
||||||
may be used by setting appropriate values in the autofs authentication
|
|
||||||
diff -up autofs-5.0.2/man/automount.8.add-ldap-schema-discovery autofs-5.0.2/man/automount.8
|
|
||||||
--- autofs-5.0.2/man/automount.8.add-ldap-schema-discovery 2007-09-05 12:52:35.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/man/automount.8 2007-09-05 12:52:35.000000000 +0800
|
|
||||||
@@ -102,6 +102,8 @@ started they will be recoverd unless the
|
|
||||||
the map in which case they need to umounted manually.
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
.BR autofs (5),
|
|
||||||
+.BR autofs (8),
|
|
||||||
+.BR auto.master (5),
|
|
||||||
.BR mount (8).
|
|
||||||
.SH BUGS
|
|
||||||
Don't know, I've fixed everything I know about.
|
|
@ -1,531 +0,0 @@
|
|||||||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
|
||||||
index 06fcecc..70b9e02 100644
|
|
||||||
--- a/daemon/lookup.c
|
|
||||||
+++ b/daemon/lookup.c
|
|
||||||
@@ -456,8 +456,12 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time
|
|
||||||
}
|
|
||||||
|
|
||||||
if (map->type) {
|
|
||||||
- debug(ap->logopt,
|
|
||||||
- "reading map %s %s", map->type, map->argv[0]);
|
|
||||||
+ if (!strncmp(map->type, "multi", 5))
|
|
||||||
+ debug(ap->logopt, "reading multi map");
|
|
||||||
+ else
|
|
||||||
+ debug(ap->logopt,
|
|
||||||
+ "reading map %s %s",
|
|
||||||
+ map->type, map->argv[0]);
|
|
||||||
result = do_read_map(ap, map, age);
|
|
||||||
map = map->next;
|
|
||||||
continue;
|
|
||||||
diff --git a/include/automount.h b/include/automount.h
|
|
||||||
index 85e6e9c..106ed0a 100644
|
|
||||||
--- a/include/automount.h
|
|
||||||
+++ b/include/automount.h
|
|
||||||
@@ -192,6 +192,7 @@ char *cache_get_offset(const char *prefix, char *offset, int start, struct list_
|
|
||||||
/* Utility functions */
|
|
||||||
|
|
||||||
char **add_argv(int argc, char **argv, char *str);
|
|
||||||
+char **append_argv(int argc1, char **argv1, int argc2, char **argv2);
|
|
||||||
const char **copy_argv(int argc, const char **argv);
|
|
||||||
int compare_argv(int argc1, const char **argv1, int argc2, const char **argv2);
|
|
||||||
int free_argv(int argc, const char **argv);
|
|
||||||
diff --git a/lib/args.c b/lib/args.c
|
|
||||||
index 9e35388..fbfb004 100644
|
|
||||||
--- a/lib/args.c
|
|
||||||
+++ b/lib/args.c
|
|
||||||
@@ -62,6 +62,45 @@ char **add_argv(int argc, char **argv, char *str)
|
|
||||||
return vector;
|
|
||||||
}
|
|
||||||
|
|
||||||
+char **append_argv(int argc1, char **argv1, int argc2, char **argv2)
|
|
||||||
+{
|
|
||||||
+ char **vector;
|
|
||||||
+ size_t vector_size;
|
|
||||||
+ int len, i, j;
|
|
||||||
+
|
|
||||||
+ len = argc1 + argc2;
|
|
||||||
+ vector_size = (len + 1) * sizeof(char *);
|
|
||||||
+ vector = (char **) realloc(argv1, vector_size);
|
|
||||||
+ if (!vector) {
|
|
||||||
+ free_argv(argc1, (const char **) argv1);
|
|
||||||
+ free_argv(argc2, (const char **) argv2);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (i = argc1, j = 0; i <= len; i++, j++) {
|
|
||||||
+ if (argv2[j]) {
|
|
||||||
+ vector[i] = strdup(argv2[j]);
|
|
||||||
+ if (!vector[i]) {
|
|
||||||
+ error(LOGOPT_ANY, "failed to strdup arg");
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ } else
|
|
||||||
+ vector[i] = NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (i < len) {
|
|
||||||
+ free_argv(len, (const char **) vector);
|
|
||||||
+ free_argv(argc2, (const char **) argv2);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ vector[len] = NULL;
|
|
||||||
+
|
|
||||||
+ free_argv(argc2, (const char **) argv2);
|
|
||||||
+
|
|
||||||
+ return vector;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
const char **copy_argv(int argc, const char **argv)
|
|
||||||
{
|
|
||||||
char **vector;
|
|
||||||
diff --git a/lib/master_parse.y b/lib/master_parse.y
|
|
||||||
index 8d2be02..f9cba05 100644
|
|
||||||
--- a/lib/master_parse.y
|
|
||||||
+++ b/lib/master_parse.y
|
|
||||||
@@ -22,6 +22,7 @@
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
+#include <ctype.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
|
|
||||||
#include "automount.h"
|
|
||||||
@@ -44,6 +45,7 @@ extern void master_set_scan_buffer(const char *);
|
|
||||||
static char *master_strdup(char *);
|
|
||||||
static void local_init_vars(void);
|
|
||||||
static void local_free_vars(void);
|
|
||||||
+static int add_multi_mapstr(void);
|
|
||||||
|
|
||||||
static int master_error(const char *s);
|
|
||||||
static int master_notify(const char *s);
|
|
||||||
@@ -53,6 +55,8 @@ static char *type;
|
|
||||||
static char *format;
|
|
||||||
static long timeout;
|
|
||||||
static unsigned ghost;
|
|
||||||
+static char **tmp_argv;
|
|
||||||
+static int tmp_argc;
|
|
||||||
static char **local_argv;
|
|
||||||
static int local_argc;
|
|
||||||
|
|
||||||
@@ -89,7 +93,7 @@ static int master_fprintf(FILE *, char *, ...);
|
|
||||||
%token COMMENT
|
|
||||||
%token MAP
|
|
||||||
%token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG
|
|
||||||
-%token COLON COMMA NL
|
|
||||||
+%token COLON COMMA NL DDASH
|
|
||||||
%type <strtype> map
|
|
||||||
%type <strtype> options
|
|
||||||
%type <strtype> dn
|
|
||||||
@@ -103,6 +107,7 @@ static int master_fprintf(FILE *, char *, ...);
|
|
||||||
%token <strtype> NILL
|
|
||||||
%token <strtype> SPACE
|
|
||||||
%token <strtype> EQUAL
|
|
||||||
+%token <strtype> MULTITYPE
|
|
||||||
%token <strtype> MAPTYPE
|
|
||||||
%token <strtype> DNSERVER
|
|
||||||
%token <strtype> DNATTR
|
|
||||||
@@ -126,7 +131,7 @@ file: {
|
|
||||||
;
|
|
||||||
|
|
||||||
line:
|
|
||||||
- | PATH map
|
|
||||||
+ | PATH mapspec
|
|
||||||
{
|
|
||||||
path = master_strdup($1);
|
|
||||||
if (!path) {
|
|
||||||
@@ -134,14 +139,49 @@ line:
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- | PATH map options
|
|
||||||
+ | PATH MULTITYPE maplist
|
|
||||||
{
|
|
||||||
+ char *tmp;
|
|
||||||
+
|
|
||||||
+ tmp = strchr($2, ':');
|
|
||||||
+ if (tmp)
|
|
||||||
+ *tmp = '\0';
|
|
||||||
+ else {
|
|
||||||
+ int len = strlen($2);
|
|
||||||
+ while (len-- && isblank($2[len]))
|
|
||||||
+ $2[len] = '\0';
|
|
||||||
+ if (len < 4) {
|
|
||||||
+ master_notify($2);
|
|
||||||
+ local_free_vars();
|
|
||||||
+ YYABORT;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
path = master_strdup($1);
|
|
||||||
if (!path) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
- }
|
|
||||||
+
|
|
||||||
+ if ((tmp = strchr($2, ',')))
|
|
||||||
+ *tmp++ = '\0';
|
|
||||||
+
|
|
||||||
+ type = master_strdup($2);
|
|
||||||
+ if (!type) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
+ local_free_vars();
|
|
||||||
+ YYABORT;
|
|
||||||
+ }
|
|
||||||
+ if (tmp) {
|
|
||||||
+ format = master_strdup(tmp);
|
|
||||||
+ if (!format) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
+ local_free_vars();
|
|
||||||
+ YYABORT;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
| PATH COLON { master_notify($1); YYABORT; }
|
|
||||||
| PATH OPTION { master_notify($2); YYABORT; }
|
|
||||||
| PATH NILL { master_notify($2); YYABORT; }
|
|
||||||
@@ -157,25 +197,89 @@ line:
|
|
||||||
| COMMENT { YYABORT; }
|
|
||||||
;
|
|
||||||
|
|
||||||
-map: PATH
|
|
||||||
+mapspec: map
|
|
||||||
+ {
|
|
||||||
+ local_argc = tmp_argc;
|
|
||||||
+ local_argv = tmp_argv;
|
|
||||||
+ tmp_argc = 0;
|
|
||||||
+ tmp_argv = NULL;
|
|
||||||
+ }
|
|
||||||
+ | map options
|
|
||||||
+ {
|
|
||||||
+ local_argc = tmp_argc;
|
|
||||||
+ local_argv = tmp_argv;
|
|
||||||
+ tmp_argc = 0;
|
|
||||||
+ tmp_argv = NULL;
|
|
||||||
+ }
|
|
||||||
+ ;
|
|
||||||
+
|
|
||||||
+maplist: map
|
|
||||||
+ {
|
|
||||||
+ if (!add_multi_mapstr()) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
+ local_free_vars();
|
|
||||||
+ YYABORT;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ | map options
|
|
||||||
+ {
|
|
||||||
+ if (!add_multi_mapstr()) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
+ local_free_vars();
|
|
||||||
+ YYABORT;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ | maplist DDASH map
|
|
||||||
{
|
|
||||||
local_argc++;
|
|
||||||
- local_argv = add_argv(local_argc, local_argv, $1);
|
|
||||||
+ local_argv = add_argv(local_argc, local_argv, "--");
|
|
||||||
if (!local_argv) {
|
|
||||||
master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
+ if (!add_multi_mapstr()) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
+ local_free_vars();
|
|
||||||
+ YYABORT;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
- | MAPNAME
|
|
||||||
+ | maplist DDASH map options
|
|
||||||
{
|
|
||||||
local_argc++;
|
|
||||||
- local_argv = add_argv(local_argc, local_argv, $1);
|
|
||||||
+ local_argv = add_argv(local_argc, local_argv, "--");
|
|
||||||
if (!local_argv) {
|
|
||||||
master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
+ if (!add_multi_mapstr()) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
+ local_free_vars();
|
|
||||||
+ YYABORT;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ ;
|
|
||||||
+
|
|
||||||
+map: PATH
|
|
||||||
+ {
|
|
||||||
+ tmp_argc++;
|
|
||||||
+ tmp_argv = add_argv(tmp_argc, tmp_argv, $1);
|
|
||||||
+ if (!tmp_argv) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
+ local_free_vars();
|
|
||||||
+ YYABORT;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ | MAPNAME
|
|
||||||
+ {
|
|
||||||
+ tmp_argc++;
|
|
||||||
+ tmp_argv = add_argv(tmp_argc, tmp_argv, $1);
|
|
||||||
+ if (!tmp_argv) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
+ local_free_vars();
|
|
||||||
+ YYABORT;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
| MAPHOSTS
|
|
||||||
{
|
|
||||||
@@ -200,9 +304,9 @@ map: PATH
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
- local_argc++;
|
|
||||||
- local_argv = add_argv(local_argc, local_argv, $1);
|
|
||||||
- if (!local_argv) {
|
|
||||||
+ tmp_argc++;
|
|
||||||
+ tmp_argv = add_argv(tmp_argc, tmp_argv, $1);
|
|
||||||
+ if (!tmp_argv) {
|
|
||||||
master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
@@ -227,9 +331,9 @@ map: PATH
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- local_argc++;
|
|
||||||
- local_argv = add_argv(local_argc, local_argv, $3);
|
|
||||||
- if (!local_argv) {
|
|
||||||
+ tmp_argc++;
|
|
||||||
+ tmp_argv = add_argv(tmp_argc, tmp_argv, $3);
|
|
||||||
+ if (!tmp_argv) {
|
|
||||||
master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
@@ -254,9 +358,9 @@ map: PATH
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- local_argc++;
|
|
||||||
- local_argv = add_argv(local_argc, local_argv, $3);
|
|
||||||
- if (!local_argv) {
|
|
||||||
+ tmp_argc++;
|
|
||||||
+ tmp_argv = add_argv(tmp_argc, tmp_argv, $3);
|
|
||||||
+ if (!tmp_argv) {
|
|
||||||
master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
@@ -281,25 +385,25 @@ map: PATH
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- local_argc++;
|
|
||||||
- local_argv = add_argv(local_argc, local_argv, $3);
|
|
||||||
- if (!local_argv) {
|
|
||||||
+ tmp_argc++;
|
|
||||||
+ tmp_argv = add_argv(tmp_argc, tmp_argv, $3);
|
|
||||||
+ if (!tmp_argv) {
|
|
||||||
master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
/* Add back the type for lookup_ldap.c to handle ldaps */
|
|
||||||
- if (*local_argv[0]) {
|
|
||||||
- tmp = malloc(strlen(type) + strlen(local_argv[0]) + 2);
|
|
||||||
+ if (*tmp_argv[0]) {
|
|
||||||
+ tmp = malloc(strlen(type) + strlen(tmp_argv[0]) + 2);
|
|
||||||
if (!tmp) {
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
strcpy(tmp, type);
|
|
||||||
strcat(tmp, ":");
|
|
||||||
- strcat(tmp, local_argv[0]);
|
|
||||||
- free(local_argv[0]);
|
|
||||||
- local_argv[0] = tmp;
|
|
||||||
+ strcat(tmp, tmp_argv[0]);
|
|
||||||
+ free(tmp_argv[0]);
|
|
||||||
+ tmp_argv[0] = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
;
|
|
||||||
@@ -441,9 +545,9 @@ daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; }
|
|
||||||
|
|
||||||
mount_option: OPTION
|
|
||||||
{
|
|
||||||
- local_argc++;
|
|
||||||
- local_argv = add_argv(local_argc, local_argv, $1);
|
|
||||||
- if (!local_argv) {
|
|
||||||
+ tmp_argc++;
|
|
||||||
+ tmp_argv = add_argv(tmp_argc, tmp_argv, $1);
|
|
||||||
+ if (!tmp_argv) {
|
|
||||||
master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
@@ -494,6 +598,8 @@ static void local_init_vars(void)
|
|
||||||
debug = 0;
|
|
||||||
timeout = -1;
|
|
||||||
ghost = defaults_get_browse_mode();
|
|
||||||
+ tmp_argv = NULL;
|
|
||||||
+ tmp_argc = 0;
|
|
||||||
local_argv = NULL;
|
|
||||||
local_argc = 0;
|
|
||||||
}
|
|
||||||
@@ -509,8 +615,62 @@ static void local_free_vars(void)
|
|
||||||
if (format)
|
|
||||||
free(format);
|
|
||||||
|
|
||||||
- if (local_argv)
|
|
||||||
+ if (local_argv) {
|
|
||||||
free_argv(local_argc, (const char **) local_argv);
|
|
||||||
+ local_argv = NULL;
|
|
||||||
+ local_argc = 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (tmp_argv) {
|
|
||||||
+ free_argv(tmp_argc, (const char **) tmp_argv);
|
|
||||||
+ tmp_argv = NULL;
|
|
||||||
+ tmp_argc = 0;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int add_multi_mapstr(void)
|
|
||||||
+{
|
|
||||||
+ /* We need the individual map types for a multi map */
|
|
||||||
+ if (!type) {
|
|
||||||
+ if (tmp_argc > 0 && *tmp_argv[0] == '/')
|
|
||||||
+ type = strdup("file");
|
|
||||||
+ else
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (format) {
|
|
||||||
+ char *tmp = realloc(type, strlen(type) + strlen(format) + 2);
|
|
||||||
+ if (!tmp)
|
|
||||||
+ return 0;
|
|
||||||
+ type = tmp;
|
|
||||||
+ strcat(type, ",");
|
|
||||||
+ strcat(type, format);
|
|
||||||
+ free(format);
|
|
||||||
+ format = NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ local_argc++;
|
|
||||||
+ local_argv = add_argv(local_argc, local_argv, type);
|
|
||||||
+ if (!local_argv) {
|
|
||||||
+ free(type);
|
|
||||||
+ type = NULL;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ local_argv = append_argv(local_argc, local_argv, tmp_argc, tmp_argv);
|
|
||||||
+ if (!local_argv) {
|
|
||||||
+ free(type);
|
|
||||||
+ type = NULL;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ local_argc += tmp_argc;
|
|
||||||
+
|
|
||||||
+ tmp_argc = 0;
|
|
||||||
+ tmp_argv = NULL;
|
|
||||||
+ free(type);
|
|
||||||
+ type = NULL;
|
|
||||||
+
|
|
||||||
+ return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void master_init_scan(void)
|
|
||||||
diff --git a/lib/master_tok.l b/lib/master_tok.l
|
|
||||||
index ee2a4eb..0548de1 100644
|
|
||||||
--- a/lib/master_tok.l
|
|
||||||
+++ b/lib/master_tok.l
|
|
||||||
@@ -27,6 +27,7 @@ static void master_echo(void); /* forward definition */
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
+#include <ctype.h>
|
|
||||||
#include "master_parse.tab.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -110,7 +111,9 @@ DNATTRSTR {AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}
|
|
||||||
DNNAMESTR ([[:alnum:]_.\-]+)
|
|
||||||
|
|
||||||
INTMAP (-hosts|-null)
|
|
||||||
-MTYPE ((file|program|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?)
|
|
||||||
+MULTI ((multi)(,(sun|hesiod))?[\:]?{OPTWS})
|
|
||||||
+MULTISEP ([\-]{2}[[:blank:]]+)
|
|
||||||
+MTYPE ((file|program|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?)
|
|
||||||
|
|
||||||
|
|
||||||
OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
|
|
||||||
@@ -184,11 +187,18 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
|
|
||||||
<MAPSTR>{
|
|
||||||
{OPTWS}\\\n{OPTWS} {}
|
|
||||||
|
|
||||||
+ {MULTI} {
|
|
||||||
+ strcpy(master_lval.strtype, master_text);
|
|
||||||
+ return(MULTITYPE);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
{MTYPE}/":" {
|
|
||||||
strcpy(master_lval.strtype, master_text);
|
|
||||||
return(MAPTYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ {MULTISEP} { return(DDASH); }
|
|
||||||
+
|
|
||||||
":" { return(COLON); }
|
|
||||||
|
|
||||||
"-hosts" {
|
|
||||||
@@ -298,6 +308,11 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
|
|
||||||
<OPTSTR>{
|
|
||||||
{OPTWS}\\\n{OPTWS} {}
|
|
||||||
|
|
||||||
+ {MULTISEP} {
|
|
||||||
+ BEGIN(MAPSTR);
|
|
||||||
+ return(DDASH);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
{OPTTOUT} { return(OPT_TIMEOUT); }
|
|
||||||
|
|
||||||
{NUMBER} {
|
|
||||||
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
|
|
||||||
index 00ab28e..38ca36c 100644
|
|
||||||
--- a/modules/lookup_multi.c
|
|
||||||
+++ b/modules/lookup_multi.c
|
|
||||||
@@ -45,7 +45,7 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void *
|
|
||||||
struct lookup_context *ctxt;
|
|
||||||
char buf[MAX_ERR_BUF];
|
|
||||||
char *map, *mapfmt;
|
|
||||||
- int i, j, an;
|
|
||||||
+ int i, an;
|
|
||||||
char *estr;
|
|
||||||
|
|
||||||
ctxt = malloc(sizeof(struct lookup_context));
|
|
||||||
@@ -73,7 +73,7 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void *
|
|
||||||
|
|
||||||
memcpy(ctxt->argl, argv, (argc + 1) * sizeof(const char *));
|
|
||||||
|
|
||||||
- for (i = j = an = 0; ctxt->argl[an]; an++) {
|
|
||||||
+ for (i = an = 0; ctxt->argl[an]; an++) {
|
|
||||||
if (ctxt->m[i].argc == 0) {
|
|
||||||
ctxt->m[i].argv = &ctxt->argl[an];
|
|
||||||
}
|
|
||||||
@@ -100,9 +100,12 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void *
|
|
||||||
if (!(ctxt->m[i].mod = open_lookup(map, MODPREFIX,
|
|
||||||
mapfmt ? mapfmt : my_mapfmt,
|
|
||||||
ctxt->m[i].argc - 1,
|
|
||||||
- ctxt->m[i].argv + 1)))
|
|
||||||
+ ctxt->m[i].argv + 1))) {
|
|
||||||
error(LOGOPT_ANY, MODPREFIX "error opening module");
|
|
||||||
+ free(map);
|
|
||||||
goto error_out;
|
|
||||||
+ }
|
|
||||||
+ free(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
*context = ctxt;
|
|
@ -1,473 +0,0 @@
|
|||||||
diff --git a/lib/master_parse.y b/lib/master_parse.y
|
|
||||||
index f9cba05..ab2895d 100644
|
|
||||||
--- a/lib/master_parse.y
|
|
||||||
+++ b/lib/master_parse.y
|
|
||||||
@@ -45,6 +45,7 @@ extern void master_set_scan_buffer(const char *);
|
|
||||||
static char *master_strdup(char *);
|
|
||||||
static void local_init_vars(void);
|
|
||||||
static void local_free_vars(void);
|
|
||||||
+static void trim_maptype(char *);
|
|
||||||
static int add_multi_mapstr(void);
|
|
||||||
|
|
||||||
static int master_error(const char *s);
|
|
||||||
@@ -141,21 +142,9 @@ line:
|
|
||||||
}
|
|
||||||
| PATH MULTITYPE maplist
|
|
||||||
{
|
|
||||||
- char *tmp;
|
|
||||||
-
|
|
||||||
- tmp = strchr($2, ':');
|
|
||||||
- if (tmp)
|
|
||||||
- *tmp = '\0';
|
|
||||||
- else {
|
|
||||||
- int len = strlen($2);
|
|
||||||
- while (len-- && isblank($2[len]))
|
|
||||||
- $2[len] = '\0';
|
|
||||||
- if (len < 4) {
|
|
||||||
- master_notify($2);
|
|
||||||
- local_free_vars();
|
|
||||||
- YYABORT;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ char *tmp = NULL;
|
|
||||||
+
|
|
||||||
+ trim_maptype($2);
|
|
||||||
|
|
||||||
path = master_strdup($1);
|
|
||||||
if (!path) {
|
|
||||||
@@ -312,81 +301,93 @@ map: PATH
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- | MAPTYPE COLON PATH
|
|
||||||
+ | MAPTYPE PATH
|
|
||||||
{
|
|
||||||
char *tmp = NULL;
|
|
||||||
|
|
||||||
+ trim_maptype($1);
|
|
||||||
+
|
|
||||||
if ((tmp = strchr($1, ',')))
|
|
||||||
*tmp++ = '\0';
|
|
||||||
|
|
||||||
type = master_strdup($1);
|
|
||||||
if (!type) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
if (tmp) {
|
|
||||||
format = master_strdup(tmp);
|
|
||||||
if (!format) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp_argc++;
|
|
||||||
- tmp_argv = add_argv(tmp_argc, tmp_argv, $3);
|
|
||||||
+ tmp_argv = add_argv(tmp_argc, tmp_argv, $2);
|
|
||||||
if (!tmp_argv) {
|
|
||||||
master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- | MAPTYPE COLON MAPNAME
|
|
||||||
+ | MAPTYPE MAPNAME
|
|
||||||
{
|
|
||||||
char *tmp = NULL;
|
|
||||||
|
|
||||||
+ trim_maptype($1);
|
|
||||||
+
|
|
||||||
if ((tmp = strchr($1, ',')))
|
|
||||||
*tmp++ = '\0';
|
|
||||||
|
|
||||||
type = master_strdup($1);
|
|
||||||
if (!type) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
if (tmp) {
|
|
||||||
format = master_strdup(tmp);
|
|
||||||
if (!format) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp_argc++;
|
|
||||||
- tmp_argv = add_argv(tmp_argc, tmp_argv, $3);
|
|
||||||
+ tmp_argv = add_argv(tmp_argc, tmp_argv, $2);
|
|
||||||
if (!tmp_argv) {
|
|
||||||
master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- | MAPTYPE COLON dn
|
|
||||||
+ | MAPTYPE dn
|
|
||||||
{
|
|
||||||
char *tmp = NULL;
|
|
||||||
|
|
||||||
+ trim_maptype($1);
|
|
||||||
+
|
|
||||||
if ((tmp = strchr($1, ',')))
|
|
||||||
*tmp++ = '\0';
|
|
||||||
|
|
||||||
type = master_strdup($1);
|
|
||||||
if (!type) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
if (tmp) {
|
|
||||||
format = master_strdup(tmp);
|
|
||||||
if (!format) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp_argc++;
|
|
||||||
- tmp_argv = add_argv(tmp_argc, tmp_argv, $3);
|
|
||||||
+ tmp_argv = add_argv(tmp_argc, tmp_argv, $2);
|
|
||||||
if (!tmp_argv) {
|
|
||||||
master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
@@ -396,6 +397,7 @@ map: PATH
|
|
||||||
if (*tmp_argv[0]) {
|
|
||||||
tmp = malloc(strlen(type) + strlen(tmp_argv[0]) + 2);
|
|
||||||
if (!tmp) {
|
|
||||||
+ master_error("memory allocation error");
|
|
||||||
local_free_vars();
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
@@ -628,33 +630,47 @@ static void local_free_vars(void)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int add_multi_mapstr(void)
|
|
||||||
+static void trim_maptype(char *type)
|
|
||||||
{
|
|
||||||
- /* We need the individual map types for a multi map */
|
|
||||||
- if (!type) {
|
|
||||||
- if (tmp_argc > 0 && *tmp_argv[0] == '/')
|
|
||||||
- type = strdup("file");
|
|
||||||
- else
|
|
||||||
- return 0;
|
|
||||||
+ char *tmp;
|
|
||||||
+
|
|
||||||
+ tmp = strchr(type, ':');
|
|
||||||
+ if (tmp)
|
|
||||||
+ *tmp = '\0';
|
|
||||||
+ else {
|
|
||||||
+ int len = strlen(type);
|
|
||||||
+ while (len-- && isblank(type[len]))
|
|
||||||
+ type[len] = '\0';
|
|
||||||
}
|
|
||||||
+ return;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int add_multi_mapstr(void)
|
|
||||||
+{
|
|
||||||
+ if (type) {
|
|
||||||
+ /* If type given and format is non-null add it back */
|
|
||||||
+ if (format) {
|
|
||||||
+ int len = strlen(type) + strlen(format) + 2;
|
|
||||||
+ char *tmp = realloc(type, len);
|
|
||||||
+ if (!tmp)
|
|
||||||
+ return 0;
|
|
||||||
+ type = tmp;
|
|
||||||
+ strcat(type, ",");
|
|
||||||
+ strcat(type, format);
|
|
||||||
+ free(format);
|
|
||||||
+ format = NULL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- if (format) {
|
|
||||||
- char *tmp = realloc(type, strlen(type) + strlen(format) + 2);
|
|
||||||
- if (!tmp)
|
|
||||||
+ local_argc++;
|
|
||||||
+ local_argv = add_argv(local_argc, local_argv, type);
|
|
||||||
+ if (!local_argv) {
|
|
||||||
+ free(type);
|
|
||||||
+ type = NULL;
|
|
||||||
return 0;
|
|
||||||
- type = tmp;
|
|
||||||
- strcat(type, ",");
|
|
||||||
- strcat(type, format);
|
|
||||||
- free(format);
|
|
||||||
- format = NULL;
|
|
||||||
- }
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- local_argc++;
|
|
||||||
- local_argv = add_argv(local_argc, local_argv, type);
|
|
||||||
- if (!local_argv) {
|
|
||||||
free(type);
|
|
||||||
type = NULL;
|
|
||||||
- return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
local_argv = append_argv(local_argc, local_argv, tmp_argc, tmp_argv);
|
|
||||||
@@ -667,8 +683,6 @@ static int add_multi_mapstr(void)
|
|
||||||
|
|
||||||
tmp_argc = 0;
|
|
||||||
tmp_argv = NULL;
|
|
||||||
- free(type);
|
|
||||||
- type = NULL;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
diff --git a/lib/master_tok.l b/lib/master_tok.l
|
|
||||||
index 0548de1..9bfeefa 100644
|
|
||||||
--- a/lib/master_tok.l
|
|
||||||
+++ b/lib/master_tok.l
|
|
||||||
@@ -111,9 +111,9 @@ DNATTRSTR {AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}
|
|
||||||
DNNAMESTR ([[:alnum:]_.\-]+)
|
|
||||||
|
|
||||||
INTMAP (-hosts|-null)
|
|
||||||
-MULTI ((multi)(,(sun|hesiod))?[\:]?{OPTWS})
|
|
||||||
+MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS}))
|
|
||||||
MULTISEP ([\-]{2}[[:blank:]]+)
|
|
||||||
-MTYPE ((file|program|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?)
|
|
||||||
+MTYPE ((file|program|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?(:{OPTWS}|{WS}))
|
|
||||||
|
|
||||||
|
|
||||||
OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
|
|
||||||
@@ -192,7 +192,7 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
|
|
||||||
return(MULTITYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
- {MTYPE}/":" {
|
|
||||||
+ {MTYPE} {
|
|
||||||
strcpy(master_lval.strtype, master_text);
|
|
||||||
return(MAPTYPE);
|
|
||||||
}
|
|
||||||
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
|
|
||||||
index 0e36a6f..98afaa9 100644
|
|
||||||
--- a/man/auto.master.5.in
|
|
||||||
+++ b/man/auto.master.5.in
|
|
||||||
@@ -103,6 +103,10 @@ entries are used for maps.
|
|
||||||
.B ldap \fPor\fB ldaps
|
|
||||||
The map is stored in an LDAP directory. If \fBldaps\fP is used the
|
|
||||||
appropriate certificate must be configured in the LDAP client.
|
|
||||||
+.TP
|
|
||||||
+.B multi
|
|
||||||
+This map type allows the specification of multiple maps separated
|
|
||||||
+by "--". These maps are searched in order to resolve key lookups.
|
|
||||||
.RE
|
|
||||||
.TP
|
|
||||||
\fBformat\fP
|
|
||||||
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
|
|
||||||
index 38ca36c..8fa94ae 100644
|
|
||||||
--- a/modules/lookup_multi.c
|
|
||||||
+++ b/modules/lookup_multi.c
|
|
||||||
@@ -19,6 +19,7 @@
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
+#include <sys/stat.h>
|
|
||||||
|
|
||||||
#define MODULE_LOOKUP
|
|
||||||
#include "automount.h"
|
|
||||||
@@ -28,7 +29,7 @@
|
|
||||||
|
|
||||||
struct module_info {
|
|
||||||
int argc;
|
|
||||||
- const char *const *argv;
|
|
||||||
+ const char **argv;
|
|
||||||
struct lookup_mod *mod;
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -40,11 +41,105 @@ struct lookup_context {
|
|
||||||
|
|
||||||
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
|
|
||||||
|
|
||||||
+static struct lookup_mod *nss_open_lookup(const char *format, int argc, const char **argv)
|
|
||||||
+{
|
|
||||||
+ struct list_head nsslist;
|
|
||||||
+ struct list_head *head, *p;
|
|
||||||
+ struct lookup_mod *mod;
|
|
||||||
+ char buf[MAX_ERR_BUF], *estr;
|
|
||||||
+
|
|
||||||
+ if (!argv || !argv[0])
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ if (*argv[0] == '/')
|
|
||||||
+ return open_lookup("file", MODPREFIX, format, argc, argv);
|
|
||||||
+
|
|
||||||
+ if (!strncmp(argv[0], "file", 4) ||
|
|
||||||
+ !strncmp(argv[0], "yp", 2) ||
|
|
||||||
+ !strncmp(argv[0], "nisplus", 7) ||
|
|
||||||
+ !strncmp(argv[0], "nis", 3) ||
|
|
||||||
+ !strncmp(argv[0], "ldaps", 5) ||
|
|
||||||
+ !strncmp(argv[0], "ldap", 4)) {
|
|
||||||
+ const char *fmt = strchr(argv[0], ',');
|
|
||||||
+ if (fmt)
|
|
||||||
+ fmt++;
|
|
||||||
+ else
|
|
||||||
+ fmt = format;
|
|
||||||
+ return open_lookup(argv[0], MODPREFIX, fmt, argc -1, argv + 1);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ INIT_LIST_HEAD(&nsslist);
|
|
||||||
+
|
|
||||||
+ if (nsswitch_parse(&nsslist)) {
|
|
||||||
+ if (!list_empty(&nsslist))
|
|
||||||
+ free_sources(&nsslist);
|
|
||||||
+ error(LOGOPT_ANY, "can't to read name service switch config.");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ head = &nsslist;
|
|
||||||
+ list_for_each(p, head) {
|
|
||||||
+ struct nss_source *this;
|
|
||||||
+
|
|
||||||
+ this = list_entry(p, struct nss_source, list);
|
|
||||||
+
|
|
||||||
+ if (!strcmp(this->source, "files")) {
|
|
||||||
+ char src_file[] = "file";
|
|
||||||
+ char src_prog[] = "program";
|
|
||||||
+ struct stat st;
|
|
||||||
+ char *type, *path, *save_argv0;
|
|
||||||
+
|
|
||||||
+ path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(argv[0]) + 2);
|
|
||||||
+ if (!path) {
|
|
||||||
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
+ crit(LOGOPT_ANY, MODPREFIX "error: %s", estr);
|
|
||||||
+ free_sources(&nsslist);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ strcpy(path, AUTOFS_MAP_DIR);
|
|
||||||
+ strcat(path, "/");
|
|
||||||
+ strcat(path, argv[0]);
|
|
||||||
+
|
|
||||||
+ if (stat(path, &st) == -1 || !S_ISREG(st.st_mode)) {
|
|
||||||
+ free(path);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (st.st_mode & __S_IEXEC)
|
|
||||||
+ type = src_prog;
|
|
||||||
+ else
|
|
||||||
+ type = src_file;
|
|
||||||
+
|
|
||||||
+ save_argv0 = (char *) argv[0];
|
|
||||||
+ argv[0] = path;
|
|
||||||
+
|
|
||||||
+ mod = open_lookup(type, MODPREFIX, format, argc, argv);
|
|
||||||
+ if (mod) {
|
|
||||||
+ free_sources(&nsslist);
|
|
||||||
+ free(save_argv0);
|
|
||||||
+ return mod;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ argv[0] = save_argv0;
|
|
||||||
+ free(path);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ mod = open_lookup(this->source, MODPREFIX, format, argc, argv);
|
|
||||||
+ if (mod) {
|
|
||||||
+ free_sources(&nsslist);
|
|
||||||
+ return mod;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ free_sources(&nsslist);
|
|
||||||
+
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void **context)
|
|
||||||
{
|
|
||||||
struct lookup_context *ctxt;
|
|
||||||
char buf[MAX_ERR_BUF];
|
|
||||||
- char *map, *mapfmt;
|
|
||||||
+ char **args;
|
|
||||||
int i, an;
|
|
||||||
char *estr;
|
|
||||||
|
|
||||||
@@ -73,39 +168,42 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void *
|
|
||||||
|
|
||||||
memcpy(ctxt->argl, argv, (argc + 1) * sizeof(const char *));
|
|
||||||
|
|
||||||
+ args = NULL;
|
|
||||||
for (i = an = 0; ctxt->argl[an]; an++) {
|
|
||||||
if (ctxt->m[i].argc == 0) {
|
|
||||||
- ctxt->m[i].argv = &ctxt->argl[an];
|
|
||||||
+ args = (char **) &ctxt->argl[an];
|
|
||||||
}
|
|
||||||
if (!strcmp(ctxt->argl[an], "--")) {
|
|
||||||
ctxt->argl[an] = NULL;
|
|
||||||
+ if (!args) {
|
|
||||||
+ crit(LOGOPT_ANY,
|
|
||||||
+ MODPREFIX "error assigning map args");
|
|
||||||
+ goto error_out;
|
|
||||||
+ }
|
|
||||||
+ ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args);
|
|
||||||
+ if (!ctxt->m[i].argv)
|
|
||||||
+ goto nomem;
|
|
||||||
+ args = NULL;
|
|
||||||
i++;
|
|
||||||
} else {
|
|
||||||
ctxt->m[i].argc++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- for (i = 0; i < ctxt->n; i++) {
|
|
||||||
- if (!ctxt->m[i].argv[0]) {
|
|
||||||
- crit(LOGOPT_ANY, MODPREFIX "missing module name");
|
|
||||||
- goto error_out;
|
|
||||||
- }
|
|
||||||
- map = strdup(ctxt->m[i].argv[0]);
|
|
||||||
- if (!map)
|
|
||||||
+ /* catch the last one */
|
|
||||||
+ if (args) {
|
|
||||||
+ ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args);
|
|
||||||
+ if (!ctxt->m[i].argv)
|
|
||||||
goto nomem;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- if ((mapfmt = strchr(map, ',')))
|
|
||||||
- *(mapfmt++) = '\0';
|
|
||||||
-
|
|
||||||
- if (!(ctxt->m[i].mod = open_lookup(map, MODPREFIX,
|
|
||||||
- mapfmt ? mapfmt : my_mapfmt,
|
|
||||||
- ctxt->m[i].argc - 1,
|
|
||||||
- ctxt->m[i].argv + 1))) {
|
|
||||||
+ for (i = 0; i < ctxt->n; i++) {
|
|
||||||
+ ctxt->m[i].mod = nss_open_lookup(my_mapfmt,
|
|
||||||
+ ctxt->m[i].argc, ctxt->m[i].argv);
|
|
||||||
+ if (!ctxt->m[i].mod) {
|
|
||||||
error(LOGOPT_ANY, MODPREFIX "error opening module");
|
|
||||||
- free(map);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
- free(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
*context = ctxt;
|
|
||||||
@@ -116,9 +214,12 @@ nomem:
|
|
||||||
crit(LOGOPT_ANY, MODPREFIX "error: %s", estr);
|
|
||||||
error_out:
|
|
||||||
if (ctxt) {
|
|
||||||
- for (i = 0; i < ctxt->n; i++)
|
|
||||||
+ for (i = 0; i < ctxt->n; i++) {
|
|
||||||
if (ctxt->m[i].mod)
|
|
||||||
close_lookup(ctxt->m[i].mod);
|
|
||||||
+ if (ctxt->m[i].argv)
|
|
||||||
+ free_argv(ctxt->m[i].argc, ctxt->m[i].argv);
|
|
||||||
+ }
|
|
||||||
if (ctxt->m)
|
|
||||||
free(ctxt->m);
|
|
||||||
if (ctxt->argl)
|
|
||||||
@@ -188,6 +289,8 @@ int lookup_done(void *context)
|
|
||||||
for (i = 0; i < ctxt->n; i++) {
|
|
||||||
if (ctxt->m[i].mod)
|
|
||||||
rv = rv || close_lookup(ctxt->m[i].mod);
|
|
||||||
+ if (ctxt->m[i].argv)
|
|
||||||
+ free_argv(ctxt->m[i].argc, ctxt->m[i].argv);
|
|
||||||
}
|
|
||||||
free(ctxt->argl);
|
|
||||||
free(ctxt->m);
|
|
@ -1,852 +0,0 @@
|
|||||||
diff --git a/include/defaults.h b/include/defaults.h
|
|
||||||
index 0984b1c..46393d9 100644
|
|
||||||
--- a/include/defaults.h
|
|
||||||
+++ b/include/defaults.h
|
|
||||||
@@ -26,7 +26,8 @@
|
|
||||||
#define DEFAULT_BROWSE_MODE 1
|
|
||||||
#define DEFAULT_LOGGING 0
|
|
||||||
|
|
||||||
-#define DEFAULT_LDAP_SERVER NULL
|
|
||||||
+#define DEFAULT_LDAP_TIMEOUT -1
|
|
||||||
+#define DEFAULT_LDAP_NETWORK_TIMEOUT 8
|
|
||||||
|
|
||||||
#define DEFAULT_MAP_OBJ_CLASS "nisMap"
|
|
||||||
#define DEFAULT_ENTRY_OBJ_CLASS "nisObject"
|
|
||||||
@@ -46,6 +47,10 @@ unsigned int defaults_get_timeout(void);
|
|
||||||
unsigned int defaults_get_browse_mode(void);
|
|
||||||
unsigned int defaults_get_logging(void);
|
|
||||||
const char *defaults_get_ldap_server(void);
|
|
||||||
+unsigned int defaults_get_ldap_timeout(void);
|
|
||||||
+unsigned int defaults_get_ldap_network_timeout(void);
|
|
||||||
+struct list_head *defaults_get_uris(void);
|
|
||||||
+void defaults_free_uris(struct list_head *);
|
|
||||||
struct ldap_schema *defaults_get_default_schema(void);
|
|
||||||
struct ldap_schema *defaults_get_schema(void);
|
|
||||||
struct ldap_searchdn *defaults_get_searchdns(void);
|
|
||||||
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
|
|
||||||
index 1a924be..ca8d658 100644
|
|
||||||
--- a/include/lookup_ldap.h
|
|
||||||
+++ b/include/lookup_ldap.h
|
|
||||||
@@ -18,6 +18,11 @@ struct ldap_schema {
|
|
||||||
char *value_attr;
|
|
||||||
};
|
|
||||||
|
|
||||||
+struct ldap_uri {
|
|
||||||
+ char *uri;
|
|
||||||
+ struct list_head list;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
struct ldap_searchdn {
|
|
||||||
char *basedn;
|
|
||||||
struct ldap_searchdn *next;
|
|
||||||
@@ -30,6 +35,8 @@ struct lookup_context {
|
|
||||||
int port;
|
|
||||||
char *base;
|
|
||||||
char *qdn;
|
|
||||||
+ unsigned int timeout;
|
|
||||||
+ unsigned int network_timeout;
|
|
||||||
|
|
||||||
/* LDAP version 2 or 3 */
|
|
||||||
int version;
|
|
||||||
@@ -37,7 +44,17 @@ struct lookup_context {
|
|
||||||
/* LDAP lookup configuration */
|
|
||||||
struct ldap_schema *schema;
|
|
||||||
|
|
||||||
- /* List of base dns for searching */
|
|
||||||
+ /*
|
|
||||||
+ * List of servers and base dns for searching.
|
|
||||||
+ * uri is the list of servers to attempt connection to and is
|
|
||||||
+ * used only if server, above, is NULL. The head of the list
|
|
||||||
+ * is the server which we are currently connected to.
|
|
||||||
+ * cur_host tracks chnages to connected server, triggering
|
|
||||||
+ * a scan of basedns when it changes.
|
|
||||||
+ * sdns is the list of basdns to check, done in the order
|
|
||||||
+ * given in configuration.
|
|
||||||
+ */
|
|
||||||
+ struct list_head *uri;
|
|
||||||
char *cur_host;
|
|
||||||
struct ldap_searchdn *sdns;
|
|
||||||
|
|
||||||
@@ -77,7 +94,7 @@ struct lookup_context {
|
|
||||||
#define LDAP_AUTH_AUTODETECT 0x0004
|
|
||||||
|
|
||||||
/* lookup_ldap.c */
|
|
||||||
-LDAP *init_ldap_connection(struct lookup_context *ctxt);
|
|
||||||
+LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt);
|
|
||||||
int unbind_ldap_connection(LDAP *ldap, struct lookup_context *ctxt);
|
|
||||||
int authtype_requires_creds(const char *authtype);
|
|
||||||
|
|
||||||
diff --git a/lib/defaults.c b/lib/defaults.c
|
|
||||||
index 7da4631..bf1ceed 100644
|
|
||||||
--- a/lib/defaults.c
|
|
||||||
+++ b/lib/defaults.c
|
|
||||||
@@ -17,6 +17,7 @@
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
+#include "list.h"
|
|
||||||
#include "defaults.h"
|
|
||||||
#include "lookup_ldap.h"
|
|
||||||
#include "log.h"
|
|
||||||
@@ -30,7 +31,9 @@
|
|
||||||
#define ENV_NAME_BROWSE_MODE "BROWSE_MODE"
|
|
||||||
#define ENV_NAME_LOGGING "LOGGING"
|
|
||||||
|
|
||||||
-#define ENV_LDAP_SERVER "LDAP_SERVER"
|
|
||||||
+#define LDAP_URI "LDAP_URI"
|
|
||||||
+#define ENV_LDAP_TIMEOUT "LDAP_TIMEOUT"
|
|
||||||
+#define ENV_LDAP_NETWORK_TIMEOUT "LDAP_NETWORK_TIMEOUT"
|
|
||||||
|
|
||||||
#define SEARCH_BASE "SEARCH_BASE"
|
|
||||||
|
|
||||||
@@ -44,7 +47,6 @@
|
|
||||||
#define ENV_AUTH_CONF_FILE "AUTH_CONF_FILE"
|
|
||||||
|
|
||||||
static const char *default_master_map_name = DEFAULT_MASTER_MAP_NAME;
|
|
||||||
-static const char *default_ldap_server = DEFAULT_LDAP_SERVER;
|
|
||||||
static const char *default_auth_conf_file = DEFAULT_AUTH_CONF_FILE;
|
|
||||||
|
|
||||||
static char *get_env_string(const char *name)
|
|
||||||
@@ -178,6 +180,99 @@ static int parse_line(char *line, char **res, char **value)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+void defaults_free_uris(struct list_head *list)
|
|
||||||
+{
|
|
||||||
+ struct list_head *next;
|
|
||||||
+ struct ldap_uri *uri;
|
|
||||||
+
|
|
||||||
+ if (list_empty(list)) {
|
|
||||||
+ free(list);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ next = list->next;
|
|
||||||
+ while (next != list) {
|
|
||||||
+ uri = list_entry(next, struct ldap_uri, list);
|
|
||||||
+ next = next->next;
|
|
||||||
+ list_del(&uri->list);
|
|
||||||
+ free(uri->uri);
|
|
||||||
+ free(uri);
|
|
||||||
+ }
|
|
||||||
+ free(list);
|
|
||||||
+
|
|
||||||
+ return;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static unsigned int add_uris(char *value, struct list_head *list)
|
|
||||||
+{
|
|
||||||
+ char *str, *tok, *ptr = NULL;
|
|
||||||
+ size_t len = strlen(value);
|
|
||||||
+
|
|
||||||
+ str = alloca(len);
|
|
||||||
+ if (!str)
|
|
||||||
+ return 0;
|
|
||||||
+ strcpy(str, value);
|
|
||||||
+
|
|
||||||
+ tok = strtok_r(str, " ", &ptr);
|
|
||||||
+ while (tok) {
|
|
||||||
+ struct ldap_uri *new;
|
|
||||||
+ char *uri;
|
|
||||||
+
|
|
||||||
+ new = malloc(sizeof(struct ldap_uri));
|
|
||||||
+ if (!new)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ uri = strdup(tok);
|
|
||||||
+ if (!uri)
|
|
||||||
+ free(new);
|
|
||||||
+ else {
|
|
||||||
+ new->uri = uri;
|
|
||||||
+ list_add_tail(&new->list, list);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ tok = strtok_r(NULL, " ", &ptr);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+struct list_head *defaults_get_uris(void)
|
|
||||||
+{
|
|
||||||
+ FILE *f;
|
|
||||||
+ char buf[MAX_LINE_LEN];
|
|
||||||
+ char *res;
|
|
||||||
+ struct list_head *list;
|
|
||||||
+
|
|
||||||
+ f = fopen(DEFAULTS_CONFIG_FILE, "r");
|
|
||||||
+ if (!f)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ list = malloc(sizeof(struct list_head));
|
|
||||||
+ if (!list) {
|
|
||||||
+ fclose(f);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ INIT_LIST_HEAD(list);
|
|
||||||
+
|
|
||||||
+ while ((res = fgets(buf, MAX_LINE_LEN, f))) {
|
|
||||||
+ char *key, *value;
|
|
||||||
+
|
|
||||||
+ if (!parse_line(res, &key, &value))
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ if (!strcasecmp(res, LDAP_URI))
|
|
||||||
+ add_uris(value, list);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (list_empty(list)) {
|
|
||||||
+ free(list);
|
|
||||||
+ list = NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ fclose(f);
|
|
||||||
+ return list;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Read config env variables and check they have been set.
|
|
||||||
*
|
|
||||||
@@ -205,7 +300,8 @@ unsigned int defaults_read_config(void)
|
|
||||||
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_LDAP_TIMEOUT, value) ||
|
|
||||||
+ check_set_config_value(key, ENV_LDAP_NETWORK_TIMEOUT, 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) ||
|
|
||||||
@@ -284,15 +380,26 @@ unsigned int defaults_get_logging(void)
|
|
||||||
return logging;
|
|
||||||
}
|
|
||||||
|
|
||||||
-const char *defaults_get_ldap_server(void)
|
|
||||||
+unsigned int defaults_get_ldap_timeout(void)
|
|
||||||
{
|
|
||||||
- char *server;
|
|
||||||
+ int res;
|
|
||||||
|
|
||||||
- server = get_env_string(ENV_LDAP_SERVER);
|
|
||||||
- if (!server)
|
|
||||||
- return default_ldap_server;
|
|
||||||
+ res = get_env_number(ENV_LDAP_TIMEOUT);
|
|
||||||
+ if (res < 0)
|
|
||||||
+ res = DEFAULT_LDAP_TIMEOUT;
|
|
||||||
|
|
||||||
- return (const char *) server;
|
|
||||||
+ return res;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+unsigned int defaults_get_ldap_network_timeout(void)
|
|
||||||
+{
|
|
||||||
+ int res;
|
|
||||||
+
|
|
||||||
+ res = get_env_number(ENV_LDAP_NETWORK_TIMEOUT);
|
|
||||||
+ if (res < 0)
|
|
||||||
+ res = DEFAULT_LDAP_NETWORK_TIMEOUT;
|
|
||||||
+
|
|
||||||
+ return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ldap_schema *defaults_get_default_schema(void)
|
|
||||||
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
|
|
||||||
index 0cb2f07..68447e0 100644
|
|
||||||
--- a/man/auto.master.5.in
|
|
||||||
+++ b/man/auto.master.5.in
|
|
||||||
@@ -230,10 +230,27 @@ values must be set, any partial schema specification will be ignored.
|
|
||||||
.P
|
|
||||||
The configuration settings available are:
|
|
||||||
.TP
|
|
||||||
+.B LDAP_TIMEOUT
|
|
||||||
+Set the network response timeout (default 8).
|
|
||||||
+Set timeout value for the synchronous API calls. The default is the LDAP
|
|
||||||
+library default of an infinite timeout.
|
|
||||||
+.TP
|
|
||||||
+.B LDAP_NETWORK_TIMEOUT
|
|
||||||
+Set the network response timeout (default 8).
|
|
||||||
+.TP
|
|
||||||
+.B LDAP_URI
|
|
||||||
+A space seperated list of server uris of the form <proto>://<server>[/]
|
|
||||||
+where <proto> can be ldap or ldaps. The option can be given multiple times.
|
|
||||||
+Map entries that include a server name override this option and it is then
|
|
||||||
+not used. Default is an empty list in which case either the server given
|
|
||||||
+in a map entry or the LDAP configured default is used. This uri list is read at
|
|
||||||
+startup and whenever the daemon receives a HUP signal.
|
|
||||||
+.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.
|
|
||||||
+the order they occur in the configuration. The search base list is read
|
|
||||||
+at startup and whenever the daemon recieves a HUP signal.
|
|
||||||
.TP
|
|
||||||
.B MAP_OBJECT_CLASS
|
|
||||||
The map object class. In the \fBnisMap\fP schema this corresponds to the class
|
|
||||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
|
||||||
index 2baf8b8..4068561 100644
|
|
||||||
--- a/modules/lookup_ldap.c
|
|
||||||
+++ b/modules/lookup_ldap.c
|
|
||||||
@@ -49,6 +49,8 @@ static struct ldap_schema common_schema[] = {
|
|
||||||
};
|
|
||||||
static unsigned int common_schema_count = sizeof(common_schema)/sizeof(struct ldap_schema);
|
|
||||||
|
|
||||||
+static LDAP *auth_init(const char *, struct lookup_context *);
|
|
||||||
+
|
|
||||||
int bind_ldap_anonymous(LDAP *ldap, struct lookup_context *ctxt)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
@@ -59,10 +61,18 @@ int bind_ldap_anonymous(LDAP *ldap, struct lookup_context *ctxt)
|
|
||||||
rv = ldap_simple_bind_s(ldap, NULL, NULL);
|
|
||||||
|
|
||||||
if (rv != LDAP_SUCCESS) {
|
|
||||||
- crit(LOGOPT_ANY,
|
|
||||||
- MODPREFIX "Unable to bind to the LDAP server: "
|
|
||||||
- "%s, error %s", ctxt->server ? "" : "(default)",
|
|
||||||
- ldap_err2string(rv));
|
|
||||||
+ if (!ctxt->uri) {
|
|
||||||
+ crit(LOGOPT_ANY,
|
|
||||||
+ MODPREFIX "Unable to bind to the LDAP server: "
|
|
||||||
+ "%s, error %s", ctxt->server ? "" : "(default)",
|
|
||||||
+ ldap_err2string(rv));
|
|
||||||
+ } else {
|
|
||||||
+ struct ldap_uri *uri;
|
|
||||||
+ uri = list_entry(ctxt->uri->next, struct ldap_uri, list);
|
|
||||||
+ warn(LOGOPT_ANY,
|
|
||||||
+ MODPREFIX "Unable to bind to the LDAP server: "
|
|
||||||
+ "%s, error %s", uri->uri, ldap_err2string(rv));
|
|
||||||
+ }
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -98,20 +108,21 @@ int unbind_ldap_connection(LDAP *ldap, struct lookup_context *ctxt)
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
-LDAP *init_ldap_connection(struct lookup_context *ctxt)
|
|
||||||
+LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt)
|
|
||||||
{
|
|
||||||
LDAP *ldap = NULL;
|
|
||||||
- int timeout = 8;
|
|
||||||
+ struct timeval timeout = { ctxt->timeout, 0 };
|
|
||||||
+ struct timeval net_timeout = { ctxt->network_timeout, 0 };
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
ctxt->version = 3;
|
|
||||||
|
|
||||||
/* Initialize the LDAP context. */
|
|
||||||
- rv = ldap_initialize(&ldap, ctxt->server);
|
|
||||||
+ rv = ldap_initialize(&ldap, uri);
|
|
||||||
if (rv != LDAP_OPT_SUCCESS) {
|
|
||||||
crit(LOGOPT_ANY,
|
|
||||||
MODPREFIX "couldn't initialize LDAP connection to %s",
|
|
||||||
- ctxt->server ? ctxt->server : "default server");
|
|
||||||
+ uri ? uri : "default server");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -120,7 +131,7 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
|
|
||||||
if (rv != LDAP_OPT_SUCCESS) {
|
|
||||||
/* fall back to LDAPv2 */
|
|
||||||
ldap_unbind_ext(ldap, NULL, NULL);
|
|
||||||
- rv = ldap_initialize(&ldap, ctxt->server);
|
|
||||||
+ rv = ldap_initialize(&ldap, uri);
|
|
||||||
if (rv != LDAP_OPT_SUCCESS) {
|
|
||||||
crit(LOGOPT_ANY, MODPREFIX "couldn't initialize LDAP");
|
|
||||||
return NULL;
|
|
||||||
@@ -128,12 +139,22 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
|
|
||||||
ctxt->version = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* Sane network connection timeout */
|
|
||||||
- rv = ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
|
|
||||||
+
|
|
||||||
+ if (ctxt->timeout != -1) {
|
|
||||||
+ /* Set synchronous call timeout */
|
|
||||||
+ rv = ldap_set_option(ldap, LDAP_OPT_TIMEOUT, &timeout);
|
|
||||||
+ if (rv != LDAP_OPT_SUCCESS)
|
|
||||||
+ info(LOGOPT_ANY, MODPREFIX
|
|
||||||
+ "failed to set synchronous call timeout to %d",
|
|
||||||
+ timeout.tv_sec);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Sane network timeout */
|
|
||||||
+ rv = ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &net_timeout);
|
|
||||||
if (rv != LDAP_OPT_SUCCESS)
|
|
||||||
info(LOGOPT_ANY,
|
|
||||||
MODPREFIX "failed to set connection timeout to %d",
|
|
||||||
- timeout);
|
|
||||||
+ net_timeout.tv_sec);
|
|
||||||
|
|
||||||
#ifdef WITH_SASL
|
|
||||||
if (ctxt->use_tls) {
|
|
||||||
@@ -159,7 +180,7 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ctxt->use_tls = LDAP_TLS_DONT_USE;
|
|
||||||
- ldap = init_ldap_connection(ctxt);
|
|
||||||
+ ldap = init_ldap_connection(uri, ctxt);
|
|
||||||
if (ldap)
|
|
||||||
ctxt->use_tls = LDAP_TLS_INIT;
|
|
||||||
return ldap;
|
|
||||||
@@ -271,7 +292,7 @@ static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *cla
|
|
||||||
e = ldap_first_entry(ldap, result);
|
|
||||||
if (e) {
|
|
||||||
dn = ldap_get_dn(ldap, e);
|
|
||||||
- debug(LOGOPT_NONE, MODPREFIX "query dn %s", dn);
|
|
||||||
+ debug(LOGOPT_NONE, MODPREFIX "found query dn %s", dn);
|
|
||||||
} else {
|
|
||||||
debug(LOGOPT_NONE,
|
|
||||||
MODPREFIX "query succeeded, no matches for %s",
|
|
||||||
@@ -378,16 +399,11 @@ static int find_query_dn(LDAP *ldap, struct lookup_context *ctxt)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static LDAP *do_connect(struct lookup_context *ctxt)
|
|
||||||
+static int do_bind(LDAP *ldap, struct lookup_context *ctxt)
|
|
||||||
{
|
|
||||||
- LDAP *ldap;
|
|
||||||
char *host = NULL, *nhost;
|
|
||||||
int rv, need_base = 1;
|
|
||||||
|
|
||||||
- ldap = init_ldap_connection(ctxt);
|
|
||||||
- if (!ldap)
|
|
||||||
- return NULL;
|
|
||||||
-
|
|
||||||
#ifdef WITH_SASL
|
|
||||||
debug(LOGOPT_NONE, "auth_required: %d, sasl_mech %s",
|
|
||||||
ctxt->auth_required, ctxt->sasl_mech);
|
|
||||||
@@ -407,23 +423,19 @@ static LDAP *do_connect(struct lookup_context *ctxt)
|
|
||||||
debug(LOGOPT_NONE, MODPREFIX "ldap anonymous bind returned %d", rv);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- if (rv != 0) {
|
|
||||||
- unbind_ldap_connection(ldap, ctxt);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
+ if (rv != 0)
|
|
||||||
+ return 0;
|
|
||||||
|
|
||||||
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;
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nhost = strdup(host);
|
|
||||||
if (!nhost) {
|
|
||||||
- unbind_ldap_connection(ldap, ctxt);
|
|
||||||
debug(LOGOPT_ANY, "failed to alloc context for hostname");
|
|
||||||
- return NULL;
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
ldap_memfree(host);
|
|
||||||
|
|
||||||
@@ -443,7 +455,7 @@ static LDAP *do_connect(struct lookup_context *ctxt)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!need_base)
|
|
||||||
- return ldap;
|
|
||||||
+ return 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the schema isn't defined in the configuration then check for
|
|
||||||
@@ -452,20 +464,134 @@ static LDAP *do_connect(struct lookup_context *ctxt)
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
} 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 0;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static LDAP *do_connect(const char *uri, struct lookup_context *ctxt)
|
|
||||||
+{
|
|
||||||
+ LDAP *ldap;
|
|
||||||
+
|
|
||||||
+ ldap = init_ldap_connection(uri, ctxt);
|
|
||||||
+ if (!ldap)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ if (!do_bind(ldap, ctxt)) {
|
|
||||||
+ unbind_ldap_connection(ldap, ctxt);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return ldap;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static LDAP *connect_to_server(const char *uri, struct lookup_context *ctxt)
|
|
||||||
+{
|
|
||||||
+ LDAP *ldap;
|
|
||||||
+
|
|
||||||
+#ifdef WITH_SASL
|
|
||||||
+ /*
|
|
||||||
+ * Determine which authentication mechanism to use if we require
|
|
||||||
+ * authentication.
|
|
||||||
+ */
|
|
||||||
+ if (ctxt->auth_required & LDAP_AUTH_REQUIRED) {
|
|
||||||
+ ldap = auth_init(uri, ctxt);
|
|
||||||
+ if (!ldap && ctxt->auth_required & LDAP_AUTH_AUTODETECT)
|
|
||||||
+ warn(LOGOPT_NONE,
|
|
||||||
+ "no authentication mechanisms auto detected.");
|
|
||||||
+ if (!ldap) {
|
|
||||||
+ error(LOGOPT_ANY, MODPREFIX
|
|
||||||
+ "cannot initialize authentication setup");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ if (!do_bind(ldap, ctxt)) {
|
|
||||||
+ unbind_ldap_connection(ldap, ctxt);
|
|
||||||
+ error(LOGOPT_ANY, MODPREFIX "cannot bind to server");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return ldap;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ ldap = do_connect(uri, ctxt);
|
|
||||||
+ if (!ldap) {
|
|
||||||
+ error(LOGOPT_ANY, MODPREFIX "cannot connect to server");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return ldap;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static LDAP *find_server(struct lookup_context *ctxt)
|
|
||||||
+{
|
|
||||||
+ LDAP *ldap = NULL;
|
|
||||||
+ struct ldap_uri *this;
|
|
||||||
+ struct list_head *p;
|
|
||||||
+ LIST_HEAD(tmp);
|
|
||||||
+
|
|
||||||
+ /* Try each uri in list, add connect fails to tmp list */
|
|
||||||
+ p = ctxt->uri->next;
|
|
||||||
+ while(p != ctxt->uri) {
|
|
||||||
+ this = list_entry(p, struct ldap_uri, list);
|
|
||||||
+ p = p->next;
|
|
||||||
+ debug(LOGOPT_ANY, "check uri %s", this->uri);
|
|
||||||
+ ldap = connect_to_server(this->uri, ctxt);
|
|
||||||
+ if (ldap) {
|
|
||||||
+ debug(LOGOPT_ANY, "connexted to uri %s", this->uri);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ list_del_init(&this->list);
|
|
||||||
+ list_add_tail(&this->list, &tmp);
|
|
||||||
}
|
|
||||||
+ /*
|
|
||||||
+ * Successfuly connected uri (head of list) and untried uris are
|
|
||||||
+ * in ctxt->uri list. Make list of remainder and failed uris with
|
|
||||||
+ * failed uris at end and assign back to ctxt-uri.
|
|
||||||
+ */
|
|
||||||
+ list_splice(ctxt->uri, &tmp);
|
|
||||||
+ INIT_LIST_HEAD(ctxt->uri);
|
|
||||||
+ list_splice(&tmp, ctxt->uri);
|
|
||||||
+
|
|
||||||
+ return ldap;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static LDAP *do_reconnect(struct lookup_context *ctxt)
|
|
||||||
+{
|
|
||||||
+ LDAP *ldap;
|
|
||||||
+
|
|
||||||
+ if (ctxt->server || !ctxt->uri) {
|
|
||||||
+ ldap = do_connect(ctxt->server, ctxt);
|
|
||||||
+ return ldap;
|
|
||||||
+ } else {
|
|
||||||
+ struct ldap_uri *this;
|
|
||||||
+ this = list_entry(ctxt->uri->next, struct ldap_uri, list);
|
|
||||||
+ ldap = do_connect(this->uri, ctxt);
|
|
||||||
+ if (ldap)
|
|
||||||
+ return ldap;
|
|
||||||
+ /* Failed to connect, put at end of list */
|
|
||||||
+ list_del_init(&this->list);
|
|
||||||
+ list_add_tail(&this->list, ctxt->uri);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ autofs_sasl_done(ctxt);
|
|
||||||
+
|
|
||||||
+ /* Current server failed connect, try the rest */
|
|
||||||
+ ldap = find_server(ctxt);
|
|
||||||
+ if (!ldap)
|
|
||||||
+ error(LOGOPT_ANY, MODPREFIX "failed to find available server");
|
|
||||||
|
|
||||||
return ldap;
|
|
||||||
}
|
|
||||||
@@ -760,10 +886,10 @@ out:
|
|
||||||
* information. If there is no configuration file, then we fall back to
|
|
||||||
* trying all supported authentication mechanisms until one works.
|
|
||||||
*
|
|
||||||
- * Returns 0 on success, with authtype, user and secret filled in as
|
|
||||||
- * appropriate. Returns -1 on failre.
|
|
||||||
+ * Returns ldap connection on success, with authtype, user and secret
|
|
||||||
+ * filled in as appropriate. Returns NULL on failre.
|
|
||||||
*/
|
|
||||||
-int auth_init(struct lookup_context *ctxt)
|
|
||||||
+static LDAP *auth_init(const char *uri, struct lookup_context *ctxt)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
LDAP *ldap;
|
|
||||||
@@ -776,14 +902,11 @@ int auth_init(struct lookup_context *ctxt)
|
|
||||||
*/
|
|
||||||
ret = parse_ldap_config(ctxt);
|
|
||||||
if (ret)
|
|
||||||
- return -1;
|
|
||||||
-
|
|
||||||
- if (ctxt->auth_required & LDAP_AUTH_NOTREQUIRED)
|
|
||||||
- return 0;
|
|
||||||
+ return NULL;
|
|
||||||
|
|
||||||
- ldap = init_ldap_connection(ctxt);
|
|
||||||
+ ldap = init_ldap_connection(uri, ctxt);
|
|
||||||
if (!ldap)
|
|
||||||
- return -1;
|
|
||||||
+ return NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize the sasl library. It is okay if user and secret
|
|
||||||
@@ -794,18 +917,12 @@ int auth_init(struct lookup_context *ctxt)
|
|
||||||
* the credential cache and the client and service principals.
|
|
||||||
*/
|
|
||||||
ret = autofs_sasl_init(ldap, ctxt);
|
|
||||||
- unbind_ldap_connection(ldap, ctxt);
|
|
||||||
if (ret) {
|
|
||||||
ctxt->sasl_mech = NULL;
|
|
||||||
- if (ctxt->auth_required & LDAP_AUTH_AUTODETECT) {
|
|
||||||
- warn(LOGOPT_NONE,
|
|
||||||
- "no authentication mechanisms auto detected.");
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
- return -1;
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return 0;
|
|
||||||
+ return ldap;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1036,6 +1153,8 @@ static void free_context(struct lookup_context *ctxt)
|
|
||||||
free(ctxt->cur_host);
|
|
||||||
if (ctxt->base)
|
|
||||||
free(ctxt->base);
|
|
||||||
+ if (ctxt->uri)
|
|
||||||
+ defaults_free_uris(ctxt->uri);
|
|
||||||
if (ctxt->sdns)
|
|
||||||
defaults_free_searchdns(ctxt->sdns);
|
|
||||||
free(ctxt);
|
|
||||||
@@ -1043,6 +1162,30 @@ static void free_context(struct lookup_context *ctxt)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void validate_uris(struct list_head *list)
|
|
||||||
+{
|
|
||||||
+ struct list_head *next;
|
|
||||||
+
|
|
||||||
+ next = list->next;
|
|
||||||
+ while (next != list) {
|
|
||||||
+ struct ldap_uri *this;
|
|
||||||
+
|
|
||||||
+ this = list_entry(next, struct ldap_uri, list);
|
|
||||||
+ next = next->next;
|
|
||||||
+
|
|
||||||
+ /* At least we get some basic validation */
|
|
||||||
+ if (!ldap_is_ldap_url(this->uri)) {
|
|
||||||
+ warn(LOGOPT_ANY,
|
|
||||||
+ "removed invalid uri from list, %s", this->uri);
|
|
||||||
+ list_del(&this->list);
|
|
||||||
+ free(this->uri);
|
|
||||||
+ free(this);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* This initializes a context (persistent non-global data) for queries to
|
|
||||||
* this module. Return zero if we succeed.
|
|
||||||
@@ -1051,7 +1194,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
|
||||||
{
|
|
||||||
struct lookup_context *ctxt;
|
|
||||||
char buf[MAX_ERR_BUF];
|
|
||||||
- int ret;
|
|
||||||
LDAP *ldap = NULL;
|
|
||||||
|
|
||||||
*context = NULL;
|
|
||||||
@@ -1079,33 +1221,42 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef WITH_SASL
|
|
||||||
- /*
|
|
||||||
- * Determine which authentication mechanism to use. We sanity-
|
|
||||||
- * check by binding to the server temporarily.
|
|
||||||
- */
|
|
||||||
- ret = auth_init(ctxt);
|
|
||||||
- if (ret && (ctxt->auth_required & LDAP_AUTH_REQUIRED)) {
|
|
||||||
- error(LOGOPT_ANY, MODPREFIX
|
|
||||||
- "cannot initialize authentication setup");
|
|
||||||
- free_context(ctxt);
|
|
||||||
- return 1;
|
|
||||||
+ ctxt->timeout = defaults_get_ldap_timeout();
|
|
||||||
+ ctxt->network_timeout = defaults_get_ldap_network_timeout();
|
|
||||||
+
|
|
||||||
+ if (!ctxt->server) {
|
|
||||||
+ struct list_head *uris = defaults_get_uris();
|
|
||||||
+ if (uris) {
|
|
||||||
+ validate_uris(uris);
|
|
||||||
+ if (!list_empty(uris))
|
|
||||||
+ ctxt->uri = uris;
|
|
||||||
+ else
|
|
||||||
+ free(uris);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
-#endif
|
|
||||||
|
|
||||||
- ldap = do_connect(ctxt);
|
|
||||||
- if (!ldap) {
|
|
||||||
- error(LOGOPT_ANY, MODPREFIX "cannot connect to server");
|
|
||||||
- free_context(ctxt);
|
|
||||||
- return 1;
|
|
||||||
+ if (ctxt->server || !ctxt->uri) {
|
|
||||||
+ ldap = connect_to_server(ctxt->server, ctxt);
|
|
||||||
+ if (!ldap) {
|
|
||||||
+ free_context(ctxt);
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ ldap = find_server(ctxt);
|
|
||||||
+ if (!ldap) {
|
|
||||||
+ free_context(ctxt);
|
|
||||||
+ error(LOGOPT_ANY, MODPREFIX
|
|
||||||
+ "failed to find available server");
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
unbind_ldap_connection(ldap, ctxt);
|
|
||||||
|
|
||||||
/* Open the parser, if we can. */
|
|
||||||
ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
|
|
||||||
if (!ctxt->parse) {
|
|
||||||
- crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
|
|
||||||
free_context(ctxt);
|
|
||||||
+ crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
*context = ctxt;
|
|
||||||
@@ -1153,7 +1304,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
|
||||||
query[l] = '\0';
|
|
||||||
|
|
||||||
/* Initialize the LDAP context. */
|
|
||||||
- ldap = do_connect(ctxt);
|
|
||||||
+ ldap = do_reconnect(ctxt);
|
|
||||||
if (!ldap)
|
|
||||||
return NSS_STATUS_UNAVAIL;
|
|
||||||
|
|
||||||
@@ -1305,7 +1456,7 @@ static int read_one_map(struct autofs_point *ap,
|
|
||||||
query[l] = '\0';
|
|
||||||
|
|
||||||
/* Initialize the LDAP context. */
|
|
||||||
- ldap = do_connect(ctxt);
|
|
||||||
+ ldap = do_reconnect(ctxt);
|
|
||||||
if (!ldap)
|
|
||||||
return NSS_STATUS_UNAVAIL;
|
|
||||||
|
|
||||||
@@ -1536,6 +1687,9 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
|
||||||
if (ret != NSS_STATUS_SUCCESS) {
|
|
||||||
switch (rv) {
|
|
||||||
case LDAP_SIZELIMIT_EXCEEDED:
|
|
||||||
+ crit(ap->logopt, MODPREFIX
|
|
||||||
+ "Unable to download entire LDAP map for: %s",
|
|
||||||
+ ap->path);
|
|
||||||
case LDAP_UNWILLING_TO_PERFORM:
|
|
||||||
pthread_setcancelstate(cur_state, NULL);
|
|
||||||
return NSS_STATUS_UNAVAIL;
|
|
||||||
@@ -1612,7 +1766,7 @@ static int lookup_one(struct autofs_point *ap,
|
|
||||||
query[ql] = '\0';
|
|
||||||
|
|
||||||
/* Initialize the LDAP context. */
|
|
||||||
- ldap = do_connect(ctxt);
|
|
||||||
+ ldap = do_reconnect(ctxt);
|
|
||||||
if (!ldap)
|
|
||||||
return CHE_FAIL;
|
|
||||||
|
|
||||||
diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in
|
|
||||||
index 2b1e20a..f01ee5f 100644
|
|
||||||
--- a/redhat/autofs.sysconfig.in
|
|
||||||
+++ b/redhat/autofs.sysconfig.in
|
|
||||||
@@ -23,6 +23,25 @@ BROWSE_MODE="no"
|
|
||||||
#
|
|
||||||
# Define base dn for map dn lookup.
|
|
||||||
#
|
|
||||||
+# Define server URIs
|
|
||||||
+#
|
|
||||||
+# LDAP_URI - space seperated list of server uris of the form
|
|
||||||
+# <proto>://<server>[/] where <proto> can be ldap
|
|
||||||
+# or ldaps. The option can be given multiple times.
|
|
||||||
+# Map entries that include a server name override
|
|
||||||
+# this option.
|
|
||||||
+#
|
|
||||||
+#LDAP_URI=""
|
|
||||||
+#
|
|
||||||
+# LDAP__TIMEOUT - timeout value for the synchronous API calls
|
|
||||||
+# (default is LDAP library default).
|
|
||||||
+#
|
|
||||||
+#LDAP_TIMEOUT=-1
|
|
||||||
+#
|
|
||||||
+# LDAP_NETWORK_TIMEOUT - set the network response timeout (default 8).
|
|
||||||
+#
|
|
||||||
+#LDAP_NETWORK_TIMEOUT=8
|
|
||||||
+#
|
|
||||||
# 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.
|
|
||||||
diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
|
|
||||||
index 2b1e20a..028341c 100644
|
|
||||||
--- a/samples/autofs.conf.default.in
|
|
||||||
+++ b/samples/autofs.conf.default.in
|
|
||||||
@@ -21,6 +21,25 @@ BROWSE_MODE="no"
|
|
||||||
#
|
|
||||||
#LOGGING="none"
|
|
||||||
#
|
|
||||||
+# Define server URIs
|
|
||||||
+#
|
|
||||||
+# LDAP_URI - space seperated list of server uris of the form
|
|
||||||
+# <proto>://<server>[/] where <proto> can be ldap
|
|
||||||
+# or ldaps. The option can be given multiple times.
|
|
||||||
+# Map entries that include a server name override
|
|
||||||
+# this option.
|
|
||||||
+#
|
|
||||||
+#LDAP_URI=""
|
|
||||||
+#
|
|
||||||
+# LDAP__TIMEOUT - timeout value for the synchronous API calls
|
|
||||||
+# (default is LDAP library default).
|
|
||||||
+#
|
|
||||||
+#LDAP_TIMEOUT=-1
|
|
||||||
+#
|
|
||||||
+# LDAP_NETWORK_TIMEOUT - set the network response timeout (default 8).
|
|
||||||
+#
|
|
||||||
+#LDAP_NETWORK_TIMEOUT=8
|
|
||||||
+#
|
|
||||||
# Define base dn for map dn lookup.
|
|
||||||
#
|
|
||||||
# SEARCH_BASE - base dn to use for searching for map search dn.
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/man/autofs.5 b/man/autofs.5
|
|
||||||
index eb15c2a..5a01791 100644
|
|
||||||
--- a/man/autofs.5
|
|
||||||
+++ b/man/autofs.5
|
|
||||||
@@ -128,7 +128,7 @@ entry looks like this:
|
|
||||||
.RS +.2i
|
|
||||||
.ta 1.0i
|
|
||||||
.nf
|
|
||||||
-* server:i/export/home/&
|
|
||||||
+* server:/export/home/&
|
|
||||||
.fi
|
|
||||||
.RE
|
|
||||||
.sp
|
|
@ -1,31 +0,0 @@
|
|||||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
|
||||||
index 06506a0..de8d515 100644
|
|
||||||
--- a/modules/lookup_ldap.c
|
|
||||||
+++ b/modules/lookup_ldap.c
|
|
||||||
@@ -549,7 +549,7 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
|
|
||||||
const char *ptr, *name;
|
|
||||||
int l, al_len;
|
|
||||||
|
|
||||||
- *proto = '\0';
|
|
||||||
+ memset(proto, 0, 9);
|
|
||||||
ptr = url;
|
|
||||||
|
|
||||||
debug(LOGOPT_NONE,
|
|
||||||
@@ -620,7 +620,7 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
|
|
||||||
} else if (strchr(ptr, ':') != NULL) {
|
|
||||||
char *q = NULL;
|
|
||||||
|
|
||||||
- /* Isolate the server(s). Include the port spec */
|
|
||||||
+ /* Isolate the server. Include the port spec */
|
|
||||||
q = strchr(ptr, ':');
|
|
||||||
if (isdigit(*q))
|
|
||||||
while (isdigit(*q))
|
|
||||||
@@ -633,7 +633,7 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
|
|
||||||
}
|
|
||||||
|
|
||||||
l = q - ptr;
|
|
||||||
- if (proto) {
|
|
||||||
+ if (*proto) {
|
|
||||||
al_len = l + strlen(proto) + 2;
|
|
||||||
tmp = malloc(al_len);
|
|
||||||
} else {
|
|
@ -1,105 +0,0 @@
|
|||||||
diff -Nurp autofs-5.0.2.orig/lib/master_tok.l autofs-5.0.2/lib/master_tok.l
|
|
||||||
--- autofs-5.0.2.orig/lib/master_tok.l 2007-11-20 15:37:48.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/lib/master_tok.l 2007-11-20 15:38:21.000000000 +0900
|
|
||||||
@@ -108,7 +108,8 @@ AT_DC ([dD][[cC])
|
|
||||||
AT_O ([oO])
|
|
||||||
AT_C ([cC])
|
|
||||||
DNATTRSTR {AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}
|
|
||||||
-DNNAMESTR ([[:alnum:]_.\-]+)
|
|
||||||
+DNNAMESTR1 ([[:alnum:]_.\- ]+)
|
|
||||||
+DNNAMESTR2 ([[:alnum:]_.\-]+)
|
|
||||||
|
|
||||||
INTMAP (-hosts|-null)
|
|
||||||
MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS}))
|
|
||||||
@@ -281,7 +282,12 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--
|
|
||||||
return EQUAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- {DNNAMESTR} {
|
|
||||||
+ {DNNAMESTR1}/"," {
|
|
||||||
+ strcpy(master_lval.strtype, master_text);
|
|
||||||
+ return DNNAME;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ {DNNAMESTR2} {
|
|
||||||
strcpy(master_lval.strtype, master_text);
|
|
||||||
return DNNAME;
|
|
||||||
}
|
|
||||||
@@ -378,7 +384,13 @@ void master_set_scan_buffer(const char *
|
|
||||||
{
|
|
||||||
line = buffer;
|
|
||||||
line_pos = &line[0];
|
|
||||||
- line_lim = line + strlen(buffer);
|
|
||||||
+ /*
|
|
||||||
+ * Ensure buffer is 1 greater than string and is zeroed before
|
|
||||||
+ * the parse so we can fit the extra NULL which allows us to
|
|
||||||
+ * explicitly match an end of line within the buffer (ie. the
|
|
||||||
+ * need for 2 NULLS when parsing in memeory buffers).
|
|
||||||
+ */
|
|
||||||
+ line_lim = line + strlen(buffer) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
|
||||||
diff -Nurp autofs-5.0.2.orig/modules/lookup_file.c autofs-5.0.2/modules/lookup_file.c
|
|
||||||
--- autofs-5.0.2.orig/modules/lookup_file.c 2007-11-20 15:37:48.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/modules/lookup_file.c 2007-11-20 15:38:18.000000000 +0900
|
|
||||||
@@ -479,7 +479,7 @@ int lookup_read_master(struct master *ma
|
|
||||||
|
|
||||||
master->name = save_name;
|
|
||||||
} else {
|
|
||||||
- blen = path_len + 1 + ent_len + 1;
|
|
||||||
+ blen = path_len + 1 + ent_len + 2;
|
|
||||||
buffer = malloc(blen);
|
|
||||||
if (!buffer) {
|
|
||||||
error(logopt,
|
|
||||||
diff -Nurp autofs-5.0.2.orig/modules/lookup_ldap.c autofs-5.0.2/modules/lookup_ldap.c
|
|
||||||
--- autofs-5.0.2.orig/modules/lookup_ldap.c 2007-11-20 15:37:48.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/modules/lookup_ldap.c 2007-11-20 15:38:18.000000000 +0900
|
|
||||||
@@ -1368,7 +1368,7 @@ int lookup_read_master(struct master *ma
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
|
|
||||||
- blen = strlen(*keyValue) + 1 + strlen(*values) + 1;
|
|
||||||
+ blen = strlen(*keyValue) + 1 + strlen(*values) + 2;
|
|
||||||
if (blen > PARSE_MAX_BUF) {
|
|
||||||
error(logopt, MODPREFIX "map entry too long");
|
|
||||||
ldap_value_free(values);
|
|
||||||
diff -Nurp autofs-5.0.2.orig/modules/lookup_nisplus.c autofs-5.0.2/modules/lookup_nisplus.c
|
|
||||||
--- autofs-5.0.2.orig/modules/lookup_nisplus.c 2007-11-20 15:37:48.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/modules/lookup_nisplus.c 2007-11-20 15:38:18.000000000 +0900
|
|
||||||
@@ -90,7 +90,7 @@ int lookup_read_master(struct master *ma
|
|
||||||
char *path, *ent;
|
|
||||||
char *buffer;
|
|
||||||
char buf[MAX_ERR_BUF];
|
|
||||||
- int cur_state;
|
|
||||||
+ int cur_state, len;
|
|
||||||
|
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
||||||
tablename = alloca(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20);
|
|
||||||
@@ -138,11 +138,13 @@ int lookup_read_master(struct master *ma
|
|
||||||
|
|
||||||
ent = ENTRY_VAL(this, 1);
|
|
||||||
|
|
||||||
- buffer = malloc(ENTRY_LEN(this, 0) + 1 + ENTRY_LEN(this, 1) + 1);
|
|
||||||
+ len = ENTRY_LEN(this, 0) + 1 + ENTRY_LEN(this, 1) + 2;
|
|
||||||
+ buffer = malloc(len);
|
|
||||||
if (!buffer) {
|
|
||||||
logerr(MODPREFIX "could not malloc parse buffer");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
+ memset(buffer, 0, len);
|
|
||||||
|
|
||||||
strcat(buffer, path);
|
|
||||||
strcat(buffer, " ");
|
|
||||||
diff -Nurp autofs-5.0.2.orig/modules/lookup_yp.c autofs-5.0.2/modules/lookup_yp.c
|
|
||||||
--- autofs-5.0.2.orig/modules/lookup_yp.c 2007-11-20 15:37:48.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/modules/lookup_yp.c 2007-11-20 15:38:18.000000000 +0900
|
|
||||||
@@ -178,7 +178,7 @@ int yp_all_master_callback(int status, c
|
|
||||||
*(ypkey + ypkeylen) = '\0';
|
|
||||||
*(val + vallen) = '\0';
|
|
||||||
|
|
||||||
- len = ypkeylen + 1 + vallen + 1;
|
|
||||||
+ len = ypkeylen + 1 + vallen + 2;
|
|
||||||
|
|
||||||
buffer = alloca(len);
|
|
||||||
if (!buffer) {
|
|
@ -1,65 +0,0 @@
|
|||||||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
|
||||||
index fd99cf2..0be10d3 100644
|
|
||||||
--- a/daemon/lookup.c
|
|
||||||
+++ b/daemon/lookup.c
|
|
||||||
@@ -222,6 +222,28 @@ int lookup_nss_read_master(struct master *master, time_t age)
|
|
||||||
"reading master %s %s", this->source, master->name);
|
|
||||||
|
|
||||||
result = read_master_map(master, this->source, age);
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * If the name of the master map hasn't been explicitly
|
|
||||||
+ * configured and we're not reading an included master map
|
|
||||||
+ * then we're using auto.master as the default. Many setups
|
|
||||||
+ * also use auto_master as the default master map so we
|
|
||||||
+ * check for this map when auto.master isn't found.
|
|
||||||
+ */
|
|
||||||
+ if (result != NSS_STATUS_SUCCESS &&
|
|
||||||
+ !master->depth && !defaults_master_set()) {
|
|
||||||
+ char *tmp = strchr(master->name, '.');
|
|
||||||
+ if (tmp) {
|
|
||||||
+ debug(logopt,
|
|
||||||
+ "%s not found, replacing '.' with '_'",
|
|
||||||
+ master->name);
|
|
||||||
+ *tmp = '_';
|
|
||||||
+ result = read_master_map(master, this->source, age);
|
|
||||||
+ if (result != NSS_STATUS_SUCCESS)
|
|
||||||
+ *tmp = '.';
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (result == NSS_STATUS_UNKNOWN) {
|
|
||||||
debug(logopt, "no map - continuing to next source");
|
|
||||||
continue;
|
|
||||||
diff --git a/include/defaults.h b/include/defaults.h
|
|
||||||
index 0e0e2a5..e296478 100644
|
|
||||||
--- a/include/defaults.h
|
|
||||||
+++ b/include/defaults.h
|
|
||||||
@@ -43,6 +43,7 @@ struct ldap_searchdn;
|
|
||||||
|
|
||||||
unsigned int defaults_read_config(unsigned int);
|
|
||||||
const char *defaults_get_master_map(void);
|
|
||||||
+int defaults_master_set(void);
|
|
||||||
unsigned int defaults_get_timeout(void);
|
|
||||||
unsigned int defaults_get_browse_mode(void);
|
|
||||||
unsigned int defaults_get_logging(void);
|
|
||||||
diff --git a/lib/defaults.c b/lib/defaults.c
|
|
||||||
index 94885e8..f494103 100644
|
|
||||||
--- a/lib/defaults.c
|
|
||||||
+++ b/lib/defaults.c
|
|
||||||
@@ -350,6 +350,15 @@ const char *defaults_get_master_map(void)
|
|
||||||
return (const char *) master;
|
|
||||||
}
|
|
||||||
|
|
||||||
+int defaults_master_set(void)
|
|
||||||
+{
|
|
||||||
+ char *val = getenv(ENV_NAME_MASTER_MAP);
|
|
||||||
+ if (!val)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
unsigned int defaults_get_timeout(void)
|
|
||||||
{
|
|
||||||
long timeout;
|
|
@ -1,264 +0,0 @@
|
|||||||
diff -up autofs-5.0.2/include/automount.h.check-mtab-updated autofs-5.0.2/include/automount.h
|
|
||||||
--- autofs-5.0.2/include/automount.h.check-mtab-updated 2007-11-20 16:10:13.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/include/automount.h 2007-11-20 16:10:36.000000000 +0900
|
|
||||||
@@ -78,6 +78,7 @@ int load_autofs4_module(void);
|
|
||||||
#define MOUNTED_LOCK _PATH_MOUNTED "~" /* mounts' lock file */
|
|
||||||
#define MTAB_NOTUPDATED 0x1000 /* mtab succeded but not updated */
|
|
||||||
#define NOT_MOUNTED 0x0100 /* path notmounted */
|
|
||||||
+#define MNT_FORCE_FAIL -1
|
|
||||||
#define _PROC_MOUNTS "/proc/mounts"
|
|
||||||
|
|
||||||
/* Constants for lookup modules */
|
|
||||||
diff -up autofs-5.0.2/modules/mount_bind.c.check-mtab-updated autofs-5.0.2/modules/mount_bind.c
|
|
||||||
--- autofs-5.0.2/modules/mount_bind.c.check-mtab-updated 2007-11-20 16:10:58.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/modules/mount_bind.c 2007-11-20 16:11:49.000000000 +0900
|
|
||||||
@@ -147,7 +147,7 @@ int mount_mount(struct autofs_point *ap,
|
|
||||||
if ((!ap->ghost && name_len) || !existed)
|
|
||||||
rmdir_path(ap, fullpath, ap->dev);
|
|
||||||
|
|
||||||
- return 1;
|
|
||||||
+ return err;
|
|
||||||
} else {
|
|
||||||
debug(ap->logopt,
|
|
||||||
MODPREFIX "mounted %s type %s on %s",
|
|
||||||
diff -up autofs-5.0.2/modules/mount_nfs.c.check-mtab-updated autofs-5.0.2/modules/mount_nfs.c
|
|
||||||
--- autofs-5.0.2/modules/mount_nfs.c.check-mtab-updated 2007-11-20 16:11:08.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/modules/mount_nfs.c 2007-11-20 16:12:44.000000000 +0900
|
|
||||||
@@ -233,6 +233,10 @@ int mount_mount(struct autofs_point *ap,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* Failed to update mtab, don't try any more */
|
|
||||||
+ if (err == MNT_FORCE_FAIL)
|
|
||||||
+ goto forced_fail;
|
|
||||||
+
|
|
||||||
/* No hostname, can't be NFS */
|
|
||||||
if (!this->name) {
|
|
||||||
this = this->next;
|
|
||||||
@@ -275,6 +279,7 @@ int mount_mount(struct autofs_point *ap,
|
|
||||||
this = this->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
+forced_fail:
|
|
||||||
free_host_list(&hosts);
|
|
||||||
ap->ghost = save_ghost;
|
|
||||||
|
|
||||||
diff -up autofs-5.0.2/daemon/spawn.c.check-mtab-updated autofs-5.0.2/daemon/spawn.c
|
|
||||||
--- autofs-5.0.2/daemon/spawn.c.check-mtab-updated 2007-11-20 16:06:45.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/daemon/spawn.c 2007-11-20 16:06:45.000000000 +0900
|
|
||||||
@@ -25,6 +25,7 @@
|
|
||||||
#include <time.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
+#include <sys/mount.h>
|
|
||||||
|
|
||||||
#include "automount.h"
|
|
||||||
|
|
||||||
@@ -268,9 +269,11 @@ int spawn_mount(unsigned logopt, ...)
|
|
||||||
char **argv, **p;
|
|
||||||
char prog[] = PATH_MOUNT;
|
|
||||||
char arg0[] = PATH_MOUNT;
|
|
||||||
+ /* In case we need to use the fake option to mount */
|
|
||||||
+ char arg_fake[] = "-f";
|
|
||||||
unsigned int options;
|
|
||||||
unsigned int retries = MTAB_LOCK_RETRIES;
|
|
||||||
- int ret;
|
|
||||||
+ int ret, printed = 0;
|
|
||||||
|
|
||||||
/* If we use mount locking we can't validate the location */
|
|
||||||
#ifdef ENABLE_MOUNT_LOCKING
|
|
||||||
@@ -283,7 +286,8 @@ int spawn_mount(unsigned logopt, ...)
|
|
||||||
for (argc = 1; va_arg(arg, char *); argc++);
|
|
||||||
va_end(arg);
|
|
||||||
|
|
||||||
- if (!(argv = alloca(sizeof(char *) * argc + 1)))
|
|
||||||
+ /* Alloc 1 extra slot in case we need to use the "-f" option */
|
|
||||||
+ if (!(argv = alloca(sizeof(char *) * argc + 2)))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
argv[0] = arg0;
|
|
||||||
@@ -304,11 +308,52 @@ int spawn_mount(unsigned logopt, ...)
|
|
||||||
|
|
||||||
while (retries--) {
|
|
||||||
ret = do_spawn(logopt, options, prog, (const char **) argv);
|
|
||||||
- if (ret & MTAB_NOTUPDATED)
|
|
||||||
+ if (ret & MTAB_NOTUPDATED) {
|
|
||||||
+ struct timespec tm = {3, 0};
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * If the mount succeeded but the mtab was not
|
|
||||||
+ * updated, then retry the mount with the -f (fake)
|
|
||||||
+ * option to just update the mtab.
|
|
||||||
+ */
|
|
||||||
+ if (!printed) {
|
|
||||||
+ debug(logopt, "mount failed with error code 16"
|
|
||||||
+ ", retrying with the -f option");
|
|
||||||
+ printed = 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Move the last two args so do_spawn() can find the
|
|
||||||
+ * mount target.
|
|
||||||
+ */
|
|
||||||
+ if (!argv[argc]) {
|
|
||||||
+ argv[argc + 1] = NULL;
|
|
||||||
+ argv[argc] = argv[argc - 1];
|
|
||||||
+ argv[argc - 1] = argv[argc - 2];
|
|
||||||
+ argv[argc - 2] = arg_fake;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ nanosleep(&tm, NULL);
|
|
||||||
+
|
|
||||||
continue;
|
|
||||||
+ }
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* This is not a fatal error */
|
|
||||||
+ if (ret == MTAB_NOTUPDATED) {
|
|
||||||
+ /*
|
|
||||||
+ * Version 5 requires that /etc/mtab be in sync with
|
|
||||||
+ * /proc/mounts. If we're unable to update matb after
|
|
||||||
+ * retrying then we have no choice but umount the mount
|
|
||||||
+ * and return a fail.
|
|
||||||
+ */
|
|
||||||
+ warn(logopt,
|
|
||||||
+ "Unable to update the mtab file, forcing mount fail!");
|
|
||||||
+ umount(argv[argc]);
|
|
||||||
+ ret = MNT_FORCE_FAIL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -328,9 +373,11 @@ int spawn_bind_mount(unsigned logopt, ..
|
|
||||||
char prog[] = PATH_MOUNT;
|
|
||||||
char arg0[] = PATH_MOUNT;
|
|
||||||
char bind[] = "--bind";
|
|
||||||
+ /* In case we need to use the fake option to mount */
|
|
||||||
+ char arg_fake[] = "-f";
|
|
||||||
unsigned int options;
|
|
||||||
unsigned int retries = MTAB_LOCK_RETRIES;
|
|
||||||
- int ret;
|
|
||||||
+ int ret, printed = 0;
|
|
||||||
|
|
||||||
/* If we use mount locking we can't validate the location */
|
|
||||||
#ifdef ENABLE_MOUNT_LOCKING
|
|
||||||
@@ -339,8 +386,12 @@ int spawn_bind_mount(unsigned logopt, ..
|
|
||||||
options = SPAWN_OPT_ACCESS;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * Alloc 2 extra slots, one for the bind option and one in case
|
|
||||||
+ * we need to use the "-f" option
|
|
||||||
+ */
|
|
||||||
va_start(arg, logopt);
|
|
||||||
- for (argc = 1; va_arg(arg, char *); argc++);
|
|
||||||
+ for (argc = 2; va_arg(arg, char *); argc++);
|
|
||||||
va_end(arg);
|
|
||||||
|
|
||||||
if (!(argv = alloca(sizeof(char *) * argc + 2)))
|
|
||||||
@@ -356,11 +407,52 @@ int spawn_bind_mount(unsigned logopt, ..
|
|
||||||
|
|
||||||
while (retries--) {
|
|
||||||
ret = do_spawn(logopt, options, prog, (const char **) argv);
|
|
||||||
- if (ret & MTAB_NOTUPDATED)
|
|
||||||
+ if (ret & MTAB_NOTUPDATED) {
|
|
||||||
+ struct timespec tm = {3, 0};
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * If the mount succeeded but the mtab was not
|
|
||||||
+ * updated, then retry the mount with the -f (fake)
|
|
||||||
+ * option to just update the mtab.
|
|
||||||
+ */
|
|
||||||
+ if (!printed) {
|
|
||||||
+ debug(logopt, "mount failed with error code 16"
|
|
||||||
+ ", retrying with the -f option");
|
|
||||||
+ printed = 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Move the last two args so do_spawn() can find the
|
|
||||||
+ * mount target.
|
|
||||||
+ */
|
|
||||||
+ if (!argv[argc]) {
|
|
||||||
+ argv[argc + 1] = NULL;
|
|
||||||
+ argv[argc] = argv[argc - 1];
|
|
||||||
+ argv[argc - 1] = argv[argc - 2];
|
|
||||||
+ argv[argc - 2] = arg_fake;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ nanosleep(&tm, NULL);
|
|
||||||
+
|
|
||||||
continue;
|
|
||||||
+ }
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* This is not a fatal error */
|
|
||||||
+ if (ret == MTAB_NOTUPDATED) {
|
|
||||||
+ /*
|
|
||||||
+ * Version 5 requires that /etc/mtab be in sync with
|
|
||||||
+ * /proc/mounts. If we're unable to update matb after
|
|
||||||
+ * retrying then we have no choice but umount the mount
|
|
||||||
+ * and return a fail.
|
|
||||||
+ */
|
|
||||||
+ warn(logopt,
|
|
||||||
+ "Unable to update the mtab file, forcing mount fail!");
|
|
||||||
+ umount(argv[argc]);
|
|
||||||
+ ret = MNT_FORCE_FAIL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -373,7 +465,7 @@ int spawn_umount(unsigned logopt, ...)
|
|
||||||
char arg0[] = PATH_UMOUNT;
|
|
||||||
unsigned int options;
|
|
||||||
unsigned int retries = MTAB_LOCK_RETRIES;
|
|
||||||
- int ret;
|
|
||||||
+ int ret, printed = 0;
|
|
||||||
|
|
||||||
#ifdef ENABLE_MOUNT_LOCKING
|
|
||||||
options = SPAWN_OPT_LOCK;
|
|
||||||
@@ -397,9 +489,37 @@ int spawn_umount(unsigned logopt, ...)
|
|
||||||
|
|
||||||
while (retries--) {
|
|
||||||
ret = do_spawn(logopt, options, prog, (const char **) argv);
|
|
||||||
- if (ret & MTAB_NOTUPDATED)
|
|
||||||
- continue;
|
|
||||||
- break;
|
|
||||||
+ if (ret & MTAB_NOTUPDATED) {
|
|
||||||
+ /*
|
|
||||||
+ * If the mount succeeded but the mtab was not
|
|
||||||
+ * updated, then retry the umount just to update
|
|
||||||
+ * the mtab.
|
|
||||||
+ */
|
|
||||||
+ if (!printed) {
|
|
||||||
+ debug(logopt, "mount failed with error code 16"
|
|
||||||
+ ", retrying with the -f option");
|
|
||||||
+ printed = 1;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ /*
|
|
||||||
+ * umount does not support the "fake" option. Thus,
|
|
||||||
+ * if we got a return value of MTAB_NOTUPDATED the
|
|
||||||
+ * first time, that means the umount actually
|
|
||||||
+ * succeeded. Then, a following umount will fail
|
|
||||||
+ * due to the fact that nothing was mounted on the
|
|
||||||
+ * mount point. So, report this as success.
|
|
||||||
+ */
|
|
||||||
+ if (retries < MTAB_LOCK_RETRIES - 1)
|
|
||||||
+ ret = 0;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* This is not a fatal error */
|
|
||||||
+ if (ret == MTAB_NOTUPDATED) {
|
|
||||||
+ warn(logopt, "Unable to update the mtab file, /proc/mounts "
|
|
||||||
+ "and /etc/mtab will differ");
|
|
||||||
+ ret = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
@ -1,35 +0,0 @@
|
|||||||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|
||||||
index 3e40428..294c511 100644
|
|
||||||
--- a/daemon/automount.c
|
|
||||||
+++ b/daemon/automount.c
|
|
||||||
@@ -1367,7 +1367,7 @@ static void usage(void)
|
|
||||||
" -d --debug log debuging info\n"
|
|
||||||
" -D --define define global macro variable\n"
|
|
||||||
/*" -f --foreground do not fork into background\n" */
|
|
||||||
- " -r --random-replicated-selection\n"
|
|
||||||
+ " -r --random-multimount-selection\n"
|
|
||||||
" use ramdom replicated server selection\n"
|
|
||||||
" -O --global-options\n"
|
|
||||||
" specify global mount options\n"
|
|
||||||
@@ -1469,7 +1469,7 @@ int main(int argc, char *argv[])
|
|
||||||
{"debug", 0, 0, 'd'},
|
|
||||||
{"define", 1, 0, 'D'},
|
|
||||||
{"foreground", 0, 0, 'f'},
|
|
||||||
- {"random-selection", 0, 0, 'r'},
|
|
||||||
+ {"random-multimount-selection", 0, 0, 'r'},
|
|
||||||
{"global-options", 1, 0, 'O'},
|
|
||||||
{"version", 0, 0, 'V'},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
diff --git a/man/automount.8 b/man/automount.8
|
|
||||||
index b01be83..fc1846a 100644
|
|
||||||
--- a/man/automount.8
|
|
||||||
+++ b/man/automount.8
|
|
||||||
@@ -47,7 +47,7 @@ Define a global macro substitution variable. Global definitions
|
|
||||||
are over-ridden macro definitions of the same name specified in
|
|
||||||
mount entries.
|
|
||||||
.TP
|
|
||||||
-.I "\-r, \-\-random-replicated-selection"
|
|
||||||
+.I "\-r, \-\-random-multimount-selection"
|
|
||||||
Enables the use of ramdom selection when choosing a host from a
|
|
||||||
list of replicated servers.
|
|
||||||
.TP
|
|
@ -1,51 +0,0 @@
|
|||||||
diff --git a/lib/nss_parse.y b/lib/nss_parse.y
|
|
||||||
index 4f67f08..e559696 100644
|
|
||||||
--- a/lib/nss_parse.y
|
|
||||||
+++ b/lib/nss_parse.y
|
|
||||||
@@ -45,6 +45,8 @@ struct nss_action act[NSS_STATUS_MAX];
|
|
||||||
#define YYLTYPE_IS_TRIVIAL 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+unsigned int nss_automount_found;
|
|
||||||
+
|
|
||||||
extern int nss_lineno;
|
|
||||||
extern int nss_lex(void);
|
|
||||||
extern FILE *nss_in;
|
|
||||||
@@ -183,10 +185,16 @@ int nsswitch_parse(struct list_head *list)
|
|
||||||
|
|
||||||
nss_in = nsswitch;
|
|
||||||
|
|
||||||
+ nss_automount_found = 0;
|
|
||||||
nss_list = list;
|
|
||||||
status = nss_parse();
|
|
||||||
nss_list = NULL;
|
|
||||||
|
|
||||||
+ /* No "automount" nsswitch entry, use "files" */
|
|
||||||
+ if (!nss_automount_found)
|
|
||||||
+ if (add_source(list, "files"))
|
|
||||||
+ status = 0;
|
|
||||||
+
|
|
||||||
pthread_cleanup_pop(1);
|
|
||||||
pthread_cleanup_pop(1);
|
|
||||||
|
|
||||||
diff --git a/lib/nss_tok.l b/lib/nss_tok.l
|
|
||||||
index 71d83b0..f96b47f 100644
|
|
||||||
--- a/lib/nss_tok.l
|
|
||||||
+++ b/lib/nss_tok.l
|
|
||||||
@@ -56,6 +56,8 @@ int nss_wrap(void);
|
|
||||||
#define YY_MAIN 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+extern unsigned int nss_automount_found;
|
|
||||||
+
|
|
||||||
%}
|
|
||||||
|
|
||||||
%option nounput
|
|
||||||
@@ -85,6 +87,7 @@ other [[:alnum:]@$%^&*()-+_":;?,<>./'{}~`]+
|
|
||||||
%%
|
|
||||||
|
|
||||||
^{automount}: {
|
|
||||||
+ nss_automount_found = 1;
|
|
||||||
BEGIN(AUTOMOUNT);
|
|
||||||
}
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
|||||||
diff -u b/lib/master.c b/lib/master.c
|
|
||||||
--- b/lib/master.c
|
|
||||||
+++ b/lib/master.c
|
|
||||||
@@ -802,8 +802,8 @@
|
|
||||||
|
|
||||||
if (list_empty(&master->mounts)) {
|
|
||||||
master_mutex_unlock();
|
|
||||||
- error(LOGOPT_ANY, "no mounts in table");
|
|
||||||
- return 0;
|
|
||||||
+ warn(LOGOPT_ANY, "no mounts in table");
|
|
||||||
+ return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
master_mutex_unlock();
|
|
||||||
--- a/daemon/automount.c
|
|
||||||
+++ b/daemon/automount.c
|
|
||||||
@@ -61,6 +61,8 @@ static size_t kpkt_len;
|
|
||||||
|
|
||||||
/* Attribute to create detached thread */
|
|
||||||
pthread_attr_t thread_attr;
|
|
||||||
+/* Attribute to create normal thread */
|
|
||||||
+pthread_attr_t thread_attr_nodetach;
|
|
||||||
|
|
||||||
struct master_readmap_cond mrc = {
|
|
||||||
PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, NULL, 0, 0, 0, 0};
|
|
||||||
@@ -914,7 +916,7 @@ static void *do_notify_state(void *arg)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int do_signals(struct master *master, int sig)
|
|
||||||
+static pthread_t do_signals(struct master *master, int sig)
|
|
||||||
{
|
|
||||||
pthread_t thid;
|
|
||||||
int r_sig = sig;
|
|
||||||
@@ -924,7 +926,7 @@ static int do_signals(struct master *master, int sig)
|
|
||||||
if (status)
|
|
||||||
fatal(status);
|
|
||||||
|
|
||||||
- status = pthread_create(&thid, &thread_attr, do_notify_state, &r_sig);
|
|
||||||
+ status = pthread_create(&thid, &thread_attr_nodetach, do_notify_state, &r_sig);
|
|
||||||
if (status) {
|
|
||||||
error(master->default_logging,
|
|
||||||
"mount state notify thread create failed");
|
|
||||||
@@ -948,7 +950,7 @@ static int do_signals(struct master *master, int sig)
|
|
||||||
|
|
||||||
pthread_cleanup_pop(1);
|
|
||||||
|
|
||||||
- return 1;
|
|
||||||
+ return thid;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *do_read_master(void *arg)
|
|
||||||
@@ -1038,6 +1040,7 @@ static int do_hup_signal(struct master *master, time_t age)
|
|
||||||
/* Deal with all the signal-driven events in the state machine */
|
|
||||||
static void *statemachine(void *arg)
|
|
||||||
{
|
|
||||||
+ pthread_t thid = 0;
|
|
||||||
sigset_t signalset;
|
|
||||||
int sig;
|
|
||||||
|
|
||||||
@@ -1048,15 +1051,17 @@ static void *statemachine(void *arg)
|
|
||||||
while (1) {
|
|
||||||
sigwait(&signalset, &sig);
|
|
||||||
|
|
||||||
-
|
|
||||||
- if (master_list_empty(master_list))
|
|
||||||
- return NULL;
|
|
||||||
-
|
|
||||||
switch (sig) {
|
|
||||||
case SIGTERM:
|
|
||||||
case SIGUSR2:
|
|
||||||
case SIGUSR1:
|
|
||||||
- do_signals(master_list, sig);
|
|
||||||
+ thid = do_signals(master_list, sig);
|
|
||||||
+ if (thid) {
|
|
||||||
+ pthread_join(thid, NULL);
|
|
||||||
+ if (master_list_empty(master_list))
|
|
||||||
+ return NULL;
|
|
||||||
+ thid = 0;
|
|
||||||
+ }
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SIGHUP:
|
|
||||||
@@ -1171,10 +1176,6 @@ static void handle_mounts_cleanup(void *arg)
|
|
||||||
|
|
||||||
msg("shut down path %s", path);
|
|
||||||
|
|
||||||
- /* If we are the last tell the state machine to shutdown */
|
|
||||||
- if (!submount && master_list_empty(master_list))
|
|
||||||
- kill(getpid(), SIGTERM);
|
|
||||||
-
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1644,6 +1645,14 @@ int main(int argc, char *argv[])
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+ if (pthread_attr_init(&thread_attr_nodetach)) {
|
|
||||||
+ crit(LOGOPT_ANY,
|
|
||||||
+ "%s: failed to init thread attribute struct!",
|
|
||||||
+ program);
|
|
||||||
+ close(start_pipefd[1]);
|
|
||||||
+ exit(1);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
msg("Starting automounter version %s, master map %s",
|
|
||||||
version, master_list->name);
|
|
||||||
msg("using kernel protocol version %d.%02d",
|
|
@ -1,385 +0,0 @@
|
|||||||
diff --git a/Makefile.conf.in b/Makefile.conf.in
|
|
||||||
index ea5fe1d..09c3129 100644
|
|
||||||
--- a/Makefile.conf.in
|
|
||||||
+++ b/Makefile.conf.in
|
|
||||||
@@ -71,6 +71,9 @@ autofsconfdir = @confdir@
|
|
||||||
# Location for autofs maps
|
|
||||||
autofsmapdir = @mapdir@
|
|
||||||
|
|
||||||
+# Location for autofs fifos
|
|
||||||
+autofsfifodir = @fifodir@
|
|
||||||
+
|
|
||||||
# Where to install the automount program
|
|
||||||
sbindir = @sbindir@
|
|
||||||
|
|
||||||
diff --git a/aclocal.m4 b/aclocal.m4
|
|
||||||
index ffeb232..118ef0d 100644
|
|
||||||
--- a/aclocal.m4
|
|
||||||
+++ b/aclocal.m4
|
|
||||||
@@ -120,6 +120,22 @@ AC_DEFUN(AF_MAP_D,
|
|
||||||
done
|
|
||||||
fi])
|
|
||||||
|
|
||||||
+dnl --------------------------------------------------------------------------
|
|
||||||
+dnl AF_FIFO_D
|
|
||||||
+dnl
|
|
||||||
+dnl Check the location of the autofs fifos directory
|
|
||||||
+dnl --------------------------------------------------------------------------
|
|
||||||
+AC_DEFUN(AF_FIFO_D,
|
|
||||||
+[if test -z "$fifodir"; then
|
|
||||||
+ for fifo_d in /var/run /tmp; do
|
|
||||||
+ if test -z "$fifodir"; then
|
|
||||||
+ if test -d "$fifo_d"; then
|
|
||||||
+ fifodir="$fifo_d"
|
|
||||||
+ fi
|
|
||||||
+ fi
|
|
||||||
+ done
|
|
||||||
+fi])
|
|
||||||
+
|
|
||||||
dnl ----------------------------------- ## -*- Autoconf -*-
|
|
||||||
dnl Check if --with-dmalloc was given. ##
|
|
||||||
dnl From Franc,ois Pinard ##
|
|
||||||
diff --git a/configure b/configure
|
|
||||||
index 3508224..0360086 100755
|
|
||||||
--- a/configure
|
|
||||||
+++ b/configure
|
|
||||||
@@ -654,6 +654,7 @@ target_alias
|
|
||||||
initdir
|
|
||||||
confdir
|
|
||||||
mapdir
|
|
||||||
+fifodir
|
|
||||||
DMALLOCLIB
|
|
||||||
MOUNT
|
|
||||||
HAVE_MOUNT
|
|
||||||
@@ -1293,6 +1294,7 @@ Optional Packages:
|
|
||||||
--with-path=PATH look in PATH for binaries needed by the automounter
|
|
||||||
--with-confdir=DIR use DIR for autofs configuration files
|
|
||||||
--with-mapdir=PATH look in PATH for mount maps used by the automounter
|
|
||||||
+ --with-fifodir=PATH use PATH as the directory for fifos used by the automounter
|
|
||||||
--with-dmalloc use dmalloc, as in
|
|
||||||
http://www.dmalloc.com/dmalloc.tar.gz
|
|
||||||
--with-hesiod=DIR enable Hesiod support (libs and includes in DIR)
|
|
||||||
@@ -1844,6 +1846,36 @@ echo "${ECHO_T}$mapdir" >&6; }
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
+# The user can specify --with-fifodir=PATH to specify where autofs fifos go
|
|
||||||
+#
|
|
||||||
+if test -z "$fifodir"; then
|
|
||||||
+ for fifo_d in /var/run /tmp; do
|
|
||||||
+ if test -z "$fifodir"; then
|
|
||||||
+ if test -d "$fifo_d"; then
|
|
||||||
+ fifodir="$fifo_d"
|
|
||||||
+ fi
|
|
||||||
+ fi
|
|
||||||
+ done
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
+# Check whether --with-fifodir was given.
|
|
||||||
+if test "${with_fifodir+set}" = set; then
|
|
||||||
+ withval=$with_fifodir; if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no"
|
|
||||||
+ then
|
|
||||||
+ :
|
|
||||||
+ else
|
|
||||||
+ fifodir="${withval}"
|
|
||||||
+ fi
|
|
||||||
+
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
+{ echo "$as_me:$LINENO: checking for autofs fifos directory" >&5
|
|
||||||
+echo $ECHO_N "checking for autofs fifos directory... $ECHO_C" >&6; }
|
|
||||||
+{ echo "$as_me:$LINENO: result: $fifodir" >&5
|
|
||||||
+echo "${ECHO_T}$fifodir" >&6; }
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
# Optional include dmalloc
|
|
||||||
#
|
|
||||||
{ echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5
|
|
||||||
@@ -6074,6 +6106,7 @@ target_alias!$target_alias$ac_delim
|
|
||||||
initdir!$initdir$ac_delim
|
|
||||||
confdir!$confdir$ac_delim
|
|
||||||
mapdir!$mapdir$ac_delim
|
|
||||||
+fifodir!$fifodir$ac_delim
|
|
||||||
DMALLOCLIB!$DMALLOCLIB$ac_delim
|
|
||||||
MOUNT!$MOUNT$ac_delim
|
|
||||||
HAVE_MOUNT!$HAVE_MOUNT$ac_delim
|
|
||||||
@@ -6124,7 +6157,7 @@ LIBOBJS!$LIBOBJS$ac_delim
|
|
||||||
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
|
||||||
_ACEOF
|
|
||||||
|
|
||||||
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 88; then
|
|
||||||
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 89; then
|
|
||||||
break
|
|
||||||
elif $ac_last_try; then
|
|
||||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
|
||||||
diff --git a/configure.in b/configure.in
|
|
||||||
index 8cddf90..a83b3f1 100644
|
|
||||||
--- a/configure.in
|
|
||||||
+++ b/configure.in
|
|
||||||
@@ -79,6 +79,23 @@ AC_MSG_RESULT([$mapdir])
|
|
||||||
AC_SUBST(mapdir)
|
|
||||||
|
|
||||||
#
|
|
||||||
+# The user can specify --with-fifodir=PATH to specify where autofs fifos go
|
|
||||||
+#
|
|
||||||
+AF_FIFO_D()
|
|
||||||
+AC_ARG_WITH(fifodir,
|
|
||||||
+[ --with-fifodir=PATH use PATH as the directory for fifos used by the automounter],
|
|
||||||
+ if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no"
|
|
||||||
+ then
|
|
||||||
+ :
|
|
||||||
+ else
|
|
||||||
+ fifodir="${withval}"
|
|
||||||
+ fi
|
|
||||||
+)
|
|
||||||
+AC_MSG_CHECKING([for autofs fifos directory])
|
|
||||||
+AC_MSG_RESULT([$fifodir])
|
|
||||||
+AC_SUBST(fifodir)
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
# Optional include dmalloc
|
|
||||||
#
|
|
||||||
AM_WITH_DMALLOC()
|
|
||||||
diff --git a/daemon/Makefile b/daemon/Makefile
|
|
||||||
index 4ee70eb..528a684 100644
|
|
||||||
--- a/daemon/Makefile
|
|
||||||
+++ b/daemon/Makefile
|
|
||||||
@@ -16,6 +16,7 @@ CFLAGS += -rdynamic $(DAEMON_CFLAGS) -D_GNU_SOURCE -I../include
|
|
||||||
CFLAGS += -DAUTOFS_LIB_DIR=\"$(autofslibdir)\"
|
|
||||||
CFLAGS += -DAUTOFS_MAP_DIR=\"$(autofsmapdir)\"
|
|
||||||
CFLAGS += -DAUTOFS_CONF_DIR=\"$(autofsconfdir)\"
|
|
||||||
+CFLAGS += -DAUTOFS_FIFO_DIR=\"$(autofsfifodir)\"
|
|
||||||
CFLAGS += -DVERSION_STRING=\"$(version)\"
|
|
||||||
LDFLAGS += -rdynamic
|
|
||||||
LIBS = -ldl
|
|
||||||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|
||||||
index 7e7d1e6..a12b6da 100644
|
|
||||||
--- a/daemon/automount.c
|
|
||||||
+++ b/daemon/automount.c
|
|
||||||
@@ -50,6 +50,9 @@ const char *libdir = AUTOFS_LIB_DIR; /* Location of library modules */
|
|
||||||
const char *mapdir = AUTOFS_MAP_DIR; /* Location of mount maps */
|
|
||||||
const char *confdir = AUTOFS_CONF_DIR; /* Location of autofs config file */
|
|
||||||
|
|
||||||
+/* autofs fifo name prefix */
|
|
||||||
+const char *fifodir = AUTOFS_FIFO_DIR "/autofs.fifo";
|
|
||||||
+
|
|
||||||
const char *global_options; /* Global option, from command line */
|
|
||||||
|
|
||||||
static char *pid_file = NULL; /* File in which to keep pid */
|
|
||||||
@@ -650,14 +653,13 @@ static int fullread(int fd, void *ptr, size_t len)
|
|
||||||
static char *automount_path_to_fifo(unsigned logopt, const char *path)
|
|
||||||
{
|
|
||||||
char *fifo_name, *p;
|
|
||||||
- int name_len = strlen(path) + strlen(AUTOFS_LOGPRI_FIFO) + 1;
|
|
||||||
+ int name_len = strlen(path) + strlen(fifodir) + 1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
fifo_name = malloc(name_len);
|
|
||||||
if (!fifo_name)
|
|
||||||
return NULL;
|
|
||||||
- ret = snprintf(fifo_name, name_len, "%s%s",
|
|
||||||
- AUTOFS_LOGPRI_FIFO, path);
|
|
||||||
+ ret = snprintf(fifo_name, name_len, "%s%s", fifodir, path);
|
|
||||||
if (ret >= name_len) {
|
|
||||||
info(logopt,
|
|
||||||
"fifo path for \"%s\" truncated to \"%s\". This may "
|
|
||||||
@@ -670,7 +672,7 @@ static char *automount_path_to_fifo(unsigned logopt, const char *path)
|
|
||||||
* create the fifo name, we will just replace instances of '/' with
|
|
||||||
* '-'.
|
|
||||||
*/
|
|
||||||
- p = fifo_name + strlen(AUTOFS_LOGPRI_FIFO);
|
|
||||||
+ p = fifo_name + strlen(fifodir);
|
|
||||||
while (*p != '\0') {
|
|
||||||
if (*p == '/')
|
|
||||||
*p = '-';
|
|
||||||
@@ -685,8 +687,9 @@ static char *automount_path_to_fifo(unsigned logopt, const char *path)
|
|
||||||
static int create_logpri_fifo(struct autofs_point *ap)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
- int fd;
|
|
||||||
+ int fd, cl_flags;
|
|
||||||
char *fifo_name;
|
|
||||||
+ char buf[MAX_ERR_BUF];
|
|
||||||
|
|
||||||
fifo_name = automount_path_to_fifo(ap->logopt, ap->path);
|
|
||||||
if (!fifo_name) {
|
|
||||||
@@ -704,18 +707,27 @@ static int create_logpri_fifo(struct autofs_point *ap)
|
|
||||||
|
|
||||||
ret = mkfifo(fifo_name, S_IRUSR|S_IWUSR);
|
|
||||||
if (ret != 0) {
|
|
||||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
crit(ap->logopt,
|
|
||||||
- "mkfifo for %s returned %d", fifo_name, errno);
|
|
||||||
+ "mkfifo for %s failed: %s", fifo_name, estr);
|
|
||||||
goto out_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = open(fifo_name, O_RDWR|O_NONBLOCK);
|
|
||||||
if (fd < 0) {
|
|
||||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
crit(ap->logopt,
|
|
||||||
- "Failed to open %s, errno %d", fifo_name, errno);
|
|
||||||
+ "Failed to open %s: %s", fifo_name, estr);
|
|
||||||
+ unlink(fifo_name);
|
|
||||||
+ ret = -1;
|
|
||||||
goto out_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) {
|
|
||||||
+ cl_flags |= FD_CLOEXEC;
|
|
||||||
+ fcntl(fd, F_SETFD, cl_flags);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
ap->logpri_fifo = fd;
|
|
||||||
|
|
||||||
out_free:
|
|
||||||
@@ -728,6 +740,10 @@ static int destroy_logpri_fifo(struct autofs_point *ap)
|
|
||||||
int ret = -1;
|
|
||||||
int fd = ap->logpri_fifo;
|
|
||||||
char *fifo_name;
|
|
||||||
+ char buf[MAX_ERR_BUF];
|
|
||||||
+
|
|
||||||
+ if (fd == -1)
|
|
||||||
+ return 0;
|
|
||||||
|
|
||||||
fifo_name = automount_path_to_fifo(ap->logopt, ap->path);
|
|
||||||
if (!fifo_name) {
|
|
||||||
@@ -739,8 +755,9 @@ static int destroy_logpri_fifo(struct autofs_point *ap)
|
|
||||||
|
|
||||||
ret = close(fd);
|
|
||||||
if (ret != 0) {
|
|
||||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
warn(ap->logopt,
|
|
||||||
- "close for fifo %s returned %d", fifo_name, errno);
|
|
||||||
+ "close for fifo %s: %s", fifo_name, estr);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = unlink(fifo_name);
|
|
||||||
@@ -760,11 +777,13 @@ static void handle_fifo_message(struct autofs_point *ap, int fd)
|
|
||||||
char buffer[PIPE_BUF];
|
|
||||||
char *end;
|
|
||||||
long pri;
|
|
||||||
+ char buf[MAX_ERR_BUF];
|
|
||||||
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
|
||||||
ret = read(fd, &buffer, sizeof(buffer));
|
|
||||||
if (ret < 0) {
|
|
||||||
- warn(ap->logopt, "read on fifo returned error %d", errno);
|
|
||||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
+ warn(ap->logopt, "read on fifo returned error: %s", estr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -846,16 +865,18 @@ static int set_log_priority(const char *path, int priority)
|
|
||||||
*/
|
|
||||||
fd = open(fifo_name, O_WRONLY|O_NONBLOCK);
|
|
||||||
if (fd < 0) {
|
|
||||||
- fprintf(stderr, "%s: open of %s failed with %d\n",
|
|
||||||
- __FUNCTION__, fifo_name, errno);
|
|
||||||
+ fprintf(stderr, "%s: open of %s failed with %s\n",
|
|
||||||
+ __FUNCTION__, fifo_name, strerror(errno));
|
|
||||||
+ fprintf(stderr, "%s: perhaps the fifo wasn't setup,"
|
|
||||||
+ " please check your log for more information\n", __FUNCTION__);
|
|
||||||
free(fifo_name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (write(fd, buf, sizeof(buf)) != sizeof(buf)) {
|
|
||||||
fprintf(stderr, "Failed to change logging priority. ");
|
|
||||||
- fprintf(stderr, "write to fifo failed with errno %d.\n",
|
|
||||||
- errno);
|
|
||||||
+ fprintf(stderr, "write to fifo failed: %s.\n",
|
|
||||||
+ strerror(errno));
|
|
||||||
close(fd);
|
|
||||||
free(fifo_name);
|
|
||||||
return -1;
|
|
||||||
@@ -870,6 +891,7 @@ static int set_log_priority(const char *path, int priority)
|
|
||||||
static int get_pkt(struct autofs_point *ap, union autofs_packet_union *pkt)
|
|
||||||
{
|
|
||||||
struct pollfd fds[3];
|
|
||||||
+ int pollfds = 3;
|
|
||||||
char buf[MAX_ERR_BUF];
|
|
||||||
|
|
||||||
fds[0].fd = ap->pipefd;
|
|
||||||
@@ -878,9 +900,11 @@ static int get_pkt(struct autofs_point *ap, union autofs_packet_union *pkt)
|
|
||||||
fds[1].events = POLLIN;
|
|
||||||
fds[2].fd = ap->logpri_fifo;
|
|
||||||
fds[2].events = POLLIN;
|
|
||||||
+ if (fds[2].fd == -1)
|
|
||||||
+ pollfds--;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
- if (poll(fds, 3, -1) == -1) {
|
|
||||||
+ if (poll(fds, pollfds, -1) == -1) {
|
|
||||||
char *estr;
|
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
@@ -930,7 +954,7 @@ static int get_pkt(struct autofs_point *ap, union autofs_packet_union *pkt)
|
|
||||||
if (fds[0].revents & POLLIN)
|
|
||||||
return fullread(ap->pipefd, pkt, kpkt_len);
|
|
||||||
|
|
||||||
- if (fds[2].revents & POLLIN) {
|
|
||||||
+ if (fds[2].fd != -1 && fds[2].revents & POLLIN) {
|
|
||||||
debug(ap->logopt, "message pending on control fifo.");
|
|
||||||
handle_fifo_message(ap, fds[2].fd);
|
|
||||||
}
|
|
||||||
@@ -983,7 +1007,6 @@ static int autofs_init_ap(struct autofs_point *ap)
|
|
||||||
crit(ap->logopt,
|
|
||||||
"failed to create commumication pipe for autofs path %s",
|
|
||||||
ap->path);
|
|
||||||
- free(ap->path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1006,7 +1029,6 @@ static int autofs_init_ap(struct autofs_point *ap)
|
|
||||||
"failed create state pipe for autofs path %s", ap->path);
|
|
||||||
close(ap->pipefd);
|
|
||||||
close(ap->kpipefd); /* Close kernel pipe end */
|
|
||||||
- free(ap->path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1021,15 +1043,8 @@ static int autofs_init_ap(struct autofs_point *ap)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (create_logpri_fifo(ap) < 0) {
|
|
||||||
- crit(ap->logopt,
|
|
||||||
- "failed to create FIFO for path %s\n", ap->path);
|
|
||||||
- destroy_logpri_fifo(ap);
|
|
||||||
- close(ap->pipefd);
|
|
||||||
- close(ap->kpipefd);
|
|
||||||
- free(ap->path);
|
|
||||||
- close(ap->state_pipe[0]);
|
|
||||||
- close(ap->state_pipe[1]);
|
|
||||||
- return -1;
|
|
||||||
+ logmsg("could not create FIFO for path %s\n", ap->path);
|
|
||||||
+ logmsg("dynamic log level changes not available for %s", ap->path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
diff --git a/include/automount.h b/include/automount.h
|
|
||||||
index 37a3c0a..b0d1a9c 100644
|
|
||||||
--- a/include/automount.h
|
|
||||||
+++ b/include/automount.h
|
|
||||||
@@ -223,8 +223,6 @@ int rmdir_path(struct autofs_point *ap, const char *path, dev_t dev);
|
|
||||||
#define MAPENT_MAX_LEN 4095
|
|
||||||
#define PARSE_MAX_BUF KEY_MAX_LEN + MAPENT_MAX_LEN + 2
|
|
||||||
|
|
||||||
-#define AUTOFS_LOGPRI_FIFO "/tmp/autofs.fifo"
|
|
||||||
-
|
|
||||||
int lookup_nss_read_master(struct master *master, time_t age);
|
|
||||||
int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time_t age);
|
|
||||||
int lookup_enumerate(struct autofs_point *ap,
|
|
||||||
diff --git a/lib/master.c b/lib/master.c
|
|
||||||
index 2e24ad0..2188bca 100644
|
|
||||||
--- a/lib/master.c
|
|
||||||
+++ b/lib/master.c
|
|
||||||
@@ -56,6 +56,7 @@ int master_add_autofs_point(struct master_mapent *entry,
|
|
||||||
|
|
||||||
ap->state_pipe[0] = -1;
|
|
||||||
ap->state_pipe[1] = -1;
|
|
||||||
+ ap->logpri_fifo = -1;
|
|
||||||
|
|
||||||
ap->path = strdup(entry->path);
|
|
||||||
if (!ap->path) {
|
|
@ -1,14 +0,0 @@
|
|||||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
|
||||||
index bad48bb..93a1b40 100644
|
|
||||||
--- a/modules/lookup_ldap.c
|
|
||||||
+++ b/modules/lookup_ldap.c
|
|
||||||
@@ -579,7 +579,9 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
|
|
||||||
list_add_tail(&this->list, ctxt->uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
+#ifdef WITH_SASL
|
|
||||||
autofs_sasl_done(ctxt);
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
/* Current server failed connect, try the rest */
|
|
||||||
ldap = find_server(logopt, ctxt);
|
|
File diff suppressed because it is too large
Load Diff
@ -1,737 +0,0 @@
|
|||||||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|
||||||
index f31ec11..d14f079 100644
|
|
||||||
--- a/daemon/automount.c
|
|
||||||
+++ b/daemon/automount.c
|
|
||||||
@@ -85,6 +85,7 @@ static int umount_all(struct autofs_point *ap, int force);
|
|
||||||
|
|
||||||
extern pthread_mutex_t master_mutex;
|
|
||||||
extern struct master *master_list;
|
|
||||||
+extern pthread_mutex_t fd_mutex;
|
|
||||||
|
|
||||||
static int do_mkdir(const char *parent, const char *path, mode_t mode)
|
|
||||||
{
|
|
||||||
@@ -994,7 +995,7 @@ int do_expire(struct autofs_point *ap, const char *name, int namelen)
|
|
||||||
|
|
||||||
static int autofs_init_ap(struct autofs_point *ap)
|
|
||||||
{
|
|
||||||
- int pipefd[2], cl_flags;
|
|
||||||
+ int pipefd[2], cl_flags, status;
|
|
||||||
|
|
||||||
if ((ap->state != ST_INIT)) {
|
|
||||||
/* This can happen if an autofs process is already running*/
|
|
||||||
@@ -1004,11 +1005,18 @@ static int autofs_init_ap(struct autofs_point *ap)
|
|
||||||
|
|
||||||
ap->pipefd = ap->kpipefd = ap->ioctlfd = -1;
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
/* Pipe for kernel communications */
|
|
||||||
if (pipe(pipefd) < 0) {
|
|
||||||
crit(ap->logopt,
|
|
||||||
"failed to create commumication pipe for autofs path %s",
|
|
||||||
ap->path);
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1031,6 +1039,9 @@ static int autofs_init_ap(struct autofs_point *ap)
|
|
||||||
"failed create state pipe for autofs path %s", ap->path);
|
|
||||||
close(ap->pipefd);
|
|
||||||
close(ap->kpipefd); /* Close kernel pipe end */
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1049,6 +1060,10 @@ static int autofs_init_ap(struct autofs_point *ap)
|
|
||||||
logmsg("dynamic log level changes not available for %s", ap->path);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|
||||||
index 619efce..6e76deb 100644
|
|
||||||
--- a/daemon/direct.c
|
|
||||||
+++ b/daemon/direct.c
|
|
||||||
@@ -53,6 +53,8 @@ pthread_once_t key_mnt_params_once = PTHREAD_ONCE_INIT;
|
|
||||||
static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
+extern pthread_mutex_t fd_mutex;
|
|
||||||
+
|
|
||||||
static void key_mnt_params_destroy(void *arg)
|
|
||||||
{
|
|
||||||
struct mnt_params *mp;
|
|
||||||
@@ -107,7 +109,11 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, stru
|
|
||||||
}
|
|
||||||
ioctlfd = me->ioctlfd;
|
|
||||||
} else {
|
|
||||||
- int cl_flags;
|
|
||||||
+ int cl_flags, status;
|
|
||||||
+
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
|
|
||||||
ioctlfd = open(me->key, O_RDONLY);
|
|
||||||
if (ioctlfd != -1) {
|
|
||||||
@@ -116,6 +122,10 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, stru
|
|
||||||
fcntl(ioctlfd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -309,11 +319,15 @@ int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struc
|
|
||||||
if (tree_get_mnt_list(mnts, &list, me->key, 1)) {
|
|
||||||
if (ap->state == ST_READMAP) {
|
|
||||||
time_t tout = ap->exp_timeout;
|
|
||||||
- int save_ioctlfd, ioctlfd;
|
|
||||||
+ int save_ioctlfd, ioctlfd, status;
|
|
||||||
|
|
||||||
save_ioctlfd = ioctlfd = me->ioctlfd;
|
|
||||||
|
|
||||||
if (ioctlfd == -1) {
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
ioctlfd = open(me->key, O_RDONLY);
|
|
||||||
if (ioctlfd != -1) {
|
|
||||||
cl_flags = fcntl(ioctlfd, F_GETFD, 0);
|
|
||||||
@@ -322,6 +336,11 @@ int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struc
|
|
||||||
fcntl(ioctlfd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioctlfd < 0) {
|
|
||||||
@@ -402,10 +421,17 @@ int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struc
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
/* Root directory for ioctl()'s */
|
|
||||||
ioctlfd = open(me->key, O_RDONLY);
|
|
||||||
if (ioctlfd < 0) {
|
|
||||||
crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
goto out_umount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -414,6 +440,10 @@ int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struc
|
|
||||||
fcntl(ioctlfd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
/* Calculate the timeouts */
|
|
||||||
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
|
|
||||||
|
|
||||||
@@ -548,6 +578,8 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|
||||||
}
|
|
||||||
ioctlfd = me->ioctlfd;
|
|
||||||
} else {
|
|
||||||
+ int status;
|
|
||||||
+
|
|
||||||
/* offset isn't mounted, return success and try to recover */
|
|
||||||
if (!is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) {
|
|
||||||
debug(ap->logopt,
|
|
||||||
@@ -556,6 +588,10 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
ioctlfd = open(me->key, O_RDONLY);
|
|
||||||
if (ioctlfd != -1) {
|
|
||||||
if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) {
|
|
||||||
@@ -563,6 +599,10 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|
||||||
fcntl(ioctlfd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioctlfd >= 0) {
|
|
||||||
@@ -760,10 +800,17 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
/* Root directory for ioctl()'s */
|
|
||||||
ioctlfd = open(me->key, O_RDONLY);
|
|
||||||
if (ioctlfd < 0) {
|
|
||||||
crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
goto out_umount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -772,6 +819,10 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|
||||||
fcntl(ioctlfd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
|
|
||||||
|
|
||||||
ret = fstat(ioctlfd, &st);
|
|
||||||
@@ -1470,6 +1521,10 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
if (me->ioctlfd != -1) {
|
|
||||||
/* Maybe someone did a manual umount, clean up ! */
|
|
||||||
ioctlfd = me->ioctlfd;
|
|
||||||
@@ -1479,6 +1534,9 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
||||||
|
|
||||||
if (ioctlfd == -1) {
|
|
||||||
cache_unlock(mc);
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
pthread_setcancelstate(state, NULL);
|
|
||||||
crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
|
|
||||||
/* TODO: how do we clear wait q in kernel ?? */
|
|
||||||
@@ -1490,6 +1548,10 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
||||||
fcntl(ioctlfd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
debug(ap->logopt, "token %ld, name %s, request pid %u",
|
|
||||||
(unsigned long) pkt->wait_queue_token, me->key, pkt->pid);
|
|
||||||
|
|
||||||
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
|
||||||
index f6b93d0..2b81ec5 100644
|
|
||||||
--- a/daemon/indirect.c
|
|
||||||
+++ b/daemon/indirect.c
|
|
||||||
@@ -43,6 +43,8 @@ extern pthread_attr_t thread_attr;
|
|
||||||
static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
+extern pthread_mutex_t fd_mutex;
|
|
||||||
+
|
|
||||||
static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
|
|
||||||
{
|
|
||||||
struct mnt_list *this;
|
|
||||||
@@ -93,7 +95,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap)
|
|
||||||
const char *type, *map_name = NULL;
|
|
||||||
struct stat st;
|
|
||||||
struct mnt_list *mnts;
|
|
||||||
- int cl_flags, ret;
|
|
||||||
+ int cl_flags, ret, status;
|
|
||||||
|
|
||||||
mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1);
|
|
||||||
if (mnts) {
|
|
||||||
@@ -147,11 +149,18 @@ static int do_mount_autofs_indirect(struct autofs_point *ap)
|
|
||||||
|
|
||||||
options = NULL;
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
/* Root directory for ioctl()'s */
|
|
||||||
ap->ioctlfd = open(ap->path, O_RDONLY);
|
|
||||||
if (ap->ioctlfd < 0) {
|
|
||||||
crit(ap->logopt,
|
|
||||||
"failed to create ioctl fd for autofs path %s", ap->path);
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
goto out_umount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -160,6 +169,10 @@ static int do_mount_autofs_indirect(struct autofs_point *ap)
|
|
||||||
fcntl(ap->ioctlfd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
|
|
||||||
|
|
||||||
ioctl(ap->ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
|
|
||||||
diff --git a/daemon/spawn.c b/daemon/spawn.c
|
|
||||||
index 78d69c6..d096460 100644
|
|
||||||
--- a/daemon/spawn.c
|
|
||||||
+++ b/daemon/spawn.c
|
|
||||||
@@ -29,6 +29,7 @@
|
|
||||||
|
|
||||||
#include "automount.h"
|
|
||||||
|
|
||||||
+pthread_mutex_t fd_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
static pthread_mutex_t spawn_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
#define SPAWN_OPT_NONE 0x0000
|
|
||||||
@@ -123,6 +124,10 @@ static int do_spawn(unsigned logopt, unsigned int options, const char *prog, con
|
|
||||||
egid = tsv->gid;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
f = fork();
|
|
||||||
if (f == 0) {
|
|
||||||
reset_signals();
|
|
||||||
@@ -131,6 +136,10 @@ static int do_spawn(unsigned logopt, unsigned int options, const char *prog, con
|
|
||||||
dup2(pipefd[1], STDERR_FILENO);
|
|
||||||
close(pipefd[1]);
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
/* Bind mount - check target exists */
|
|
||||||
if (use_access) {
|
|
||||||
char **pargv = (char **) argv;
|
|
||||||
@@ -166,6 +175,10 @@ static int do_spawn(unsigned logopt, unsigned int options, const char *prog, con
|
|
||||||
} else {
|
|
||||||
tmpsig = oldsig;
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
sigaddset(&tmpsig, SIGCHLD);
|
|
||||||
pthread_sigmask(SIG_SETMASK, &tmpsig, NULL);
|
|
||||||
|
|
||||||
diff --git a/lib/nss_parse.y b/lib/nss_parse.y
|
|
||||||
index 90b7d25..7fbc42a 100644
|
|
||||||
--- a/lib/nss_parse.y
|
|
||||||
+++ b/lib/nss_parse.y
|
|
||||||
@@ -31,6 +31,7 @@
|
|
||||||
#include "nss_parse.tab.h"
|
|
||||||
|
|
||||||
static pthread_mutex_t parse_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
+extern pthread_mutex_t fd_mutex;
|
|
||||||
|
|
||||||
static struct list_head *nss_list;
|
|
||||||
static struct nss_source *src;
|
|
||||||
@@ -163,16 +164,24 @@ static void parse_close_nsswitch(void *arg)
|
|
||||||
int nsswitch_parse(struct list_head *list)
|
|
||||||
{
|
|
||||||
FILE *nsswitch;
|
|
||||||
- int fd, cl_flags, status;
|
|
||||||
+ int fd, cl_flags, status, cur_state;
|
|
||||||
+
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
||||||
|
|
||||||
nsswitch = fopen(NSSWITCH_FILE, "r");
|
|
||||||
if (!nsswitch) {
|
|
||||||
logerr("couldn't open %s\n", NSSWITCH_FILE);
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+ pthread_setcancelstate(cur_state, NULL);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- pthread_cleanup_push(parse_close_nsswitch, nsswitch);
|
|
||||||
-
|
|
||||||
fd = fileno(nsswitch);
|
|
||||||
|
|
||||||
if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) {
|
|
||||||
@@ -180,9 +189,16 @@ int nsswitch_parse(struct list_head *list)
|
|
||||||
fcntl(fd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
parse_mutex_lock();
|
|
||||||
+ pthread_cleanup_push(parse_close_nsswitch, nsswitch);
|
|
||||||
pthread_cleanup_push(parse_mutex_unlock, NULL);
|
|
||||||
|
|
||||||
+ pthread_setcancelstate(cur_state, NULL);
|
|
||||||
+
|
|
||||||
nss_in = nsswitch;
|
|
||||||
|
|
||||||
nss_automount_found = 0;
|
|
||||||
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
|
|
||||||
index 5797639..5cf7fc3 100644
|
|
||||||
--- a/lib/rpc_subs.c
|
|
||||||
+++ b/lib/rpc_subs.c
|
|
||||||
@@ -54,6 +54,8 @@
|
|
||||||
|
|
||||||
inline void dump_core(void);
|
|
||||||
|
|
||||||
+extern pthread_mutex_t fd_mutex;
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Create a UDP RPC client
|
|
||||||
*/
|
|
||||||
@@ -105,20 +107,31 @@ got_addr:
|
|
||||||
raddr.sin_port = htons(info->port);
|
|
||||||
|
|
||||||
if (!info->client) {
|
|
||||||
+ int status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
/*
|
|
||||||
* bind to any unused port. If we left this up to the rpc
|
|
||||||
* layer, it would bind to a reserved port, which has been shown
|
|
||||||
* to exhaust the reserved port range in some situations.
|
|
||||||
*/
|
|
||||||
fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
- if (fd < 0)
|
|
||||||
+ if (fd < 0) {
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
return NULL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) {
|
|
||||||
cl_flags |= FD_CLOEXEC;
|
|
||||||
fcntl(fd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
laddr.sin_family = AF_INET;
|
|
||||||
laddr.sin_port = 0;
|
|
||||||
laddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
@@ -314,15 +327,27 @@ got_addr:
|
|
||||||
addr.sin_port = htons(info->port);
|
|
||||||
|
|
||||||
if (!info->client) {
|
|
||||||
+ int status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
fd = socket(PF_INET, SOCK_STREAM, info->proto->p_proto);
|
|
||||||
- if (fd < 0)
|
|
||||||
+ if (fd < 0) {
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
return NULL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) {
|
|
||||||
cl_flags |= FD_CLOEXEC;
|
|
||||||
fcntl(fd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
ret = connect_nb(fd, &addr, &info->timeout);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out_close;
|
|
||||||
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
|
|
||||||
index a77068a..4bdd57e 100644
|
|
||||||
--- a/modules/lookup_file.c
|
|
||||||
+++ b/modules/lookup_file.c
|
|
||||||
@@ -36,6 +36,8 @@
|
|
||||||
|
|
||||||
#define MAX_INCLUDE_DEPTH 16
|
|
||||||
|
|
||||||
+extern pthread_mutex_t fd_mutex;
|
|
||||||
+
|
|
||||||
typedef enum {
|
|
||||||
st_begin, st_compare, st_star, st_badent, st_entspc, st_getent
|
|
||||||
} LOOKUP_STATE;
|
|
||||||
@@ -395,7 +397,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
|
||||||
char *ent;
|
|
||||||
struct stat st;
|
|
||||||
FILE *f;
|
|
||||||
- int fd, cl_flags;
|
|
||||||
+ int fd, cl_flags, status;
|
|
||||||
unsigned int path_len, ent_len;
|
|
||||||
int entry, cur_state;
|
|
||||||
|
|
||||||
@@ -422,11 +424,18 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
|
||||||
return NSS_STATUS_UNAVAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
f = fopen(ctxt->mapname, "r");
|
|
||||||
if (!f) {
|
|
||||||
error(logopt,
|
|
||||||
MODPREFIX "could not open master map file %s",
|
|
||||||
ctxt->mapname);
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
return NSS_STATUS_UNAVAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -437,6 +446,10 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
|
||||||
fcntl(fd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
while(1) {
|
|
||||||
entry = read_one(logopt, f, path, &path_len, ent, &ent_len);
|
|
||||||
if (!entry) {
|
|
||||||
@@ -640,7 +653,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
|
||||||
char *mapent;
|
|
||||||
struct stat st;
|
|
||||||
FILE *f;
|
|
||||||
- int fd, cl_flags;
|
|
||||||
+ int fd, cl_flags, status;
|
|
||||||
unsigned int k_len, m_len;
|
|
||||||
int entry;
|
|
||||||
|
|
||||||
@@ -673,10 +686,17 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
|
||||||
return NSS_STATUS_UNAVAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
f = fopen(ctxt->mapname, "r");
|
|
||||||
if (!f) {
|
|
||||||
error(ap->logopt,
|
|
||||||
MODPREFIX "could not open map file %s", ctxt->mapname);
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
return NSS_STATUS_UNAVAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -687,6 +707,10 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
|
||||||
fcntl(fd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
while(1) {
|
|
||||||
entry = read_one(ap->logopt, f, key, &k_len, mapent, &m_len);
|
|
||||||
if (!entry) {
|
|
||||||
@@ -773,7 +797,7 @@ static int lookup_one(struct autofs_point *ap,
|
|
||||||
char mapent[MAPENT_MAX_LEN + 1];
|
|
||||||
time_t age = time(NULL);
|
|
||||||
FILE *f;
|
|
||||||
- int fd, cl_flags;
|
|
||||||
+ int fd, cl_flags, status;
|
|
||||||
unsigned int k_len, m_len;
|
|
||||||
int entry, ret;
|
|
||||||
|
|
||||||
@@ -783,10 +807,17 @@ static int lookup_one(struct autofs_point *ap,
|
|
||||||
|
|
||||||
mc = source->mc;
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
f = fopen(ctxt->mapname, "r");
|
|
||||||
if (!f) {
|
|
||||||
error(ap->logopt,
|
|
||||||
MODPREFIX "could not open map file %s", ctxt->mapname);
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
return CHE_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -797,6 +828,10 @@ static int lookup_one(struct autofs_point *ap,
|
|
||||||
fcntl(fd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
while(1) {
|
|
||||||
entry = read_one(ap->logopt, f, mkey, &k_len, mapent, &m_len);
|
|
||||||
if (entry) {
|
|
||||||
@@ -886,7 +921,7 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt)
|
|
||||||
char mapent[MAPENT_MAX_LEN + 1];
|
|
||||||
time_t age = time(NULL);
|
|
||||||
FILE *f;
|
|
||||||
- int fd, cl_flags;
|
|
||||||
+ int fd, cl_flags, status;
|
|
||||||
unsigned int k_len, m_len;
|
|
||||||
int entry, ret;
|
|
||||||
|
|
||||||
@@ -896,10 +931,17 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt)
|
|
||||||
|
|
||||||
mc = source->mc;
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
f = fopen(ctxt->mapname, "r");
|
|
||||||
if (!f) {
|
|
||||||
error(ap->logopt,
|
|
||||||
MODPREFIX "could not open map file %s", ctxt->mapname);
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
return CHE_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -910,6 +952,10 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt)
|
|
||||||
fcntl(fd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
while(1) {
|
|
||||||
entry = read_one(ap->logopt, f, mkey, &k_len, mapent, &m_len);
|
|
||||||
if (entry) {
|
|
||||||
diff --git a/modules/mount_changer.c b/modules/mount_changer.c
|
|
||||||
index 08d9147..3bec011 100644
|
|
||||||
--- a/modules/mount_changer.c
|
|
||||||
+++ b/modules/mount_changer.c
|
|
||||||
@@ -34,6 +34,8 @@
|
|
||||||
|
|
||||||
#define MODPREFIX "mount(changer): "
|
|
||||||
|
|
||||||
+extern pthread_mutex_t fd_mutex;
|
|
||||||
+
|
|
||||||
int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */
|
|
||||||
|
|
||||||
int swapCD(const char *device, const char *slotName);
|
|
||||||
@@ -158,11 +160,18 @@ int swapCD(const char *device, const char *slotName)
|
|
||||||
|
|
||||||
slot = atoi(slotName) - 1;
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
/* open device */
|
|
||||||
fd = open(device, O_RDONLY | O_NONBLOCK);
|
|
||||||
if (fd < 0) {
|
|
||||||
logerr(MODPREFIX "Opening device %s failed : %s",
|
|
||||||
device, strerror(errno));
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -171,6 +180,10 @@ int swapCD(const char *device, const char *slotName)
|
|
||||||
fcntl(fd, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
/* Check CD player status */
|
|
||||||
total_slots_available = ioctl(fd, CDROM_CHANGER_NSLOTS);
|
|
||||||
if (total_slots_available <= 1) {
|
|
||||||
diff --git a/modules/replicated.c b/modules/replicated.c
|
|
||||||
index 90b2925..21cb9da 100644
|
|
||||||
--- a/modules/replicated.c
|
|
||||||
+++ b/modules/replicated.c
|
|
||||||
@@ -74,6 +74,8 @@
|
|
||||||
#define max(x, y) (x >= y ? x : y)
|
|
||||||
#define mmax(x, y, z) (max(x, y) == x ? max(x, z) : max(y, z))
|
|
||||||
|
|
||||||
+extern pthread_mutex_t fd_mutex;
|
|
||||||
+
|
|
||||||
void seed_random(void)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
@@ -102,7 +104,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
|
|
||||||
char tmp[20], buf[MAX_ERR_BUF], *ptr;
|
|
||||||
struct ifconf ifc;
|
|
||||||
struct ifreq *ifr, nmptr;
|
|
||||||
- int sock, cl_flags, ret, i;
|
|
||||||
+ int sock, cl_flags, ret, i, status;
|
|
||||||
uint32_t mask, ha, ia;
|
|
||||||
|
|
||||||
memcpy(tmp, host_addr, addr_len);
|
|
||||||
@@ -110,10 +112,17 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
|
|
||||||
|
|
||||||
ha = ntohl((uint32_t) hst_addr->s_addr);
|
|
||||||
|
|
||||||
+ status = pthread_mutex_lock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (sock < 0) {
|
|
||||||
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
logerr("socket creation failed: %s", estr);
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
return PROXIMITY_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -122,6 +131,10 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
|
|
||||||
fcntl(sock, F_SETFD, cl_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ status = pthread_mutex_unlock(&fd_mutex);
|
|
||||||
+ if (status)
|
|
||||||
+ fatal(status);
|
|
||||||
+
|
|
||||||
ifc.ifc_len = sizeof(buf);
|
|
||||||
ifc.ifc_req = (struct ifreq *) buf;
|
|
||||||
ret = ioctl(sock, SIOCGIFCONF, &ifc);
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/lib/master_tok.l b/lib/master_tok.l
|
|
||||||
index 9bfeefa..ff69a24 100644
|
|
||||||
--- a/lib/master_tok.l
|
|
||||||
+++ b/lib/master_tok.l
|
|
||||||
@@ -272,7 +272,7 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
|
|
||||||
return DNSERVER;
|
|
||||||
}
|
|
||||||
|
|
||||||
- {DNATTRSTR} {
|
|
||||||
+ {DNATTRSTR}/"=" {
|
|
||||||
strcpy(master_lval.strtype, master_text);
|
|
||||||
return DNATTR;
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/Makefile.rules b/Makefile.rules
|
|
||||||
index b1d1a49..30716dc 100644
|
|
||||||
--- a/Makefile.rules
|
|
||||||
+++ b/Makefile.rules
|
|
||||||
@@ -44,7 +44,7 @@ CXXFLAGS = $(CFLAGS)
|
|
||||||
LD = ld
|
|
||||||
SOLDFLAGS = -shared
|
|
||||||
|
|
||||||
-CFLAGS += -D_REENTRANT
|
|
||||||
+CFLAGS += -D_REENTRANT -D_FILE_OFFSET_BITS=64
|
|
||||||
LDFLAGS += -lpthread
|
|
||||||
|
|
||||||
ifdef DMALLOCLIB
|
|
@ -1,32 +0,0 @@
|
|||||||
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
|
|
||||||
index 98afaa9..69c796e 100644
|
|
||||||
--- a/man/auto.master.5.in
|
|
||||||
+++ b/man/auto.master.5.in
|
|
||||||
@@ -138,6 +138,14 @@ Treat errors when mounting file systems as fatal. This is important when
|
|
||||||
multiple file systems should be mounted (`multimounts'). If this option
|
|
||||||
is given, no file system is mounted at all if at least one file system
|
|
||||||
can't be mounted.
|
|
||||||
+.TP
|
|
||||||
+.I "nosymlink"
|
|
||||||
+This is an autofs specific option that is a pseudo mount option and
|
|
||||||
+so is given without a leading dash. Historically this option was used
|
|
||||||
+to prevent symlinking of local NFS mounts. Nowadays it can be used to
|
|
||||||
+prevent bind mounting of local NFS filesystems as well. If you need to
|
|
||||||
+prevent bind mounting for only specific entrys in a map then this
|
|
||||||
+can be done by adding the "port=" mount option to the given entries.
|
|
||||||
.SH GENERAL SYSTEM DEFAULTS CONFIGURATION
|
|
||||||
.P
|
|
||||||
The default value of several general settings may be changed in the
|
|
||||||
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
|
|
||||||
index 25f72b9..e7a9a8a 100644
|
|
||||||
--- a/modules/mount_nfs.c
|
|
||||||
+++ b/modules/mount_nfs.c
|
|
||||||
@@ -214,7 +214,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
|
|
||||||
port_opt = strstr(nfsoptions, "port=");
|
|
||||||
|
|
||||||
/* Port option specified, don't try to bind */
|
|
||||||
- if (!port_opt && this->proximity == PROXIMITY_LOCAL) {
|
|
||||||
+ if (!nosymlink && !port_opt && this->proximity == PROXIMITY_LOCAL) {
|
|
||||||
/* Local host -- do a "bind" */
|
|
||||||
const char *bind_options = ro ? "ro" : "";
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
diff --git a/modules/replicated.c b/modules/replicated.c
|
|
||||||
index de1b40c..0764d4a 100644
|
|
||||||
--- a/modules/replicated.c
|
|
||||||
+++ b/modules/replicated.c
|
|
||||||
@@ -607,12 +607,31 @@ static int get_supported_ver_and_cost(struct host *host, unsigned int version, c
|
|
||||||
|
|
||||||
parms.pm_prog = NFS_PROGRAM;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * The version passed in is the version as defined in
|
|
||||||
+ * include/replicated.h. However, the version we want to send
|
|
||||||
+ * off to the rpc calls should match the program version of NFS.
|
|
||||||
+ * So, we do the conversion here.
|
|
||||||
+ */
|
|
||||||
if (version & UDP_SELECTED_MASK) {
|
|
||||||
proto = "udp";
|
|
||||||
- vers = (version << 8);
|
|
||||||
- } else {
|
|
||||||
+ version >>= 8;
|
|
||||||
+ } else
|
|
||||||
proto = "tcp";
|
|
||||||
- vers = version;
|
|
||||||
+
|
|
||||||
+ switch (version) {
|
|
||||||
+ case NFS2_SUPPORTED:
|
|
||||||
+ vers = NFS2_VERSION;
|
|
||||||
+ break;
|
|
||||||
+ case NFS3_SUPPORTED:
|
|
||||||
+ vers = NFS3_VERSION;
|
|
||||||
+ break;
|
|
||||||
+ case NFS4_SUPPORTED:
|
|
||||||
+ vers = NFS4_VERSION;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ crit(LOGOPT_ANY, "called with invalid version: 0x%x\n", version);
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rpc_info.proto = getprotobyname(proto);
|
|
@ -1,202 +0,0 @@
|
|||||||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|
||||||
index 294c511..9809b9c 100644
|
|
||||||
--- a/daemon/automount.c
|
|
||||||
+++ b/daemon/automount.c
|
|
||||||
@@ -104,11 +104,14 @@ static int do_mkdir(const char *parent, const char *path, mode_t mode)
|
|
||||||
status = statfs(parent, &fs);
|
|
||||||
if ((status != -1 && fs.f_type == (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) ||
|
|
||||||
contained_in_local_fs(path)) {
|
|
||||||
- if (mkdir(path, mode) == -1)
|
|
||||||
+ if (mkdir(path, mode) == -1) {
|
|
||||||
+ errno = EACCES;
|
|
||||||
return 0;
|
|
||||||
+ }
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ errno = EACCES;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|
||||||
index 179e74b..9a39a6f 100644
|
|
||||||
--- a/daemon/direct.c
|
|
||||||
+++ b/daemon/direct.c
|
|
||||||
@@ -604,6 +604,14 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|
||||||
}
|
|
||||||
ioctlfd = me->ioctlfd;
|
|
||||||
} else {
|
|
||||||
+ /* offset isn't mounted, return success and try to recover */
|
|
||||||
+ if (!is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) {
|
|
||||||
+ debug(ap->logopt,
|
|
||||||
+ "offset %s unexpectedly not mounted",
|
|
||||||
+ me->key);
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
ioctlfd = open(me->key, O_RDONLY);
|
|
||||||
if (ioctlfd != -1) {
|
|
||||||
if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) {
|
|
||||||
@@ -689,11 +697,19 @@ force_umount:
|
|
||||||
} else
|
|
||||||
msg("umounted offset mount %s", me->key);
|
|
||||||
|
|
||||||
+ if (!rv && me->dir_created) {
|
|
||||||
+ if (rmdir(me->key) == -1) {
|
|
||||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
+ warn(ap->logopt, "failed to remove dir %s: %s",
|
|
||||||
+ me->key, estr);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, int is_autofs_fs)
|
|
||||||
+int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|
||||||
{
|
|
||||||
+ char buf[MAX_ERR_BUF];
|
|
||||||
struct mnt_params *mp;
|
|
||||||
time_t timeout = ap->exp_timeout;
|
|
||||||
struct stat st;
|
|
||||||
@@ -740,36 +756,38 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, int is_autof
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (is_autofs_fs) {
|
|
||||||
- /* In case the directory doesn't exist, try to mkdir it */
|
|
||||||
- if (mkdir_path(me->key, 0555) < 0) {
|
|
||||||
- if (errno != EEXIST) {
|
|
||||||
- crit(ap->logopt,
|
|
||||||
- "failed to create mount directory %s %d",
|
|
||||||
- me->key, errno);
|
|
||||||
- return -1;
|
|
||||||
- }
|
|
||||||
+ /* In case the directory doesn't exist, try to mkdir it */
|
|
||||||
+ if (mkdir_path(me->key, 0555) < 0) {
|
|
||||||
+ if (errno == EEXIST) {
|
|
||||||
/*
|
|
||||||
* If we recieve an error, and it's EEXIST
|
|
||||||
* we know the directory was not created.
|
|
||||||
*/
|
|
||||||
me->dir_created = 0;
|
|
||||||
+ } else if (errno == EACCES) {
|
|
||||||
+ /*
|
|
||||||
+ * We require the mount point directory to exist when
|
|
||||||
+ * installing multi-mount triggers into a host
|
|
||||||
+ * filesystem.
|
|
||||||
+ *
|
|
||||||
+ * If it doesn't exist it is not a valid part of the
|
|
||||||
+ * mount heirachy.
|
|
||||||
+ */
|
|
||||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
+ debug(ap->logopt,
|
|
||||||
+ "can't create mount directory: %s, %s",
|
|
||||||
+ me->key, estr);
|
|
||||||
+ return -1;
|
|
||||||
} else {
|
|
||||||
- /* No errors so the directory was successfully created */
|
|
||||||
- me->dir_created = 1;
|
|
||||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
+ crit(ap->logopt,
|
|
||||||
+ "failed to create mount directory: %s, %s",
|
|
||||||
+ me->key, estr);
|
|
||||||
+ return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
- me->dir_created = 0;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * We require the mount point directory to exist when
|
|
||||||
- * installing multi-mount triggers into a host filesystem.
|
|
||||||
- *
|
|
||||||
- * If it doesn't exist it is not a valid part of the
|
|
||||||
- * mount heirachy so we silently succeed here.
|
|
||||||
- */
|
|
||||||
- if (stat(me->key, &st) == -1 && errno == ENOENT)
|
|
||||||
- return 0;
|
|
||||||
+ /* No errors so the directory was successfully created */
|
|
||||||
+ me->dir_created = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug(ap->logopt,
|
|
||||||
@@ -832,10 +850,8 @@ out_close:
|
|
||||||
out_umount:
|
|
||||||
umount(me->key);
|
|
||||||
out_err:
|
|
||||||
- if (is_autofs_fs) {
|
|
||||||
- if (stat(me->key, &st) == 0 && me->dir_created)
|
|
||||||
- rmdir_path(ap, me->key, st.st_dev);
|
|
||||||
- }
|
|
||||||
+ if (stat(me->key, &st) == 0 && me->dir_created)
|
|
||||||
+ rmdir_path(ap, me->key, st.st_dev);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
diff --git a/include/automount.h b/include/automount.h
|
|
||||||
index 106ed0a..d9e4ecd 100644
|
|
||||||
--- a/include/automount.h
|
|
||||||
+++ b/include/automount.h
|
|
||||||
@@ -470,7 +470,7 @@ void *expire_proc_direct(void *);
|
|
||||||
int expire_offsets_direct(struct autofs_point *ap, struct mapent *me, int now);
|
|
||||||
int mount_autofs_indirect(struct autofs_point *ap);
|
|
||||||
int mount_autofs_direct(struct autofs_point *ap);
|
|
||||||
-int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, int is_autofs_fs);
|
|
||||||
+int mount_autofs_offset(struct autofs_point *ap, struct mapent *me);
|
|
||||||
void submount_signal_parent(struct autofs_point *ap, unsigned int success);
|
|
||||||
int umount_autofs(struct autofs_point *ap, int force);
|
|
||||||
int umount_autofs_indirect(struct autofs_point *ap);
|
|
||||||
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
|
|
||||||
index 0c45905..ad19f34 100644
|
|
||||||
--- a/lib/parse_subs.c
|
|
||||||
+++ b/lib/parse_subs.c
|
|
||||||
@@ -388,10 +388,8 @@ int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me,
|
|
||||||
struct mapent *oe;
|
|
||||||
struct list_head *pos = NULL;
|
|
||||||
unsigned int fs_path_len;
|
|
||||||
- struct statfs fs;
|
|
||||||
- struct stat st;
|
|
||||||
- unsigned int mounted, is_autofs_fs;
|
|
||||||
- int ret, start;
|
|
||||||
+ unsigned int mounted;
|
|
||||||
+ int start;
|
|
||||||
|
|
||||||
fs_path_len = strlen(root) + strlen(base);
|
|
||||||
if (fs_path_len > PATH_MAX)
|
|
||||||
@@ -399,15 +397,6 @@ int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me,
|
|
||||||
|
|
||||||
strcpy(path, root);
|
|
||||||
strcat(path, base);
|
|
||||||
- ret = statfs(path, &fs);
|
|
||||||
- if (ret == -1) {
|
|
||||||
- /* There's no mount yet - it must be autofs */
|
|
||||||
- if (errno == ENOENT)
|
|
||||||
- is_autofs_fs = 1;
|
|
||||||
- else
|
|
||||||
- return -1;
|
|
||||||
- } else
|
|
||||||
- is_autofs_fs = fs.f_type == (__SWORD_TYPE) AUTOFS_SUPER_MAGIC ? 1 : 0;
|
|
||||||
|
|
||||||
mounted = 0;
|
|
||||||
start = strlen(root);
|
|
||||||
@@ -424,20 +413,9 @@ int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me,
|
|
||||||
if (!oe)
|
|
||||||
goto cont;
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * If the host filesystem is not an autofs fs
|
|
||||||
- * we require the mount point directory exist
|
|
||||||
- * and that permissions are OK.
|
|
||||||
- */
|
|
||||||
- if (!is_autofs_fs) {
|
|
||||||
- ret = stat(oe->key, &st);
|
|
||||||
- if (ret == -1)
|
|
||||||
- goto cont;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
debug(ap->logopt, "mount offset %s", oe->key);
|
|
||||||
|
|
||||||
- if (mount_autofs_offset(ap, oe, is_autofs_fs) < 0)
|
|
||||||
+ if (mount_autofs_offset(ap, oe) < 0)
|
|
||||||
warn(ap->logopt, "failed to mount offset");
|
|
||||||
else
|
|
||||||
mounted++;
|
|
@ -1,22 +0,0 @@
|
|||||||
diff --git a/daemon/spawn.c b/daemon/spawn.c
|
|
||||||
index 3d5ea56..ab3274c 100644
|
|
||||||
--- a/daemon/spawn.c
|
|
||||||
+++ b/daemon/spawn.c
|
|
||||||
@@ -290,7 +290,16 @@ int spawn_mount(unsigned logopt, ...)
|
|
||||||
|
|
||||||
va_start(arg, logopt);
|
|
||||||
p = argv + 1;
|
|
||||||
- while ((*p++ = va_arg(arg, char *)));
|
|
||||||
+ while ((*p = va_arg(arg, char *))) {
|
|
||||||
+ if (options == SPAWN_OPT_NONE && !strcmp(*p, "-o")) {
|
|
||||||
+ *(++p) = va_arg(arg, char *);
|
|
||||||
+ if (!*p)
|
|
||||||
+ break;
|
|
||||||
+ if (strstr(*p, "loop"))
|
|
||||||
+ options = SPAWN_OPT_ACCESS;
|
|
||||||
+ }
|
|
||||||
+ p++;
|
|
||||||
+ }
|
|
||||||
va_end(arg);
|
|
||||||
|
|
||||||
while (retries--) {
|
|
@ -1,271 +0,0 @@
|
|||||||
diff -up autofs-5.0.2/modules/lookup_ldap.c.foreground-logging autofs-5.0.2/modules/lookup_ldap.c
|
|
||||||
--- autofs-5.0.2/modules/lookup_ldap.c.foreground-logging 2007-09-24 14:42:28.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/modules/lookup_ldap.c 2007-09-24 14:44:18.000000000 +0800
|
|
||||||
@@ -468,17 +468,17 @@ int parse_ldap_config(struct lookup_cont
|
|
||||||
ctxt->client_princ = client_princ;
|
|
||||||
|
|
||||||
debug(LOGOPT_NONE,
|
|
||||||
- "ldap authentication configured with the following options:\n");
|
|
||||||
+ "ldap authentication configured with the following options:");
|
|
||||||
debug(LOGOPT_NONE,
|
|
||||||
"use_tls: %u, "
|
|
||||||
"tls_required: %u, "
|
|
||||||
"auth_required: %u, "
|
|
||||||
- "sasl_mech: %s\n",
|
|
||||||
+ "sasl_mech: %s",
|
|
||||||
use_tls, tls_required, auth_required, authtype);
|
|
||||||
debug(LOGOPT_NONE,
|
|
||||||
"user: %s, "
|
|
||||||
"secret: %s, "
|
|
||||||
- "client principal: %s\n",
|
|
||||||
+ "client principal: %s",
|
|
||||||
user, secret ? "specified" : "unspecified",
|
|
||||||
client_princ);
|
|
||||||
|
|
||||||
diff -up autofs-5.0.2/modules/cyrus-sasl.c.foreground-logging autofs-5.0.2/modules/cyrus-sasl.c
|
|
||||||
--- autofs-5.0.2/modules/cyrus-sasl.c.foreground-logging 2007-06-18 15:18:08.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/modules/cyrus-sasl.c 2007-09-24 14:44:18.000000000 +0800
|
|
||||||
@@ -197,7 +197,7 @@ get_server_SASL_mechanisms(LDAP *ld)
|
|
||||||
if (mechanisms == NULL) {
|
|
||||||
/* Well, that was a waste of time. */
|
|
||||||
msg("No SASL authentication mechanisms are supported"
|
|
||||||
- " by the LDAP server.\n");
|
|
||||||
+ " by the LDAP server.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff -up autofs-5.0.2/daemon/automount.c.foreground-logging autofs-5.0.2/daemon/automount.c
|
|
||||||
--- autofs-5.0.2/daemon/automount.c.foreground-logging 2007-09-24 14:42:28.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/daemon/automount.c 2007-09-24 14:44:18.000000000 +0800
|
|
||||||
@@ -58,14 +58,13 @@ unsigned int random_selection; /* use ra
|
|
||||||
static int start_pipefd[2];
|
|
||||||
static int st_stat = 0;
|
|
||||||
static int *pst_stat = &st_stat;
|
|
||||||
+static pthread_t state_mach_thid;
|
|
||||||
|
|
||||||
/* Pre-calculated kernel packet length */
|
|
||||||
static size_t kpkt_len;
|
|
||||||
|
|
||||||
/* Attribute to create detached thread */
|
|
||||||
pthread_attr_t thread_attr;
|
|
||||||
-/* Attribute to create normal thread */
|
|
||||||
-pthread_attr_t thread_attr_nodetach;
|
|
||||||
|
|
||||||
struct master_readmap_cond mrc = {
|
|
||||||
PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, NULL, 0, 0, 0, 0};
|
|
||||||
@@ -75,9 +74,6 @@ struct startup_cond suc = {
|
|
||||||
|
|
||||||
pthread_key_t key_thread_stdenv_vars;
|
|
||||||
|
|
||||||
-/* re-entrant syslog default context data */
|
|
||||||
-#define AUTOFS_SYSLOG_CONTEXT {-1, 0, 0, LOG_PID, (const char *)0, LOG_DAEMON, 0xff};
|
|
||||||
-
|
|
||||||
#define MAX_OPEN_FILES 10240
|
|
||||||
|
|
||||||
static int umount_all(struct autofs_point *ap, int force);
|
|
||||||
@@ -792,7 +788,6 @@ static void become_daemon(unsigned foreg
|
|
||||||
{
|
|
||||||
FILE *pidfp;
|
|
||||||
char buf[MAX_ERR_BUF];
|
|
||||||
- unsigned to_stderr = 0;
|
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
/* Don't BUSY any directories unnecessarily */
|
|
||||||
@@ -809,7 +804,9 @@ static void become_daemon(unsigned foreg
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Detach from foreground process */
|
|
||||||
- if (!foreground) {
|
|
||||||
+ if (foreground)
|
|
||||||
+ log_to_stderr();
|
|
||||||
+ else {
|
|
||||||
pid = fork();
|
|
||||||
if (pid > 0) {
|
|
||||||
int r;
|
|
||||||
@@ -834,13 +831,8 @@ static void become_daemon(unsigned foreg
|
|
||||||
fprintf(stderr, "setsid: %s", estr);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* Setup logging */
|
|
||||||
- if (to_stderr)
|
|
||||||
- log_to_stderr();
|
|
||||||
- else
|
|
||||||
log_to_syslog();
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* Write pid file if requested */
|
|
||||||
if (pid_file) {
|
|
||||||
@@ -929,7 +921,7 @@ static pthread_t do_signals(struct maste
|
|
||||||
if (status)
|
|
||||||
fatal(status);
|
|
||||||
|
|
||||||
- status = pthread_create(&thid, &thread_attr_nodetach, do_notify_state, &r_sig);
|
|
||||||
+ status = pthread_create(&thid, &thread_attr, do_notify_state, &r_sig);
|
|
||||||
if (status) {
|
|
||||||
error(master->default_logging,
|
|
||||||
"mount state notify thread create failed");
|
|
||||||
@@ -1043,7 +1035,6 @@ static int do_hup_signal(struct master *
|
|
||||||
/* Deal with all the signal-driven events in the state machine */
|
|
||||||
static void *statemachine(void *arg)
|
|
||||||
{
|
|
||||||
- pthread_t thid = 0;
|
|
||||||
sigset_t signalset;
|
|
||||||
int sig;
|
|
||||||
|
|
||||||
@@ -1056,15 +1047,12 @@ static void *statemachine(void *arg)
|
|
||||||
|
|
||||||
switch (sig) {
|
|
||||||
case SIGTERM:
|
|
||||||
+ case SIGINT:
|
|
||||||
case SIGUSR2:
|
|
||||||
+ if (master_list_empty(master_list))
|
|
||||||
+ return NULL;
|
|
||||||
case SIGUSR1:
|
|
||||||
- thid = do_signals(master_list, sig);
|
|
||||||
- if (thid) {
|
|
||||||
- pthread_join(thid, NULL);
|
|
||||||
- if (master_list_empty(master_list))
|
|
||||||
- return NULL;
|
|
||||||
- thid = 0;
|
|
||||||
- }
|
|
||||||
+ do_signals(master_list, sig);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SIGHUP:
|
|
||||||
@@ -1179,6 +1167,10 @@ static void handle_mounts_cleanup(void *
|
|
||||||
|
|
||||||
msg("shut down path %s", path);
|
|
||||||
|
|
||||||
+ /* If we are the last tell the state machine to shutdown */
|
|
||||||
+ if (!submount && master_list_empty(master_list))
|
|
||||||
+ pthread_kill(state_mach_thid, SIGTERM);
|
|
||||||
+
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1357,7 +1349,7 @@ static void usage(void)
|
|
||||||
" -v --verbose be verbose\n"
|
|
||||||
" -d --debug log debuging info\n"
|
|
||||||
" -D --define define global macro variable\n"
|
|
||||||
- /*" -f --foreground do not fork into background\n" */
|
|
||||||
+ " -f --foreground do not fork into background\n"
|
|
||||||
" -r --random-multimount-selection\n"
|
|
||||||
" use ramdom replicated server selection\n"
|
|
||||||
" -O --global-options\n"
|
|
||||||
@@ -1632,14 +1624,6 @@ int main(int argc, char *argv[])
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- if (pthread_attr_init(&thread_attr_nodetach)) {
|
|
||||||
- crit(LOGOPT_ANY,
|
|
||||||
- "%s: failed to init thread attribute struct!",
|
|
||||||
- program);
|
|
||||||
- close(start_pipefd[1]);
|
|
||||||
- exit(1);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
msg("Starting automounter version %s, master map %s",
|
|
||||||
version, master_list->name);
|
|
||||||
msg("using kernel protocol version %d.%02d",
|
|
||||||
@@ -1684,6 +1668,7 @@ int main(int argc, char *argv[])
|
|
||||||
res = write(start_pipefd[1], pst_stat, sizeof(pst_stat));
|
|
||||||
close(start_pipefd[1]);
|
|
||||||
|
|
||||||
+ state_mach_thid = pthread_self();
|
|
||||||
statemachine(NULL);
|
|
||||||
|
|
||||||
master_kill(master_list);
|
|
||||||
diff -up autofs-5.0.2/lib/master.c.foreground-logging autofs-5.0.2/lib/master.c
|
|
||||||
--- autofs-5.0.2/lib/master.c.foreground-logging 2007-09-24 14:42:28.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/lib/master.c 2007-09-24 14:44:18.000000000 +0800
|
|
||||||
@@ -954,6 +954,7 @@ void master_notify_state_change(struct m
|
|
||||||
|
|
||||||
switch (sig) {
|
|
||||||
case SIGTERM:
|
|
||||||
+ case SIGINT:
|
|
||||||
if (ap->state != ST_SHUTDOWN_PENDING &&
|
|
||||||
ap->state != ST_SHUTDOWN_FORCE) {
|
|
||||||
next = ST_SHUTDOWN_PENDING;
|
|
||||||
diff -up autofs-5.0.2/lib/log.c.foreground-logging autofs-5.0.2/lib/log.c
|
|
||||||
--- autofs-5.0.2/lib/log.c.foreground-logging 2007-06-18 15:18:08.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/lib/log.c 2007-09-24 14:44:18.000000000 +0800
|
|
||||||
@@ -27,9 +27,6 @@
|
|
||||||
|
|
||||||
#include "automount.h"
|
|
||||||
|
|
||||||
-/* re-entrant syslog default context data */
|
|
||||||
-#define AUTOFS_SYSLOG_CONTEXT {-1, 0, 0, LOG_PID, (const char *) 0, LOG_DAEMON, 0xff};
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
struct syslog_data syslog_context = AUTOFS_SYSLOG_CONTEXT;
|
|
||||||
struct syslog_data *slc = &syslog_context;
|
|
||||||
@@ -134,30 +131,40 @@ static void syslog_debug(unsigned int lo
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void to_stderr(unsigned int logopt, const char *msg, ...)
|
|
||||||
+{
|
|
||||||
+ va_list ap;
|
|
||||||
+ va_start(ap, msg);
|
|
||||||
+ vfprintf(stderr, msg, ap);
|
|
||||||
+ fputc('\n',stderr);
|
|
||||||
+ va_end(ap);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void set_mnt_logging(struct autofs_point *ap)
|
|
||||||
{
|
|
||||||
unsigned int opt_verbose = ap->logopt & LOGOPT_VERBOSE;
|
|
||||||
unsigned int opt_debug = ap->logopt & LOGOPT_DEBUG;
|
|
||||||
|
|
||||||
- if (opt_debug)
|
|
||||||
- log_debug = syslog_debug;
|
|
||||||
+ if (opt_debug) {
|
|
||||||
+ if (logging_to_syslog)
|
|
||||||
+ log_debug = syslog_debug;
|
|
||||||
+ else
|
|
||||||
+ log_debug = to_stderr;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (opt_verbose || opt_debug) {
|
|
||||||
- log_info = syslog_info;
|
|
||||||
- log_notice = syslog_notice;
|
|
||||||
- log_warn = syslog_warn;
|
|
||||||
+ if (logging_to_syslog) {
|
|
||||||
+ log_info = syslog_info;
|
|
||||||
+ log_notice = syslog_notice;
|
|
||||||
+ log_warn = syslog_warn;
|
|
||||||
+ } else {
|
|
||||||
+ log_info = to_stderr;
|
|
||||||
+ log_notice = to_stderr;
|
|
||||||
+ log_warn = to_stderr;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void to_stderr(unsigned int logopt, const char *msg, ...)
|
|
||||||
-{
|
|
||||||
- va_list ap;
|
|
||||||
- va_start(ap, msg);
|
|
||||||
- vfprintf(stderr, msg, ap);
|
|
||||||
- fputc('\n',stderr);
|
|
||||||
- va_end(ap);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
void log_to_syslog(void)
|
|
||||||
{
|
|
||||||
char buf[MAX_ERR_BUF];
|
|
||||||
diff -up autofs-5.0.2/man/automount.8.foreground-logging autofs-5.0.2/man/automount.8
|
|
||||||
--- autofs-5.0.2/man/automount.8.foreground-logging 2007-09-24 14:42:28.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/man/automount.8 2007-09-24 14:44:18.000000000 +0800
|
|
||||||
@@ -47,6 +47,9 @@ Define a global macro substitution varia
|
|
||||||
are over-ridden macro definitions of the same name specified in
|
|
||||||
mount entries.
|
|
||||||
.TP
|
|
||||||
+.I "\-f, \-\-foreground"
|
|
||||||
+Run the daemon in the forground and log to stderr instead of syslog."
|
|
||||||
+.TP
|
|
||||||
.I "\-r, \-\-random-multimount-selection"
|
|
||||||
Enables the use of ramdom selection when choosing a host from a
|
|
||||||
list of replicated servers.
|
|
@ -1,56 +0,0 @@
|
|||||||
diff --git a/daemon/state.c b/daemon/state.c
|
|
||||||
index 6c373c8..39f4497 100644
|
|
||||||
--- a/daemon/state.c
|
|
||||||
+++ b/daemon/state.c
|
|
||||||
@@ -894,6 +894,7 @@ static void *st_queue_handler(void *arg)
|
|
||||||
struct list_head *head;
|
|
||||||
struct list_head *p;
|
|
||||||
struct timespec wait;
|
|
||||||
+ struct timeval now;
|
|
||||||
int status, ret;
|
|
||||||
|
|
||||||
st_mutex_lock();
|
|
||||||
@@ -904,8 +905,9 @@ static void *st_queue_handler(void *arg)
|
|
||||||
* entry is added.
|
|
||||||
*/
|
|
||||||
head = &state_queue;
|
|
||||||
- wait.tv_sec = time(NULL) + 1;
|
|
||||||
- wait.tv_nsec = 0;
|
|
||||||
+ gettimeofday(&now, NULL);
|
|
||||||
+ wait.tv_sec = now.tv_sec + 1;
|
|
||||||
+ wait.tv_nsec = now.tv_usec * 1000;
|
|
||||||
|
|
||||||
while (list_empty(head)) {
|
|
||||||
status = pthread_cond_timedwait(&cond, &mutex, &wait);
|
|
||||||
@@ -939,8 +941,9 @@ static void *st_queue_handler(void *arg)
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
- wait.tv_sec = time(NULL) + 1;
|
|
||||||
- wait.tv_nsec = 0;
|
|
||||||
+ gettimeofday(&now, NULL);
|
|
||||||
+ wait.tv_sec = now.tv_sec + 1;
|
|
||||||
+ wait.tv_nsec = now.tv_usec * 1000;
|
|
||||||
|
|
||||||
signaled = 0;
|
|
||||||
while (!signaled) {
|
|
||||||
diff --git a/lib/alarm.c b/lib/alarm.c
|
|
||||||
index c6c4ba3..90bf7aa 100755
|
|
||||||
--- a/lib/alarm.c
|
|
||||||
+++ b/lib/alarm.c
|
|
||||||
@@ -192,12 +192,14 @@ static void *alarm_handler(void *arg)
|
|
||||||
now = time(NULL);
|
|
||||||
|
|
||||||
if (first->time > now) {
|
|
||||||
+ struct timeval usecs;
|
|
||||||
/*
|
|
||||||
* Wait for alarm to trigger or a new alarm
|
|
||||||
* to be added.
|
|
||||||
*/
|
|
||||||
+ gettimeofday(&usecs, NULL);
|
|
||||||
expire.tv_sec = first->time;
|
|
||||||
- expire.tv_nsec = 0;
|
|
||||||
+ expire.tv_nsec = usecs.tv_usec * 1000;
|
|
||||||
|
|
||||||
status = pthread_cond_timedwait(&cond, &mutex, &expire);
|
|
||||||
if (status && status != ETIMEDOUT)
|
|
@ -1,77 +0,0 @@
|
|||||||
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
|
|
||||||
index 56aaa5d..49a711c 100644
|
|
||||||
--- a/man/auto.master.5.in
|
|
||||||
+++ b/man/auto.master.5.in
|
|
||||||
@@ -196,8 +196,8 @@ For example, with an entry in the master map of
|
|
||||||
accessing /net/myserver will mount exports from myserver on directories below
|
|
||||||
/net/myserver.
|
|
||||||
.P
|
|
||||||
-NOTE: mounts done from a hosts map will be mounted with the "nosuid" option
|
|
||||||
-unless the "suid" option is explicitly given in the master map entry.
|
|
||||||
+NOTE: mounts done from a hosts map will be mounted with the "nosuid" and "nodev" options
|
|
||||||
+unless the options "suid" and "dev" are explicitly given in the master map entry.
|
|
||||||
.SH LDAP MAPS
|
|
||||||
If the map type \fBldap\fP is specified the mapname is of the form
|
|
||||||
\fB[//servername/]dn\fP, where the optional \fBservername\fP is
|
|
||||||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|
||||||
index a97a7aa..4241f16 100644
|
|
||||||
--- a/modules/parse_sun.c
|
|
||||||
+++ b/modules/parse_sun.c
|
|
||||||
@@ -589,8 +589,12 @@ static int sun_mount(struct autofs_point *ap, const char *root,
|
|
||||||
type = ap->entry->maps->type;
|
|
||||||
if (type && !strcmp(type, "hosts")) {
|
|
||||||
if (options) {
|
|
||||||
- if (!strstr(options, "suid")) {
|
|
||||||
- char *tmp = alloca(strlen(options) + 8);
|
|
||||||
+ int len = strlen(options);
|
|
||||||
+ int suid = strstr(options, "suid") ? 0 : 7;
|
|
||||||
+ int dev = strstr(options, "dev") ? 0 : 6;
|
|
||||||
+
|
|
||||||
+ if (suid || dev) {
|
|
||||||
+ char *tmp = alloca(len + suid + dev + 1);
|
|
||||||
if (!tmp) {
|
|
||||||
error(ap->logopt, MODPREFIX
|
|
||||||
"alloca failed for options");
|
|
||||||
@@ -598,12 +602,16 @@ static int sun_mount(struct autofs_point *ap, const char *root,
|
|
||||||
return -1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
strcpy(tmp, options);
|
|
||||||
- strcat(tmp, ",nosuid");
|
|
||||||
+ if (suid)
|
|
||||||
+ strcat(tmp, ",nosuid");
|
|
||||||
+ if (dev)
|
|
||||||
+ strcat(tmp, ",nodev");
|
|
||||||
options = tmp;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
- char *tmp = alloca(7);
|
|
||||||
+ char *tmp = alloca(13);
|
|
||||||
if (!tmp) {
|
|
||||||
error(ap->logopt,
|
|
||||||
MODPREFIX "alloca failed for options");
|
|
||||||
@@ -611,7 +619,7 @@ static int sun_mount(struct autofs_point *ap, const char *root,
|
|
||||||
return -1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
- strcpy(tmp, "nosuid");
|
|
||||||
+ strcpy(tmp, "nosuid,nodev");
|
|
||||||
options = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/samples/auto.master b/samples/auto.master
|
|
||||||
index 4995976..9fe5609 100644
|
|
||||||
--- a/samples/auto.master
|
|
||||||
+++ b/samples/auto.master
|
|
||||||
@@ -7,8 +7,8 @@
|
|
||||||
/misc /etc/auto.misc
|
|
||||||
#
|
|
||||||
# NOTE: mounts done from a hosts map will be mounted with the
|
|
||||||
-# "nosuid" option unless the "suid" option is explicitly
|
|
||||||
-# given.
|
|
||||||
+# "nosuid" and "nodev" options unless the "suid" and "dev"
|
|
||||||
+# options are explicitly given.
|
|
||||||
#
|
|
||||||
/net -hosts
|
|
||||||
#
|
|
@ -1,79 +0,0 @@
|
|||||||
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
|
|
||||||
index d488960..56aaa5d 100644
|
|
||||||
--- a/man/auto.master.5.in
|
|
||||||
+++ b/man/auto.master.5.in
|
|
||||||
@@ -195,6 +195,9 @@ For example, with an entry in the master map of
|
|
||||||
.hy
|
|
||||||
accessing /net/myserver will mount exports from myserver on directories below
|
|
||||||
/net/myserver.
|
|
||||||
+.P
|
|
||||||
+NOTE: mounts done from a hosts map will be mounted with the "nosuid" option
|
|
||||||
+unless the "suid" option is explicitly given in the master map entry.
|
|
||||||
.SH LDAP MAPS
|
|
||||||
If the map type \fBldap\fP is specified the mapname is of the form
|
|
||||||
\fB[//servername/]dn\fP, where the optional \fBservername\fP is
|
|
||||||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|
||||||
index 186e567..9a97329 100644
|
|
||||||
--- a/modules/parse_sun.c
|
|
||||||
+++ b/modules/parse_sun.c
|
|
||||||
@@ -496,6 +496,7 @@ static int sun_mount(struct autofs_point *ap, const char *root,
|
|
||||||
int rv, cur_state;
|
|
||||||
char *mountpoint;
|
|
||||||
char *what;
|
|
||||||
+ char *type;
|
|
||||||
|
|
||||||
if (*options == '\0')
|
|
||||||
options = NULL;
|
|
||||||
@@ -585,6 +586,36 @@ static int sun_mount(struct autofs_point *ap, const char *root,
|
|
||||||
mountpoint = alloca(namelen + 1);
|
|
||||||
sprintf(mountpoint, "%.*s", namelen, name);
|
|
||||||
|
|
||||||
+ type = ap->entry->maps->type;
|
|
||||||
+ if (type && !strcmp(type, "hosts")) {
|
|
||||||
+ if (options) {
|
|
||||||
+ if (!strstr(options, "suid")) {
|
|
||||||
+ char *tmp = alloca(strlen(options) + 8);
|
|
||||||
+ if (!tmp) {
|
|
||||||
+ error(ap->logopt, MODPREFIX
|
|
||||||
+ "alloca failed for options");
|
|
||||||
+ if (nonstrict)
|
|
||||||
+ return -1;
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+ strcpy(tmp, options);
|
|
||||||
+ strcat(tmp, ",nosuid");
|
|
||||||
+ options = tmp;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ char *tmp = alloca(7);
|
|
||||||
+ if (!tmp) {
|
|
||||||
+ error(ap->logopt,
|
|
||||||
+ MODPREFIX "alloca failed for options");
|
|
||||||
+ if (nonstrict)
|
|
||||||
+ return -1;
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+ strcpy(tmp, "nosuid");
|
|
||||||
+ options = tmp;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
||||||
if (!strcmp(fstype, "nfs")) {
|
|
||||||
what = alloca(loclen + 1);
|
|
||||||
diff --git a/samples/auto.master b/samples/auto.master
|
|
||||||
index d4796a3..4995976 100644
|
|
||||||
--- a/samples/auto.master
|
|
||||||
+++ b/samples/auto.master
|
|
||||||
@@ -5,6 +5,11 @@
|
|
||||||
# For details of the format look at autofs(5).
|
|
||||||
#
|
|
||||||
/misc /etc/auto.misc
|
|
||||||
+#
|
|
||||||
+# NOTE: mounts done from a hosts map will be mounted with the
|
|
||||||
+# "nosuid" option unless the "suid" option is explicitly
|
|
||||||
+# given.
|
|
||||||
+#
|
|
||||||
/net -hosts
|
|
||||||
#
|
|
||||||
# Include central master map if it can be found using
|
|
@ -1,20 +0,0 @@
|
|||||||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
|
||||||
index 70b9e02..4f2b318 100644
|
|
||||||
--- a/daemon/lookup.c
|
|
||||||
+++ b/daemon/lookup.c
|
|
||||||
@@ -325,6 +325,7 @@ static int read_file_source_instance(struct autofs_point *ap, struct map_source
|
|
||||||
instance->recurse = map->recurse;
|
|
||||||
instance->depth = map->depth;
|
|
||||||
}
|
|
||||||
+ instance->stale = map->stale;
|
|
||||||
|
|
||||||
return do_read_map(ap, instance, age);
|
|
||||||
}
|
|
||||||
@@ -346,6 +347,7 @@ static int read_source_instance(struct autofs_point *ap, struct map_source *map,
|
|
||||||
instance->recurse = map->recurse;
|
|
||||||
instance->depth = map->depth;
|
|
||||||
}
|
|
||||||
+ instance->stale = map->stale;
|
|
||||||
|
|
||||||
return do_read_map(ap, instance, age);
|
|
||||||
}
|
|
@ -1,130 +0,0 @@
|
|||||||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|
||||||
index 4ab4204..88e59ab 100644
|
|
||||||
--- a/daemon/direct.c
|
|
||||||
+++ b/daemon/direct.c
|
|
||||||
@@ -1218,11 +1218,11 @@ static void *do_mount_direct(void *arg)
|
|
||||||
struct passwd *ppw = &pw;
|
|
||||||
struct passwd **pppw = &ppw;
|
|
||||||
struct group gr;
|
|
||||||
- struct group *pgr = &gr;
|
|
||||||
- struct group **ppgr = &pgr;
|
|
||||||
+ struct group *pgr;
|
|
||||||
+ struct group **ppgr;
|
|
||||||
char *pw_tmp, *gr_tmp;
|
|
||||||
struct thread_stdenv_vars *tsv;
|
|
||||||
- int tmplen;
|
|
||||||
+ int tmplen, grplen;
|
|
||||||
struct stat st;
|
|
||||||
int status, state;
|
|
||||||
|
|
||||||
@@ -1326,7 +1326,7 @@ static void *do_mount_direct(void *arg)
|
|
||||||
|
|
||||||
/* Try to get group info */
|
|
||||||
|
|
||||||
- tmplen = sysconf(_SC_GETGR_R_SIZE_MAX);
|
|
||||||
+ grplen = sysconf(_SC_GETGR_R_SIZE_MAX);
|
|
||||||
if (tmplen < 0) {
|
|
||||||
error(ap->logopt, "failed to get buffer size for getgrgid_r");
|
|
||||||
free(tsv->user);
|
|
||||||
@@ -1335,16 +1335,28 @@ static void *do_mount_direct(void *arg)
|
|
||||||
goto cont;
|
|
||||||
}
|
|
||||||
|
|
||||||
- gr_tmp = malloc(tmplen + 1);
|
|
||||||
- if (!gr_tmp) {
|
|
||||||
- error(ap->logopt, "failed to malloc buffer for getgrgid_r");
|
|
||||||
- free(tsv->user);
|
|
||||||
- free(tsv->home);
|
|
||||||
- free(tsv);
|
|
||||||
- goto cont;
|
|
||||||
+ gr_tmp = NULL;
|
|
||||||
+ tmplen = grplen;
|
|
||||||
+ while (1) {
|
|
||||||
+ char *tmp = realloc(gr_tmp, tmplen + 1);
|
|
||||||
+ if (!tmp) {
|
|
||||||
+ error(ap->logopt, "failed to malloc buffer for getgrgid_r");
|
|
||||||
+ if (gr_tmp)
|
|
||||||
+ free(gr_tmp);
|
|
||||||
+ free(tsv->user);
|
|
||||||
+ free(tsv->home);
|
|
||||||
+ free(tsv);
|
|
||||||
+ goto cont;
|
|
||||||
+ }
|
|
||||||
+ gr_tmp = tmp;
|
|
||||||
+ pgr = &gr;
|
|
||||||
+ ppgr = &pgr;
|
|
||||||
+ status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr);
|
|
||||||
+ if (status != ERANGE)
|
|
||||||
+ break;
|
|
||||||
+ tmplen += grplen;
|
|
||||||
}
|
|
||||||
|
|
||||||
- status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr);
|
|
||||||
if (status || !pgr) {
|
|
||||||
error(ap->logopt, "failed to get group info from getgrgid_r");
|
|
||||||
free(tsv->user);
|
|
||||||
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
|
||||||
index 5c422c8..f6b93d0 100644
|
|
||||||
--- a/daemon/indirect.c
|
|
||||||
+++ b/daemon/indirect.c
|
|
||||||
@@ -666,11 +666,11 @@ static void *do_mount_indirect(void *arg)
|
|
||||||
struct passwd *ppw = &pw;
|
|
||||||
struct passwd **pppw = &ppw;
|
|
||||||
struct group gr;
|
|
||||||
- struct group *pgr = &gr;
|
|
||||||
- struct group **ppgr = &pgr;
|
|
||||||
+ struct group *pgr;
|
|
||||||
+ struct group **ppgr;
|
|
||||||
char *pw_tmp, *gr_tmp;
|
|
||||||
struct thread_stdenv_vars *tsv;
|
|
||||||
- int len, tmplen, status, state;
|
|
||||||
+ int len, tmplen, grplen, status, state;
|
|
||||||
|
|
||||||
mt = (struct pending_args *) arg;
|
|
||||||
|
|
||||||
@@ -771,7 +771,7 @@ static void *do_mount_indirect(void *arg)
|
|
||||||
|
|
||||||
/* Try to get group info */
|
|
||||||
|
|
||||||
- tmplen = sysconf(_SC_GETGR_R_SIZE_MAX);
|
|
||||||
+ grplen = sysconf(_SC_GETGR_R_SIZE_MAX);
|
|
||||||
if (tmplen < 0) {
|
|
||||||
error(ap->logopt, "failed to get buffer size for getgrgid_r");
|
|
||||||
free(tsv->user);
|
|
||||||
@@ -780,16 +780,28 @@ static void *do_mount_indirect(void *arg)
|
|
||||||
goto cont;
|
|
||||||
}
|
|
||||||
|
|
||||||
- gr_tmp = malloc(tmplen + 1);
|
|
||||||
- if (!gr_tmp) {
|
|
||||||
- error(ap->logopt, "failed to malloc buffer for getgrgid_r");
|
|
||||||
- free(tsv->user);
|
|
||||||
- free(tsv->home);
|
|
||||||
- free(tsv);
|
|
||||||
- goto cont;
|
|
||||||
+ gr_tmp = NULL;
|
|
||||||
+ tmplen = grplen;
|
|
||||||
+ while (1) {
|
|
||||||
+ char *tmp = realloc(gr_tmp, tmplen + 1);
|
|
||||||
+ if (!tmp) {
|
|
||||||
+ error(ap->logopt, "failed to malloc buffer for getgrgid_r");
|
|
||||||
+ if (gr_tmp)
|
|
||||||
+ free(gr_tmp);
|
|
||||||
+ free(tsv->user);
|
|
||||||
+ free(tsv->home);
|
|
||||||
+ free(tsv);
|
|
||||||
+ goto cont;
|
|
||||||
+ }
|
|
||||||
+ gr_tmp = tmp;
|
|
||||||
+ pgr = &gr;
|
|
||||||
+ ppgr = &pgr;
|
|
||||||
+ status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr);
|
|
||||||
+ if (status != ERANGE)
|
|
||||||
+ break;
|
|
||||||
+ tmplen += grplen;
|
|
||||||
}
|
|
||||||
|
|
||||||
- status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr);
|
|
||||||
if (status || !pgr) {
|
|
||||||
error(ap->logopt, "failed to get group info from getgrgid_r");
|
|
||||||
free(tsv->user);
|
|
@ -1,22 +0,0 @@
|
|||||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
|
||||||
index d5e666b..a7b315e 100644
|
|
||||||
--- a/modules/lookup_ldap.c
|
|
||||||
+++ b/modules/lookup_ldap.c
|
|
||||||
@@ -1500,7 +1500,7 @@ static int lookup_one(struct autofs_point *ap,
|
|
||||||
*qKey = '/';
|
|
||||||
|
|
||||||
/* Build a query string. */
|
|
||||||
- l = strlen(class) + 2*strlen(entry) + strlen(qKey) + 29;
|
|
||||||
+ l = strlen(class) + 3*strlen(entry) + strlen(qKey) + 35;
|
|
||||||
|
|
||||||
query = alloca(l);
|
|
||||||
if (query == NULL) {
|
|
||||||
@@ -1514,7 +1514,7 @@ static int lookup_one(struct autofs_point *ap,
|
|
||||||
* whose entry is equal to qKey.
|
|
||||||
*/
|
|
||||||
ql = sprintf(query,
|
|
||||||
- "(&(objectclass=%s)(|(%s=%s)(%s=/)))", class, entry, qKey, entry);
|
|
||||||
+ "(&(objectclass=%s)(|(%s=%s)(%s=/)(%s=\\2A)))", class, entry, qKey, entry, entry);
|
|
||||||
if (ql >= l) {
|
|
||||||
error(ap->logopt,
|
|
||||||
MODPREFIX "error forming query string");
|
|
@ -1,178 +0,0 @@
|
|||||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
|
||||||
index de8d515..a412797 100644
|
|
||||||
--- a/modules/lookup_ldap.c
|
|
||||||
+++ b/modules/lookup_ldap.c
|
|
||||||
@@ -1210,50 +1210,68 @@ static int read_one_map(struct autofs_point *ap,
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * By definition keys must be unique within
|
|
||||||
- * each map entry
|
|
||||||
+ * By definition keys should be unique within each map entry,
|
|
||||||
+ * but as always there are exceptions.
|
|
||||||
*/
|
|
||||||
k_val = NULL;
|
|
||||||
k_len = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Keys must be unique so, in general, there shouldn't be
|
|
||||||
+ * Keys should be unique so, in general, there shouldn't be
|
|
||||||
* more than one attribute value. We make an exception for
|
|
||||||
* wildcard entries as people may have values for '*' or
|
|
||||||
* '/' for compaibility reasons. We use the '/' as the
|
|
||||||
* wildcard in LDAP but allow '*' as well to allow for
|
|
||||||
* people using older schemas that allow '*' as a key
|
|
||||||
- * value.
|
|
||||||
+ * value. Another case where there can be multiple key
|
|
||||||
+ * values is when people have used the "%" hack to specify
|
|
||||||
+ * case matching ctriteria in a caase insensitive attribute.
|
|
||||||
*/
|
|
||||||
count = ldap_count_values_len(bvKey);
|
|
||||||
- if (count > 2) {
|
|
||||||
- error(ap->logopt,
|
|
||||||
- MODPREFIX
|
|
||||||
- "key %.*s has duplicate entries - ignoring",
|
|
||||||
- bvKey[0]->bv_len, bvKey[0]->bv_val);
|
|
||||||
- goto next;
|
|
||||||
- } else if (count == 2) {
|
|
||||||
+ if (count > 1) {
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
/* Check for the "/" and "*" and use as "/" if found */
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
- /* check for wildcard */
|
|
||||||
- if (bvKey[i]->bv_len != 1)
|
|
||||||
+ bvKey[i]->bv_val[bvKey[i]->bv_len] = '\0';
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * If multiple entries are present they could
|
|
||||||
+ * be the result of people using the "%" hack so
|
|
||||||
+ * ignore them.
|
|
||||||
+ */
|
|
||||||
+ if (strchr(bvKey[i]->bv_val, '%'))
|
|
||||||
continue;
|
|
||||||
- if (*bvKey[i]->bv_val != '/' &&
|
|
||||||
- *bvKey[i]->bv_val != '*')
|
|
||||||
- continue;
|
|
||||||
- /* always use '/' internally */
|
|
||||||
- *bvKey[i]->bv_val = '/';
|
|
||||||
+
|
|
||||||
+ /* check for wildcard */
|
|
||||||
+ if (bvKey[i]->bv_len == 1 &&
|
|
||||||
+ (*bvKey[i]->bv_val == '/' ||
|
|
||||||
+ *bvKey[i]->bv_val == '*')) {
|
|
||||||
+ /* always use '/' internally */
|
|
||||||
+ *bvKey[i]->bv_val = '/';
|
|
||||||
+ k_val = bvKey[i]->bv_val;
|
|
||||||
+ k_len = 1;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * We have a result from LDAP so this is a
|
|
||||||
+ * valid entry. Set the result to the LDAP
|
|
||||||
+ * key that isn't a wildcard and doesn't have
|
|
||||||
+ * any "%" hack values present. This should be
|
|
||||||
+ * the case insensitive match string for the
|
|
||||||
+ * nis schema, the default value.
|
|
||||||
+ */
|
|
||||||
k_val = bvKey[i]->bv_val;
|
|
||||||
- k_len = 1;
|
|
||||||
+ k_len = bvKey[i]->bv_len;
|
|
||||||
+
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!k_val) {
|
|
||||||
error(ap->logopt,
|
|
||||||
MODPREFIX
|
|
||||||
- "key %.*s has duplicate entries - ignoring",
|
|
||||||
+ "invalid entry %.*s - ignoring",
|
|
||||||
bvKey[0]->bv_len, bvKey[0]->bv_val);
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
@@ -1495,7 +1513,10 @@ static int lookup_one(struct autofs_point *ap,
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* By definition keys must be unique within each map entry */
|
|
||||||
+ /*
|
|
||||||
+ * By definition keys should be unique within each map entry,
|
|
||||||
+ * but as always there are exceptions.
|
|
||||||
+ */
|
|
||||||
k_val = NULL;
|
|
||||||
k_len = 0;
|
|
||||||
|
|
||||||
@@ -1506,37 +1527,53 @@ static int lookup_one(struct autofs_point *ap,
|
|
||||||
* '/' for compaibility reasons. We use the '/' as the
|
|
||||||
* wildcard in LDAP but allow '*' as well to allow for
|
|
||||||
* people using older schemas that allow '*' as a key
|
|
||||||
- * value.
|
|
||||||
+ * value. Another case where there can be multiple key
|
|
||||||
+ * values is when people have used the "%" hack to specify
|
|
||||||
+ * case matching ctriteria in a caase insensitive attribute.
|
|
||||||
*/
|
|
||||||
count = ldap_count_values_len(bvKey);
|
|
||||||
- if (count > 2) {
|
|
||||||
- error(ap->logopt,
|
|
||||||
- MODPREFIX
|
|
||||||
- "key %.*s has duplicate entries - ignoring",
|
|
||||||
- bvKey[0]->bv_len, bvKey[0]->bv_val);
|
|
||||||
- goto next;
|
|
||||||
- } else if (count == 2) {
|
|
||||||
+ if (count > 1) {
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
/* Check for the "/" and "*" and use as "/" if found */
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
- /* check for wildcard */
|
|
||||||
- if (bvKey[i]->bv_len != 1)
|
|
||||||
- continue;
|
|
||||||
- if (*bvKey[i]->bv_val != '/' &&
|
|
||||||
- *bvKey[i]->bv_val != '*')
|
|
||||||
+ bvKey[i]->bv_val[bvKey[i]->bv_len] = '\0';
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * If multiple entries are present they could
|
|
||||||
+ * be the result of people using the "%" hack so
|
|
||||||
+ * ignore them.
|
|
||||||
+ */
|
|
||||||
+ if (strchr(bvKey[i]->bv_val, '%'))
|
|
||||||
continue;
|
|
||||||
- /* always use '/' internally */
|
|
||||||
- *bvKey[i]->bv_val = '/';
|
|
||||||
- k_val = bvKey[i]->bv_val;
|
|
||||||
- k_len = 1;
|
|
||||||
+
|
|
||||||
+ /* check for wildcard */
|
|
||||||
+ if (bvKey[i]->bv_len == 1 &&
|
|
||||||
+ (*bvKey[i]->bv_val == '/' ||
|
|
||||||
+ *bvKey[i]->bv_val == '*')) {
|
|
||||||
+ /* always use '/' internally */
|
|
||||||
+ *bvKey[i]->bv_val = '/';
|
|
||||||
+ k_val = bvKey[i]->bv_val;
|
|
||||||
+ k_len = 1;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * The key was matched by LDAP so this is a
|
|
||||||
+ * valid entry. Set the result key to the
|
|
||||||
+ * lookup key to provide the mixed case
|
|
||||||
+ * matching provided by the "%" hack.
|
|
||||||
+ */
|
|
||||||
+ k_val = qKey;
|
|
||||||
+ k_len = strlen(qKey);
|
|
||||||
+
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!k_val) {
|
|
||||||
error(ap->logopt,
|
|
||||||
- MODPREFIX "key %.*s has duplicate entries",
|
|
||||||
- bvKey[0]->bv_len, bvKey[0]->bv_val);
|
|
||||||
+ MODPREFIX "no valid key found for %.*s",
|
|
||||||
+ qKey_len, qKey);
|
|
||||||
ret = CHE_FAIL;
|
|
||||||
goto next;
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in
|
|
||||||
index 8299b55..85f4e34 100644
|
|
||||||
--- a/redhat/autofs.sysconfig.in
|
|
||||||
+++ b/redhat/autofs.sysconfig.in
|
|
||||||
@@ -21,9 +21,12 @@ BROWSE_MODE="no"
|
|
||||||
#
|
|
||||||
#LOGGING="none"
|
|
||||||
#
|
|
||||||
-# Define the default LDAP schema to use for lookups
|
|
||||||
+# Define the LDAP schema to used for lookups
|
|
||||||
#
|
|
||||||
-# System default
|
|
||||||
+# If no schema is set autofs will check each of the schemas
|
|
||||||
+# below in the order given to try and locate an appropriate
|
|
||||||
+# basdn for lookups. If you want to minimize the number of
|
|
||||||
+# queries to the server set the values here.
|
|
||||||
#
|
|
||||||
#MAP_OBJECT_CLASS="nisMap"
|
|
||||||
#ENTRY_OBJECT_CLASS="nisObject"
|
|
||||||
diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
|
|
||||||
index 8299b55..85f4e34 100644
|
|
||||||
--- a/samples/autofs.conf.default.in
|
|
||||||
+++ b/samples/autofs.conf.default.in
|
|
||||||
@@ -21,9 +21,12 @@ BROWSE_MODE="no"
|
|
||||||
#
|
|
||||||
#LOGGING="none"
|
|
||||||
#
|
|
||||||
-# Define the default LDAP schema to use for lookups
|
|
||||||
+# Define the LDAP schema to used for lookups
|
|
||||||
#
|
|
||||||
-# System default
|
|
||||||
+# If no schema is set autofs will check each of the schemas
|
|
||||||
+# below in the order given to try and locate an appropriate
|
|
||||||
+# basdn for lookups. If you want to minimize the number of
|
|
||||||
+# queries to the server set the values here.
|
|
||||||
#
|
|
||||||
#MAP_OBJECT_CLASS="nisMap"
|
|
||||||
#ENTRY_OBJECT_CLASS="nisObject"
|
|
@ -1,816 +0,0 @@
|
|||||||
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
|
|
@ -1,134 +0,0 @@
|
|||||||
diff -up autofs-5.0.2/configure.libxml2-workaround autofs-5.0.2/configure
|
|
||||||
--- autofs-5.0.2/configure.libxml2-workaround 2007-09-24 14:25:06.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/configure 2007-09-24 14:26:09.000000000 +0800
|
|
||||||
@@ -2498,6 +2498,23 @@ echo "${ECHO_T}yes" >&6; }
|
|
||||||
HAVE_LIBXML=1
|
|
||||||
XML_LIBS=`$XML_CONFIG --libs`
|
|
||||||
XML_FLAGS=`$XML_CONFIG --cflags`
|
|
||||||
+ XML_VER=`$XML_CONFIG --version`
|
|
||||||
+ XML_MAJOR=`echo $XML_VER|cut -d\. -f1`
|
|
||||||
+ if test $XML_MAJOR -le 2
|
|
||||||
+ then
|
|
||||||
+ XML_MINOR=`echo $XML_VER|cut -d\. -f2`
|
|
||||||
+ if test $XML_MINOR -le 6
|
|
||||||
+ then
|
|
||||||
+ XML_REV=`echo $XML_VER|cut -d\. -f3`
|
|
||||||
+ if test $XML_REV -le 99; then
|
|
||||||
+
|
|
||||||
+cat >>confdefs.h <<\_ACEOF
|
|
||||||
+#define LIBXML2_WORKAROUND 1
|
|
||||||
+_ACEOF
|
|
||||||
+
|
|
||||||
+ fi
|
|
||||||
+ fi
|
|
||||||
+ fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
diff -up autofs-5.0.2/include/config.h.in.libxml2-workaround autofs-5.0.2/include/config.h.in
|
|
||||||
--- autofs-5.0.2/include/config.h.in.libxml2-workaround 2007-09-24 14:25:06.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/include/config.h.in 2007-09-24 14:26:09.000000000 +0800
|
|
||||||
@@ -60,6 +60,9 @@
|
|
||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
|
||||||
#undef HAVE_UNISTD_H
|
|
||||||
|
|
||||||
+/* Use libxml2 tsd usage workaround */
|
|
||||||
+#undef LIBXML2_WORKAROUND
|
|
||||||
+
|
|
||||||
/* Define to the address where bug reports for this package should be sent. */
|
|
||||||
#undef PACKAGE_BUGREPORT
|
|
||||||
|
|
||||||
diff -up autofs-5.0.2/aclocal.m4.libxml2-workaround autofs-5.0.2/aclocal.m4
|
|
||||||
--- autofs-5.0.2/aclocal.m4.libxml2-workaround 2007-09-24 14:25:06.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/aclocal.m4 2007-09-24 14:26:09.000000000 +0800
|
|
||||||
@@ -167,6 +167,19 @@ else
|
|
||||||
HAVE_LIBXML=1
|
|
||||||
XML_LIBS=`$XML_CONFIG --libs`
|
|
||||||
XML_FLAGS=`$XML_CONFIG --cflags`
|
|
||||||
+ XML_VER=`$XML_CONFIG --version`
|
|
||||||
+ XML_MAJOR=`echo $XML_VER|cut -d\. -f1`
|
|
||||||
+ if test $XML_MAJOR -le 2
|
|
||||||
+ then
|
|
||||||
+ XML_MINOR=`echo $XML_VER|cut -d\. -f2`
|
|
||||||
+ if test $XML_MINOR -le 6
|
|
||||||
+ then
|
|
||||||
+ XML_REV=`echo $XML_VER|cut -d\. -f3`
|
|
||||||
+ if test $XML_REV -le 99; then
|
|
||||||
+ AC_DEFINE(LIBXML2_WORKAROUND,1, [Use libxml2 tsd usage workaround])
|
|
||||||
+ fi
|
|
||||||
+ fi
|
|
||||||
+ fi
|
|
||||||
fi])
|
|
||||||
|
|
||||||
dnl --------------------------------------------------------------------------
|
|
||||||
diff -up autofs-5.0.2/modules/lookup_ldap.c.libxml2-workaround autofs-5.0.2/modules/lookup_ldap.c
|
|
||||||
--- autofs-5.0.2/modules/lookup_ldap.c.libxml2-workaround 2007-09-24 14:25:06.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/modules/lookup_ldap.c 2007-09-24 14:26:09.000000000 +0800
|
|
||||||
@@ -1929,9 +1929,6 @@ int lookup_done(void *context)
|
|
||||||
struct lookup_context *ctxt = (struct lookup_context *) context;
|
|
||||||
int rv = close_parse(ctxt->parse);
|
|
||||||
#ifdef WITH_SASL
|
|
||||||
- EVP_cleanup();
|
|
||||||
- ERR_free_strings();
|
|
||||||
-
|
|
||||||
autofs_sasl_done(ctxt);
|
|
||||||
#endif
|
|
||||||
free_context(ctxt);
|
|
||||||
diff -up autofs-5.0.2/daemon/automount.c.libxml2-workaround autofs-5.0.2/daemon/automount.c
|
|
||||||
--- autofs-5.0.2/daemon/automount.c.libxml2-workaround 2007-09-24 14:25:06.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/daemon/automount.c 2007-09-24 14:28:56.000000000 +0800
|
|
||||||
@@ -40,6 +40,9 @@
|
|
||||||
#include <sys/utsname.h>
|
|
||||||
|
|
||||||
#include "automount.h"
|
|
||||||
+#ifdef LIBXML2_WORKAROUND
|
|
||||||
+#include <dlfcn.h>
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
const char *program; /* Initialized with argv[0] */
|
|
||||||
const char *version = VERSION_STRING; /* Program version */
|
|
||||||
@@ -1266,22 +1269,6 @@ void *handle_mounts(void *arg)
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_cleanup_pop(1);
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * A cowboy .. me!
|
|
||||||
- * That noise yu ear aint spuurs sonny!!
|
|
||||||
- *
|
|
||||||
- * The libkrb5support destructor called indirectly through
|
|
||||||
- * libgssapi_krb5 which is used bt libkrb5 (somehow) must run
|
|
||||||
- * to completion before the last thread using it exits so
|
|
||||||
- * that it's per thread data keys are deleted or we get a
|
|
||||||
- * little segfault at exit. So much for dlclose being
|
|
||||||
- * syncronous.
|
|
||||||
- *
|
|
||||||
- * So, the solution is a recipe for disaster.
|
|
||||||
- * Hope we don't get a really busy system!
|
|
||||||
- */
|
|
||||||
- /*sleep(1);*/
|
|
||||||
sched_yield();
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
@@ -1681,6 +1668,11 @@ int main(int argc, char *argv[])
|
|
||||||
close(start_pipefd[1]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+#ifdef LIBXML2_WORKAROUND
|
|
||||||
+ void *dh = dlopen("libxml2.so", RTLD_NOW);
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
if (!master_read_master(master_list, age, 0)) {
|
|
||||||
master_kill(master_list);
|
|
||||||
*pst_stat = 3;
|
|
||||||
@@ -1702,5 +1694,9 @@ int main(int argc, char *argv[])
|
|
||||||
}
|
|
||||||
closelog();
|
|
||||||
|
|
||||||
+#ifdef LIBXML2_WORKAROUND
|
|
||||||
+ if (dh)
|
|
||||||
+ dlclose(dh);
|
|
||||||
+#endif
|
|
||||||
exit(0);
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|
||||||
index 9ec6923..7e7d1e6 100644
|
|
||||||
--- a/daemon/automount.c
|
|
||||||
+++ b/daemon/automount.c
|
|
||||||
@@ -1278,6 +1278,8 @@ static void *do_read_master(void *arg)
|
|
||||||
|
|
||||||
defaults_read_config(1);
|
|
||||||
|
|
||||||
+ info(logopt, "re-reading master map %s", master->name);
|
|
||||||
+
|
|
||||||
status = master_read_master(master, age, readall);
|
|
||||||
|
|
||||||
master->reading = 0;
|
|
||||||
diff --git a/daemon/state.c b/daemon/state.c
|
|
||||||
index a2da762..cf07aac 100644
|
|
||||||
--- a/daemon/state.c
|
|
||||||
+++ b/daemon/state.c
|
|
||||||
@@ -376,6 +376,8 @@ static void *do_readmap(void *arg)
|
|
||||||
|
|
||||||
pthread_cleanup_push(do_readmap_cleanup, ra);
|
|
||||||
|
|
||||||
+ info(ap->logopt, "re-reading map for %s", ap->path);
|
|
||||||
+
|
|
||||||
status = lookup_nss_read_map(ap, NULL, now);
|
|
||||||
if (!status)
|
|
||||||
pthread_exit(NULL);
|
|
@ -1,493 +0,0 @@
|
|||||||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|
||||||
index a12b6da..7becad5 100644
|
|
||||||
--- a/daemon/automount.c
|
|
||||||
+++ b/daemon/automount.c
|
|
||||||
@@ -58,6 +58,8 @@ const char *global_options; /* Global option, from command line */
|
|
||||||
static char *pid_file = NULL; /* File in which to keep pid */
|
|
||||||
unsigned int global_random_selection; /* use random policy when selecting
|
|
||||||
* which multi-mount host to mount */
|
|
||||||
+long global_negative_timeout = -1;
|
|
||||||
+
|
|
||||||
static int start_pipefd[2];
|
|
||||||
static int st_stat = 0;
|
|
||||||
static int *pst_stat = &st_stat;
|
|
||||||
@@ -1671,6 +1673,8 @@ static void usage(void)
|
|
||||||
" -f --foreground do not fork into background\n"
|
|
||||||
" -r --random-multimount-selection\n"
|
|
||||||
" use ramdom replicated server selection\n"
|
|
||||||
+ " -n --negative-timeout n\n"
|
|
||||||
+ " set the timeout for failed key lookups.\n"
|
|
||||||
" -O --global-options\n"
|
|
||||||
" specify global mount options\n"
|
|
||||||
" -l --set-log-priority priority path [path,...]\n"
|
|
||||||
@@ -1810,6 +1814,7 @@ int main(int argc, char *argv[])
|
|
||||||
{"define", 1, 0, 'D'},
|
|
||||||
{"foreground", 0, 0, 'f'},
|
|
||||||
{"random-multimount-selection", 0, 0, 'r'},
|
|
||||||
+ {"negative-timeout", 1, 0, 'n'},
|
|
||||||
{"global-options", 1, 0, 'O'},
|
|
||||||
{"version", 0, 0, 'V'},
|
|
||||||
{"set-log-priority", 1, 0, 'l'},
|
|
||||||
@@ -1833,7 +1838,7 @@ int main(int argc, char *argv[])
|
|
||||||
foreground = 0;
|
|
||||||
|
|
||||||
opterr = 0;
|
|
||||||
- while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:", long_options, NULL)) != EOF) {
|
|
||||||
+ while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:n:", long_options, NULL)) != EOF) {
|
|
||||||
switch (opt) {
|
|
||||||
case 'h':
|
|
||||||
usage();
|
|
||||||
@@ -1871,6 +1876,10 @@ int main(int argc, char *argv[])
|
|
||||||
global_random_selection = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
+ case 'n':
|
|
||||||
+ global_negative_timeout = getnumopt(optarg, opt);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
case 'O':
|
|
||||||
if (!have_global_options) {
|
|
||||||
global_options = strdup(optarg);
|
|
||||||
diff --git a/include/automount.h b/include/automount.h
|
|
||||||
index b0d1a9c..4887da6 100644
|
|
||||||
--- a/include/automount.h
|
|
||||||
+++ b/include/automount.h
|
|
||||||
@@ -442,6 +442,7 @@ struct autofs_point {
|
|
||||||
unsigned int type; /* Type of map direct or indirect */
|
|
||||||
time_t exp_timeout; /* Timeout for expiring mounts */
|
|
||||||
time_t exp_runfreq; /* Frequency for polling for timeouts */
|
|
||||||
+ time_t negative_timeout; /* timeout in secs for failed mounts */
|
|
||||||
unsigned ghost; /* Enable/disable gohsted directories */
|
|
||||||
unsigned logopt; /* Per map logging */
|
|
||||||
pthread_t exp_thread; /* Thread that is expiring */
|
|
||||||
diff --git a/include/defaults.h b/include/defaults.h
|
|
||||||
index e296478..6e4f52a 100644
|
|
||||||
--- a/include/defaults.h
|
|
||||||
+++ b/include/defaults.h
|
|
||||||
@@ -22,9 +22,10 @@
|
|
||||||
|
|
||||||
#define DEFAULT_MASTER_MAP_NAME "auto.master"
|
|
||||||
|
|
||||||
-#define DEFAULT_TIMEOUT 600
|
|
||||||
-#define DEFAULT_BROWSE_MODE 1
|
|
||||||
-#define DEFAULT_LOGGING 0
|
|
||||||
+#define DEFAULT_TIMEOUT 600
|
|
||||||
+#define DEFAULT_NEGATIVE_TIMEOUT 60
|
|
||||||
+#define DEFAULT_BROWSE_MODE 1
|
|
||||||
+#define DEFAULT_LOGGING 0
|
|
||||||
|
|
||||||
#define DEFAULT_LDAP_TIMEOUT -1
|
|
||||||
#define DEFAULT_LDAP_NETWORK_TIMEOUT 8
|
|
||||||
@@ -45,6 +46,7 @@ unsigned int defaults_read_config(unsigned int);
|
|
||||||
const char *defaults_get_master_map(void);
|
|
||||||
int defaults_master_set(void);
|
|
||||||
unsigned int defaults_get_timeout(void);
|
|
||||||
+unsigned int defaults_get_negative_timeout(void);
|
|
||||||
unsigned int defaults_get_browse_mode(void);
|
|
||||||
unsigned int defaults_get_logging(void);
|
|
||||||
const char *defaults_get_ldap_server(void);
|
|
||||||
diff --git a/lib/defaults.c b/lib/defaults.c
|
|
||||||
index f494103..8149549 100644
|
|
||||||
--- a/lib/defaults.c
|
|
||||||
+++ b/lib/defaults.c
|
|
||||||
@@ -28,6 +28,7 @@
|
|
||||||
#define ENV_NAME_MASTER_MAP "MASTER_MAP_NAME"
|
|
||||||
|
|
||||||
#define ENV_NAME_TIMEOUT "TIMEOUT"
|
|
||||||
+#define ENV_NAME_NEGATIVE_TIMEOUT "NEGATIVE_TIMEOUT"
|
|
||||||
#define ENV_NAME_BROWSE_MODE "BROWSE_MODE"
|
|
||||||
#define ENV_NAME_LOGGING "LOGGING"
|
|
||||||
|
|
||||||
@@ -308,6 +309,7 @@ unsigned int defaults_read_config(unsigned int to_syslog)
|
|
||||||
|
|
||||||
if (check_set_config_value(key, ENV_NAME_MASTER_MAP, value, to_syslog) ||
|
|
||||||
check_set_config_value(key, ENV_NAME_TIMEOUT, value, to_syslog) ||
|
|
||||||
+ check_set_config_value(key, ENV_NAME_NEGATIVE_TIMEOUT, value, to_syslog) ||
|
|
||||||
check_set_config_value(key, ENV_NAME_BROWSE_MODE, value, to_syslog) ||
|
|
||||||
check_set_config_value(key, ENV_NAME_LOGGING, value, to_syslog) ||
|
|
||||||
check_set_config_value(key, ENV_LDAP_TIMEOUT, value, to_syslog) ||
|
|
||||||
@@ -370,6 +372,17 @@ unsigned int defaults_get_timeout(void)
|
|
||||||
return (unsigned int) timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
+unsigned int defaults_get_negative_timeout(void)
|
|
||||||
+{
|
|
||||||
+ long n_timeout;
|
|
||||||
+
|
|
||||||
+ n_timeout = get_env_number(ENV_NAME_NEGATIVE_TIMEOUT);
|
|
||||||
+ if (n_timeout <= 0)
|
|
||||||
+ n_timeout = DEFAULT_NEGATIVE_TIMEOUT;
|
|
||||||
+
|
|
||||||
+ return (unsigned int) n_timeout;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
unsigned int defaults_get_browse_mode(void)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
diff --git a/lib/master.c b/lib/master.c
|
|
||||||
index 2188bca..c001d20 100644
|
|
||||||
--- a/lib/master.c
|
|
||||||
+++ b/lib/master.c
|
|
||||||
@@ -30,6 +30,8 @@
|
|
||||||
/* The root of the map entry tree */
|
|
||||||
struct master *master_list = NULL;
|
|
||||||
|
|
||||||
+extern long global_negative_timeout;
|
|
||||||
+
|
|
||||||
/* Attribute to create detached thread */
|
|
||||||
extern pthread_attr_t thread_attr;
|
|
||||||
|
|
||||||
@@ -68,6 +70,14 @@ int master_add_autofs_point(struct master_mapent *entry,
|
|
||||||
ap->exp_thread = 0;
|
|
||||||
ap->readmap_thread = 0;
|
|
||||||
ap->exp_timeout = timeout;
|
|
||||||
+ /*
|
|
||||||
+ * Program command line option overrides config.
|
|
||||||
+ * We can't use 0 negative timeout so use default.
|
|
||||||
+ */
|
|
||||||
+ if (global_negative_timeout <= 0)
|
|
||||||
+ ap->negative_timeout = defaults_get_negative_timeout();
|
|
||||||
+ else
|
|
||||||
+ ap->negative_timeout = global_negative_timeout;
|
|
||||||
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
|
|
||||||
ap->ghost = ghost;
|
|
||||||
|
|
||||||
diff --git a/lib/master_parse.y b/lib/master_parse.y
|
|
||||||
index a767f9e..b450122 100644
|
|
||||||
--- a/lib/master_parse.y
|
|
||||||
+++ b/lib/master_parse.y
|
|
||||||
@@ -55,6 +55,7 @@ static char *path;
|
|
||||||
static char *type;
|
|
||||||
static char *format;
|
|
||||||
static long timeout;
|
|
||||||
+static long negative_timeout;
|
|
||||||
static unsigned ghost;
|
|
||||||
extern unsigned global_random_selection;
|
|
||||||
static unsigned random_selection;
|
|
||||||
@@ -95,7 +96,8 @@ static int master_fprintf(FILE *, char *, ...);
|
|
||||||
|
|
||||||
%token COMMENT
|
|
||||||
%token MAP
|
|
||||||
-%token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG OPT_RANDOM
|
|
||||||
+%token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE
|
|
||||||
+%token OPT_DEBUG OPT_RANDOM
|
|
||||||
%token COLON COMMA NL DDASH
|
|
||||||
%type <strtype> map
|
|
||||||
%type <strtype> options
|
|
||||||
@@ -542,6 +544,7 @@ option: daemon_option
|
|
||||||
;
|
|
||||||
|
|
||||||
daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; }
|
|
||||||
+ | OPT_NTIMEOUT NUMBER { negative_timeout = $2; }
|
|
||||||
| OPT_NOGHOST { ghost = 0; }
|
|
||||||
| OPT_GHOST { ghost = 1; }
|
|
||||||
| OPT_VERBOSE { verbose = 1; }
|
|
||||||
@@ -603,6 +606,7 @@ static void local_init_vars(void)
|
|
||||||
verbose = 0;
|
|
||||||
debug = 0;
|
|
||||||
timeout = -1;
|
|
||||||
+ negative_timeout = 0;
|
|
||||||
ghost = defaults_get_browse_mode();
|
|
||||||
random_selection = global_random_selection;
|
|
||||||
tmp_argv = NULL;
|
|
||||||
@@ -793,6 +797,8 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry->ap->random_selection = random_selection;
|
|
||||||
+ if (negative_timeout)
|
|
||||||
+ entry->ap->negative_timeout = negative_timeout;
|
|
||||||
|
|
||||||
/*
|
|
||||||
source = master_find_map_source(entry, type, format,
|
|
||||||
diff --git a/lib/master_tok.l b/lib/master_tok.l
|
|
||||||
index 36aa785..d908047 100644
|
|
||||||
--- a/lib/master_tok.l
|
|
||||||
+++ b/lib/master_tok.l
|
|
||||||
@@ -118,6 +118,7 @@ MTYPE ((file|program|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?(
|
|
||||||
|
|
||||||
|
|
||||||
OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
|
|
||||||
+OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeout{OPTWS}={OPTWS})
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
@@ -321,6 +322,8 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
|
|
||||||
|
|
||||||
{OPTTOUT}/{NUMBER} { return(OPT_TIMEOUT); }
|
|
||||||
|
|
||||||
+ {OPTNTOUT}/{NUMBER} { return(OPT_NTIMEOUT); }
|
|
||||||
+
|
|
||||||
{NUMBER} {
|
|
||||||
master_lval.longtype = atol(master_text);
|
|
||||||
return(NUMBER);
|
|
||||||
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
|
|
||||||
index 68447e0..d488960 100644
|
|
||||||
--- a/man/auto.master.5.in
|
|
||||||
+++ b/man/auto.master.5.in
|
|
||||||
@@ -152,6 +152,11 @@ Enables the use of ramdom selection when choosing a host from a
|
|
||||||
list of replicated servers. This option is applied to this mount
|
|
||||||
only, overriding the global setting that may be specified on the
|
|
||||||
command line.
|
|
||||||
+.TP
|
|
||||||
+.I "\-n, \-\-negative\-timeout <seconds>"
|
|
||||||
+Set the timeout for caching failed key lookups. This option can be
|
|
||||||
+used to override the global default given either on the command line
|
|
||||||
+or in the configuration.
|
|
||||||
.SH GENERAL SYSTEM DEFAULTS CONFIGURATION
|
|
||||||
.P
|
|
||||||
The default value of several general settings may be changed in the
|
|
||||||
@@ -164,6 +169,11 @@ They are:
|
|
||||||
.B TIMEOUT
|
|
||||||
sets the default mount timeout (program default 600).
|
|
||||||
.TP
|
|
||||||
+.B NEGATIVE_TIMEOUT
|
|
||||||
+Set the default timeout for caching failed key lookups (program default
|
|
||||||
+60). If the equivalent command line option is given it will override this
|
|
||||||
+setting.
|
|
||||||
+.TP
|
|
||||||
.B BROWSE_MODE
|
|
||||||
Maps are browsable by default (program default "yes").
|
|
||||||
.TP
|
|
||||||
diff --git a/man/automount.8 b/man/automount.8
|
|
||||||
index 5cd63c7..59ad50e 100644
|
|
||||||
--- a/man/automount.8
|
|
||||||
+++ b/man/automount.8
|
|
||||||
@@ -34,6 +34,9 @@ Set the global minimum timeout, in seconds, until directories
|
|
||||||
are unmounted. The default is 10 minutes. Setting the timeout
|
|
||||||
to zero disables umounts completely.
|
|
||||||
.TP
|
|
||||||
+.I "\-n <seconds>, \-\-negative\-timeout <seconds>"
|
|
||||||
+Set the default timeout for caching failed key lookups. The default is 60 seconds.
|
|
||||||
+.TP
|
|
||||||
.I "\-v, \-\-verbose"
|
|
||||||
Enables logging of general status and progress messages for all
|
|
||||||
autofs managed mounts.
|
|
||||||
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
|
|
||||||
index c093415..1007de4 100644
|
|
||||||
--- a/modules/lookup_file.c
|
|
||||||
+++ b/modules/lookup_file.c
|
|
||||||
@@ -1126,7 +1126,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
rv = cache_update(mc, source, key, NULL, now);
|
|
||||||
if (rv != CHE_FAIL) {
|
|
||||||
me = cache_lookup_distinct(mc, key);
|
|
||||||
- me->status = now + NEGATIVE_TIMEOUT;
|
|
||||||
+ me->status = now + ap->negative_timeout;
|
|
||||||
}
|
|
||||||
cache_unlock(mc);
|
|
||||||
}
|
|
||||||
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
|
|
||||||
index d746e42..1ef420e 100644
|
|
||||||
--- a/modules/lookup_hosts.c
|
|
||||||
+++ b/modules/lookup_hosts.c
|
|
||||||
@@ -138,7 +138,10 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
|
|
||||||
cache_readlock(mc);
|
|
||||||
me = cache_lookup_distinct(mc, name);
|
|
||||||
- if (!me) {
|
|
||||||
+ if (me && me->status >= time(NULL)) {
|
|
||||||
+ cache_unlock(mc);
|
|
||||||
+ return NSS_STATUS_NOTFOUND;
|
|
||||||
+ } else if (!me) {
|
|
||||||
cache_unlock(mc);
|
|
||||||
/*
|
|
||||||
* We haven't read the list of hosts into the
|
|
||||||
@@ -192,10 +195,22 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
ret = ctxt->parse->parse_mount(ap, name, name_len,
|
|
||||||
mapent, ctxt->parse->context);
|
|
||||||
|
|
||||||
- if (!ret)
|
|
||||||
- return NSS_STATUS_SUCCESS;
|
|
||||||
-
|
|
||||||
- return NSS_STATUS_TRYAGAIN;
|
|
||||||
+ if (ret) {
|
|
||||||
+ time_t now = time(NULL);
|
|
||||||
+ int rv = CHE_OK;
|
|
||||||
+
|
|
||||||
+ cache_writelock(mc);
|
|
||||||
+ me = cache_lookup_distinct(mc, name);
|
|
||||||
+ if (!me)
|
|
||||||
+ rv = cache_update(mc, source, name, NULL, now);
|
|
||||||
+ if (rv != CHE_FAIL) {
|
|
||||||
+ me = cache_lookup_distinct(mc, name);
|
|
||||||
+ me->status = now + ap->negative_timeout;
|
|
||||||
+ }
|
|
||||||
+ cache_unlock(mc);
|
|
||||||
+ return NSS_STATUS_TRYAGAIN;
|
|
||||||
+ }
|
|
||||||
+ return NSS_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
/*
|
|
||||||
@@ -267,8 +282,21 @@ done:
|
|
||||||
mapent, ctxt->parse->context);
|
|
||||||
free(mapent);
|
|
||||||
|
|
||||||
- if (ret)
|
|
||||||
+ if (ret) {
|
|
||||||
+ time_t now = time(NULL);
|
|
||||||
+ int rv = CHE_OK;
|
|
||||||
+
|
|
||||||
+ cache_writelock(mc);
|
|
||||||
+ me = cache_lookup_distinct(mc, name);
|
|
||||||
+ if (!me)
|
|
||||||
+ rv = cache_update(mc, source, name, NULL, now);
|
|
||||||
+ if (rv != CHE_FAIL) {
|
|
||||||
+ me = cache_lookup_distinct(mc, name);
|
|
||||||
+ me->status = now + ap->negative_timeout;
|
|
||||||
+ }
|
|
||||||
+ cache_unlock(mc);
|
|
||||||
return NSS_STATUS_TRYAGAIN;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
return NSS_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
|
||||||
index 8719af9..4dea3b2 100644
|
|
||||||
--- a/modules/lookup_ldap.c
|
|
||||||
+++ b/modules/lookup_ldap.c
|
|
||||||
@@ -2125,7 +2125,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
rv = cache_update(mc, source, key, NULL, now);
|
|
||||||
if (rv != CHE_FAIL) {
|
|
||||||
me = cache_lookup_distinct(mc, key);
|
|
||||||
- me->status = now + NEGATIVE_TIMEOUT;
|
|
||||||
+ me->status = now + ap->negative_timeout;
|
|
||||||
}
|
|
||||||
cache_unlock(mc);
|
|
||||||
}
|
|
||||||
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
|
|
||||||
index bcdaeeb..e948c14 100644
|
|
||||||
--- a/modules/lookup_nisplus.c
|
|
||||||
+++ b/modules/lookup_nisplus.c
|
|
||||||
@@ -547,7 +547,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
rv = cache_update(mc, source, key, NULL, now);
|
|
||||||
if (rv != CHE_FAIL) {
|
|
||||||
me = cache_lookup_distinct(mc, key);
|
|
||||||
- me->status = time(NULL) + NEGATIVE_TIMEOUT;
|
|
||||||
+ me->status = time(NULL) + ap->negative_timeout;
|
|
||||||
}
|
|
||||||
cache_unlock(mc);
|
|
||||||
}
|
|
||||||
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
|
|
||||||
index e28168e..7c266d6 100644
|
|
||||||
--- a/modules/lookup_program.c
|
|
||||||
+++ b/modules/lookup_program.c
|
|
||||||
@@ -134,7 +134,10 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
/* Catch installed direct offset triggers */
|
|
||||||
cache_readlock(mc);
|
|
||||||
me = cache_lookup_distinct(mc, name);
|
|
||||||
- if (!me) {
|
|
||||||
+ if (me && me->status >= time(NULL)) {
|
|
||||||
+ cache_unlock(mc);
|
|
||||||
+ return NSS_STATUS_NOTFOUND;
|
|
||||||
+ } else if (!me) {
|
|
||||||
cache_unlock(mc);
|
|
||||||
/*
|
|
||||||
* If there's a '/' in the name and the offset is not in
|
|
||||||
@@ -147,15 +150,33 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cache_unlock(mc);
|
|
||||||
+
|
|
||||||
/* Otherwise we found a valid offset so try mount it */
|
|
||||||
debug(ap->logopt, MODPREFIX "%s -> %s", name, me->mapent);
|
|
||||||
|
|
||||||
- master_source_current_wait(ap->entry);
|
|
||||||
- ap->entry->current = source;
|
|
||||||
-
|
|
||||||
- ret = ctxt->parse->parse_mount(ap, name, name_len,
|
|
||||||
- me->mapent, ctxt->parse->context);
|
|
||||||
- goto out_free;
|
|
||||||
+ /*
|
|
||||||
+ * If this is a request for an offset mount (whose entry
|
|
||||||
+ * must be present in the cache to be valid) or the entry
|
|
||||||
+ * is newer than the negative timeout value then just
|
|
||||||
+ * try and mount it. Otherwise try and remove it and
|
|
||||||
+ * proceed with the program map lookup.
|
|
||||||
+ */
|
|
||||||
+ if (strchr(name, '/') ||
|
|
||||||
+ me->age + ap->negative_timeout > time(NULL)) {
|
|
||||||
+ master_source_current_wait(ap->entry);
|
|
||||||
+ ap->entry->current = source;
|
|
||||||
+ ret = ctxt->parse->parse_mount(ap, name,
|
|
||||||
+ name_len, me->mapent, ctxt->parse->context);
|
|
||||||
+ goto out_free;
|
|
||||||
+ } else {
|
|
||||||
+ if (me->multi) {
|
|
||||||
+ warn(ap->logopt, MODPREFIX
|
|
||||||
+ "unexpected lookup for active multi-mount"
|
|
||||||
+ " key %s, returning fail", name);
|
|
||||||
+ return NSS_STATUS_UNAVAIL;
|
|
||||||
+ }
|
|
||||||
+ cache_delete(mc, name);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
mapent = (char *) malloc(MAPENT_MAX_LEN + 1);
|
|
||||||
@@ -356,8 +377,21 @@ out_free:
|
|
||||||
if (mapent)
|
|
||||||
free(mapent);
|
|
||||||
|
|
||||||
- if (ret)
|
|
||||||
+ if (ret) {
|
|
||||||
+ time_t now = time(NULL);
|
|
||||||
+ int rv = CHE_OK;
|
|
||||||
+
|
|
||||||
+ cache_writelock(mc);
|
|
||||||
+ me = cache_lookup_distinct(mc, name);
|
|
||||||
+ if (!me)
|
|
||||||
+ rv = cache_update(mc, source, name, NULL, now);
|
|
||||||
+ if (rv != CHE_FAIL) {
|
|
||||||
+ me = cache_lookup_distinct(mc, name);
|
|
||||||
+ me->status = now + ap->negative_timeout;
|
|
||||||
+ }
|
|
||||||
+ cache_unlock(mc);
|
|
||||||
return NSS_STATUS_UNAVAIL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
return NSS_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
|
|
||||||
index 7ba6940..6c20145 100644
|
|
||||||
--- a/modules/lookup_yp.c
|
|
||||||
+++ b/modules/lookup_yp.c
|
|
||||||
@@ -639,7 +639,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
rv = cache_update(mc, source, key, NULL, now);
|
|
||||||
if (rv != CHE_FAIL) {
|
|
||||||
me = cache_lookup_distinct(mc, key);
|
|
||||||
- me->status = now + NEGATIVE_TIMEOUT;
|
|
||||||
+ me->status = now + ap->negative_timeout;
|
|
||||||
}
|
|
||||||
cache_unlock(mc);
|
|
||||||
}
|
|
||||||
diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in
|
|
||||||
index f01ee5f..636763a 100644
|
|
||||||
--- a/redhat/autofs.sysconfig.in
|
|
||||||
+++ b/redhat/autofs.sysconfig.in
|
|
||||||
@@ -9,6 +9,11 @@
|
|
||||||
#
|
|
||||||
TIMEOUT=300
|
|
||||||
#
|
|
||||||
+# NEGATIVE_TIMEOUT - set the default negative timeout for
|
|
||||||
+# failed mount attempts (default 60).
|
|
||||||
+#
|
|
||||||
+#NEGATIVE_TIMEOUT=60
|
|
||||||
+#
|
|
||||||
# BROWSE_MODE - maps are browsable by default.
|
|
||||||
#
|
|
||||||
BROWSE_MODE="no"
|
|
||||||
diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
|
|
||||||
index 028341c..086ba4f 100644
|
|
||||||
--- a/samples/autofs.conf.default.in
|
|
||||||
+++ b/samples/autofs.conf.default.in
|
|
||||||
@@ -9,6 +9,11 @@
|
|
||||||
#
|
|
||||||
TIMEOUT=300
|
|
||||||
#
|
|
||||||
+# NEGATIVE_TIMEOUT - set the default negative timeout for
|
|
||||||
+# failed mount attempts (default 60).
|
|
||||||
+#
|
|
||||||
+#NEGATIVE_TIMEOUT=60
|
|
||||||
+#
|
|
||||||
# BROWSE_MODE - maps are browsable by default.
|
|
||||||
#
|
|
||||||
BROWSE_MODE="no"
|
|
@ -1,59 +0,0 @@
|
|||||||
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
|
|
||||||
index a9a4c75..1f8fa15 100644
|
|
||||||
--- a/modules/lookup_hosts.c
|
|
||||||
+++ b/modules/lookup_hosts.c
|
|
||||||
@@ -215,7 +215,7 @@ done:
|
|
||||||
if (mapent) {
|
|
||||||
int len = strlen(mapent) + 1;
|
|
||||||
|
|
||||||
- len += strlen(name) + 2*strlen(exp->ex_dir) + 3;
|
|
||||||
+ len += strlen(name) + 2*(strlen(exp->ex_dir) + 2) + 3;
|
|
||||||
mapent = realloc(mapent, len);
|
|
||||||
if (!mapent) {
|
|
||||||
char *estr;
|
|
||||||
@@ -224,10 +224,11 @@ done:
|
|
||||||
rpc_exports_free(exp);
|
|
||||||
return NSS_STATUS_UNAVAIL;
|
|
||||||
}
|
|
||||||
- strcat(mapent, " ");
|
|
||||||
+ strcat(mapent, " \"");
|
|
||||||
strcat(mapent, exp->ex_dir);
|
|
||||||
+ strcat(mapent, "\"");
|
|
||||||
} else {
|
|
||||||
- int len = 2*strlen(exp->ex_dir) + strlen(name) + 3;
|
|
||||||
+ int len = 2*(strlen(exp->ex_dir) + 2) + strlen(name) + 3;
|
|
||||||
|
|
||||||
mapent = malloc(len);
|
|
||||||
if (!mapent) {
|
|
||||||
@@ -237,12 +238,15 @@ done:
|
|
||||||
rpc_exports_free(exp);
|
|
||||||
return NSS_STATUS_UNAVAIL;
|
|
||||||
}
|
|
||||||
- strcpy(mapent, exp->ex_dir);
|
|
||||||
+ strcpy(mapent, "\"");
|
|
||||||
+ strcat(mapent, exp->ex_dir);
|
|
||||||
+ strcat(mapent, "\"");
|
|
||||||
}
|
|
||||||
- strcat(mapent, " ");
|
|
||||||
+ strcat(mapent, " \"");
|
|
||||||
strcat(mapent, name);
|
|
||||||
strcat(mapent, ":");
|
|
||||||
strcat(mapent, exp->ex_dir);
|
|
||||||
+ strcat(mapent, "\"");
|
|
||||||
|
|
||||||
exp = exp->ex_next;
|
|
||||||
}
|
|
||||||
@@ -260,13 +264,9 @@ done:
|
|
||||||
cache_update(mc, source, name, mapent, now);
|
|
||||||
cache_unlock(mc);
|
|
||||||
|
|
||||||
- debug(LOGOPT_ANY, "source wait");
|
|
||||||
-
|
|
||||||
master_source_current_wait(ap->entry);
|
|
||||||
ap->entry->current = source;
|
|
||||||
|
|
||||||
- debug(LOGOPT_ANY, "do parse_mount");
|
|
||||||
-
|
|
||||||
ret = ctxt->parse->parse_mount(ap, name, name_len,
|
|
||||||
mapent, ctxt->parse->context);
|
|
||||||
free(mapent);
|
|
@ -1,14 +0,0 @@
|
|||||||
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
|
|
||||||
index ad19f34..3627f44 100644
|
|
||||||
--- a/lib/parse_subs.c
|
|
||||||
+++ b/lib/parse_subs.c
|
|
||||||
@@ -297,7 +297,8 @@ char *sanitize_path(const char *path, int origlen, unsigned int type, unsigned i
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (origlen > 1 && *(cp - 1) == '/')
|
|
||||||
+ /* Remove trailing / but watch out for a quoted / alone */
|
|
||||||
+ if (strlen(cp) > 1 && origlen > 1 && *(cp - 1) == '/')
|
|
||||||
*(cp - 1) = '\0';
|
|
||||||
|
|
||||||
return s_path;
|
|
@ -1,247 +0,0 @@
|
|||||||
diff -up autofs-5.0.2/include/replicated.h.random-selection-fix autofs-5.0.2/include/replicated.h
|
|
||||||
--- autofs-5.0.2/include/replicated.h.random-selection-fix 2007-06-18 15:18:08.000000000 +0800
|
|
||||||
+++ autofs-5.0.2/include/replicated.h 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
@@ -63,7 +63,7 @@ struct host {
|
|
||||||
void seed_random(void);
|
|
||||||
void free_host_list(struct host **);
|
|
||||||
int parse_location(struct host **, const char *);
|
|
||||||
-int prune_host_list(struct host **, unsigned int, const char *);
|
|
||||||
+int prune_host_list(struct host **, unsigned int, const char *, unsigned int);
|
|
||||||
void dump_host_list(struct host *);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
diff -up autofs-5.0.2/include/automount.h.random-selection-fix autofs-5.0.2/include/automount.h
|
|
||||||
--- autofs-5.0.2/include/automount.h.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/include/automount.h 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
@@ -448,6 +448,8 @@ struct autofs_point {
|
|
||||||
enum states state; /* Current state */
|
|
||||||
int state_pipe[2]; /* State change router pipe */
|
|
||||||
unsigned dir_created; /* Directory created for this mount? */
|
|
||||||
+ unsigned random_selection; /* Use random policy when selecting a
|
|
||||||
+ * host from which to mount */
|
|
||||||
struct autofs_point *parent; /* Owner of mounts list for submount */
|
|
||||||
pthread_mutex_t mounts_mutex; /* Protect mount lists */
|
|
||||||
pthread_cond_t mounts_cond; /* Submounts condition variable */
|
|
||||||
diff -up autofs-5.0.2/modules/mount_nfs.c.random-selection-fix autofs-5.0.2/modules/mount_nfs.c
|
|
||||||
--- autofs-5.0.2/modules/mount_nfs.c.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/modules/mount_nfs.c 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
@@ -137,7 +137,7 @@ int mount_mount(struct autofs_point *ap,
|
|
||||||
warn(ap->logopt, MODPREFIX "no hosts available");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
- prune_host_list(&hosts, vers, nfsoptions);
|
|
||||||
+ prune_host_list(&hosts, vers, nfsoptions, ap->random_selection);
|
|
||||||
|
|
||||||
if (!hosts) {
|
|
||||||
warn(ap->logopt, MODPREFIX "no hosts available");
|
|
||||||
diff -up autofs-5.0.2/modules/replicated.c.random-selection-fix autofs-5.0.2/modules/replicated.c
|
|
||||||
--- autofs-5.0.2/modules/replicated.c.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/modules/replicated.c 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
@@ -74,8 +74,6 @@
|
|
||||||
#define max(x, y) (x >= y ? x : y)
|
|
||||||
#define mmax(x, y, z) (max(x, y) == x ? max(x, z) : max(y, z))
|
|
||||||
|
|
||||||
-extern unsigned int random_selection;
|
|
||||||
-
|
|
||||||
void seed_random(void)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
@@ -392,7 +390,7 @@ static unsigned short get_port_option(co
|
|
||||||
static unsigned int get_nfs_info(struct host *host,
|
|
||||||
struct conn_info *pm_info, struct conn_info *rpc_info,
|
|
||||||
const char *proto, unsigned int version,
|
|
||||||
- const char *options)
|
|
||||||
+ const char *options, unsigned int random_selection)
|
|
||||||
{
|
|
||||||
char *have_port_opt = options ? strstr(options, "port=") : NULL;
|
|
||||||
struct pmap parms;
|
|
||||||
@@ -535,7 +533,9 @@ done_ver:
|
|
||||||
return supported;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int get_vers_and_cost(struct host *host, unsigned int version, const char *options)
|
|
||||||
+static int get_vers_and_cost(struct host *host,
|
|
||||||
+ unsigned int version, const char *options,
|
|
||||||
+ unsigned int random_selection)
|
|
||||||
{
|
|
||||||
struct conn_info pm_info, rpc_info;
|
|
||||||
time_t timeout = RPC_TIMEOUT;
|
|
||||||
@@ -559,7 +559,9 @@ static int get_vers_and_cost(struct host
|
|
||||||
vers &= version;
|
|
||||||
|
|
||||||
if (version & UDP_REQUESTED) {
|
|
||||||
- supported = get_nfs_info(host, &pm_info, &rpc_info, "udp", vers, options);
|
|
||||||
+ supported = get_nfs_info(host,
|
|
||||||
+ &pm_info, &rpc_info, "udp", vers,
|
|
||||||
+ options, random_selection);
|
|
||||||
if (supported) {
|
|
||||||
ret = 1;
|
|
||||||
host->version |= (supported << 8);
|
|
||||||
@@ -567,7 +569,9 @@ static int get_vers_and_cost(struct host
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version & TCP_REQUESTED) {
|
|
||||||
- supported = get_nfs_info(host, &pm_info, &rpc_info, "tcp", vers, options);
|
|
||||||
+ supported = get_nfs_info(host,
|
|
||||||
+ &pm_info, &rpc_info, "tcp", vers,
|
|
||||||
+ options, random_selection);
|
|
||||||
if (supported) {
|
|
||||||
ret = 1;
|
|
||||||
host->version |= supported;
|
|
||||||
@@ -577,7 +581,9 @@ static int get_vers_and_cost(struct host
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int get_supported_ver_and_cost(struct host *host, unsigned int version, const char *options)
|
|
||||||
+static int get_supported_ver_and_cost(struct host *host,
|
|
||||||
+ unsigned int version, const char *options,
|
|
||||||
+ unsigned int random_selection)
|
|
||||||
{
|
|
||||||
char *have_port_opt = options ? strstr(options, "port=") : NULL;
|
|
||||||
struct conn_info pm_info, rpc_info;
|
|
||||||
@@ -695,7 +701,9 @@ done:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int prune_host_list(struct host **list, unsigned int vers, const char *options)
|
|
||||||
+int prune_host_list(struct host **list,
|
|
||||||
+ unsigned int vers, const char *options,
|
|
||||||
+ unsigned int random_selection)
|
|
||||||
{
|
|
||||||
struct host *this, *last, *first;
|
|
||||||
struct host *new = NULL;
|
|
||||||
@@ -734,7 +742,8 @@ int prune_host_list(struct host **list,
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (this->name) {
|
|
||||||
- status = get_vers_and_cost(this, vers, options);
|
|
||||||
+ status = get_vers_and_cost(this, vers,
|
|
||||||
+ options, random_selection);
|
|
||||||
if (!status) {
|
|
||||||
if (this == first) {
|
|
||||||
first = next;
|
|
||||||
@@ -824,7 +833,9 @@ int prune_host_list(struct host **list,
|
|
||||||
remove_host(list, this);
|
|
||||||
add_host(&new, this);
|
|
||||||
} else {
|
|
||||||
- status = get_supported_ver_and_cost(this, selected_version, options);
|
|
||||||
+ status = get_supported_ver_and_cost(this,
|
|
||||||
+ selected_version, options,
|
|
||||||
+ random_selection);
|
|
||||||
if (status) {
|
|
||||||
this->version = selected_version;
|
|
||||||
remove_host(list, this);
|
|
||||||
diff -up autofs-5.0.2/daemon/automount.c.random-selection-fix autofs-5.0.2/daemon/automount.c
|
|
||||||
--- autofs-5.0.2/daemon/automount.c.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/daemon/automount.c 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
@@ -52,9 +52,9 @@ const char *confdir = AUTOFS_CONF_DIR; /
|
|
||||||
|
|
||||||
const char *global_options; /* Global option, from command line */
|
|
||||||
|
|
||||||
-static char *pid_file = NULL; /* File in which to keep pid */
|
|
||||||
-unsigned int random_selection; /* use random policy when selecting
|
|
||||||
- * which multi-mount host to mount */
|
|
||||||
+static char *pid_file = NULL; /* File in which to keep pid */
|
|
||||||
+unsigned int global_random_selection; /* use random policy when selecting
|
|
||||||
+ * which multi-mount host to mount */
|
|
||||||
static int start_pipefd[2];
|
|
||||||
static int st_stat = 0;
|
|
||||||
static int *pst_stat = &st_stat;
|
|
||||||
@@ -1469,7 +1469,7 @@ int main(int argc, char *argv[])
|
|
||||||
timeout = defaults_get_timeout();
|
|
||||||
ghost = defaults_get_browse_mode();
|
|
||||||
logging = defaults_get_logging();
|
|
||||||
- random_selection = 0;
|
|
||||||
+ global_random_selection = 0;
|
|
||||||
global_options = NULL;
|
|
||||||
have_global_options = 0;
|
|
||||||
foreground = 0;
|
|
||||||
@@ -1510,7 +1510,7 @@ int main(int argc, char *argv[])
|
|
||||||
exit(0);
|
|
||||||
|
|
||||||
case 'r':
|
|
||||||
- random_selection = 1;
|
|
||||||
+ global_random_selection = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'O':
|
|
||||||
diff -up autofs-5.0.2/lib/master_tok.l.random-selection-fix autofs-5.0.2/lib/master_tok.l
|
|
||||||
--- autofs-5.0.2/lib/master_tok.l.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/lib/master_tok.l 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
@@ -324,6 +324,7 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--
|
|
||||||
-g|--ghost|-?browse { return(OPT_GHOST); }
|
|
||||||
-v|--verbose { return(OPT_VERBOSE); }
|
|
||||||
-d|--debug { return(OPT_DEBUG); }
|
|
||||||
+ -r|--random-multimount-selection { return(OPT_RANDOM); }
|
|
||||||
|
|
||||||
{OPTWS}","{OPTWS} { return(COMMA); }
|
|
||||||
|
|
||||||
diff -up autofs-5.0.2/lib/master_parse.y.random-selection-fix autofs-5.0.2/lib/master_parse.y
|
|
||||||
--- autofs-5.0.2/lib/master_parse.y.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/lib/master_parse.y 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
@@ -56,6 +56,8 @@ static char *type;
|
|
||||||
static char *format;
|
|
||||||
static long timeout;
|
|
||||||
static unsigned ghost;
|
|
||||||
+extern unsigned global_random_selection;
|
|
||||||
+static unsigned random_selection;
|
|
||||||
static char **tmp_argv;
|
|
||||||
static int tmp_argc;
|
|
||||||
static char **local_argv;
|
|
||||||
@@ -93,7 +95,7 @@ static int master_fprintf(FILE *, char *
|
|
||||||
|
|
||||||
%token COMMENT
|
|
||||||
%token MAP
|
|
||||||
-%token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG
|
|
||||||
+%token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG OPT_RANDOM
|
|
||||||
%token COLON COMMA NL DDASH
|
|
||||||
%type <strtype> map
|
|
||||||
%type <strtype> options
|
|
||||||
@@ -174,6 +176,7 @@ line:
|
|
||||||
| PATH COLON { master_notify($1); YYABORT; }
|
|
||||||
| PATH OPTION { master_notify($2); YYABORT; }
|
|
||||||
| PATH NILL { master_notify($2); YYABORT; }
|
|
||||||
+ | PATH OPT_RANDOM { master_notify($1); YYABORT; }
|
|
||||||
| PATH OPT_DEBUG { master_notify($1); YYABORT; }
|
|
||||||
| PATH OPT_TIMEOUT { master_notify($1); YYABORT; }
|
|
||||||
| PATH OPT_GHOST { master_notify($1); YYABORT; }
|
|
||||||
@@ -543,6 +546,7 @@ daemon_option: OPT_TIMEOUT NUMBER { time
|
|
||||||
| OPT_GHOST { ghost = 1; }
|
|
||||||
| OPT_VERBOSE { verbose = 1; }
|
|
||||||
| OPT_DEBUG { debug = 1; }
|
|
||||||
+ | OPT_RANDOM { random_selection = 1; }
|
|
||||||
;
|
|
||||||
|
|
||||||
mount_option: OPTION
|
|
||||||
@@ -600,6 +604,7 @@ static void local_init_vars(void)
|
|
||||||
debug = 0;
|
|
||||||
timeout = -1;
|
|
||||||
ghost = defaults_get_browse_mode();
|
|
||||||
+ random_selection = global_random_selection;
|
|
||||||
tmp_argv = NULL;
|
|
||||||
tmp_argc = 0;
|
|
||||||
local_argv = NULL;
|
|
||||||
@@ -790,6 +795,7 @@ int master_parse_entry(const char *buffe
|
|
||||||
}
|
|
||||||
set_mnt_logging(ap);
|
|
||||||
}
|
|
||||||
+ entry->ap->random_selection = random_selection;
|
|
||||||
|
|
||||||
/*
|
|
||||||
source = master_find_map_source(entry, type, format,
|
|
||||||
diff -up autofs-5.0.2/man/auto.master.5.in.random-selection-fix autofs-5.0.2/man/auto.master.5.in
|
|
||||||
--- autofs-5.0.2/man/auto.master.5.in.random-selection-fix 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/man/auto.master.5.in 2007-11-20 14:55:28.000000000 +0900
|
|
||||||
@@ -146,6 +146,12 @@ to prevent symlinking of local NFS mount
|
|
||||||
prevent bind mounting of local NFS filesystems as well. If you need to
|
|
||||||
prevent bind mounting for only specific entrys in a map then this
|
|
||||||
can be done by adding the "port=" mount option to the given entries.
|
|
||||||
+.TP
|
|
||||||
+.I "\-r, \-\-random-multimount-selection"
|
|
||||||
+Enables the use of ramdom selection when choosing a host from a
|
|
||||||
+list of replicated servers. This option is applied to this mount
|
|
||||||
+only, overriding the global setting that may be specified on the
|
|
||||||
+command line.
|
|
||||||
.SH GENERAL SYSTEM DEFAULTS CONFIGURATION
|
|
||||||
.P
|
|
||||||
The default value of several general settings may be changed in the
|
|
@ -1,611 +0,0 @@
|
|||||||
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
|
|
||||||
index 831d456..d79a94f 100644
|
|
||||||
--- a/lib/rpc_subs.c
|
|
||||||
+++ b/lib/rpc_subs.c
|
|
||||||
@@ -52,10 +52,7 @@
|
|
||||||
/* Get numeric value of the n bits starting at position p */
|
|
||||||
#define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n))
|
|
||||||
|
|
||||||
-static char *domain = NULL;
|
|
||||||
-
|
|
||||||
inline void dump_core(void);
|
|
||||||
-static pthread_mutex_t networks_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a UDP RPC client
|
|
||||||
@@ -764,573 +761,6 @@ void rpc_exports_free(exports list)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int masked_match(const char *addr, const char *mask)
|
|
||||||
-{
|
|
||||||
- char buf[MAX_IFC_BUF], *ptr;
|
|
||||||
- struct sockaddr_in saddr;
|
|
||||||
- struct sockaddr_in6 saddr6;
|
|
||||||
- struct ifconf ifc;
|
|
||||||
- struct ifreq *ifr;
|
|
||||||
- int sock, cl_flags, ret, i, is_ipv4, is_ipv6;
|
|
||||||
- unsigned int msize;
|
|
||||||
-
|
|
||||||
- sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
- if (sock < 0) {
|
|
||||||
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
- error(LOGOPT_ANY, "socket creation failed: %s", estr);
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if ((cl_flags = fcntl(sock, F_GETFD, 0)) != -1) {
|
|
||||||
- cl_flags |= FD_CLOEXEC;
|
|
||||||
- fcntl(sock, F_SETFD, cl_flags);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ifc.ifc_len = sizeof(buf);
|
|
||||||
- ifc.ifc_req = (struct ifreq *) buf;
|
|
||||||
- ret = ioctl(sock, SIOCGIFCONF, &ifc);
|
|
||||||
- if (ret == -1) {
|
|
||||||
- close(sock);
|
|
||||||
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
- error(LOGOPT_ANY, "ioctl: %s", estr);
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- is_ipv4 = is_ipv6 = 0;
|
|
||||||
- is_ipv4 = inet_pton(AF_INET, addr, &saddr.sin_addr);
|
|
||||||
- if (!is_ipv4)
|
|
||||||
- is_ipv6 = inet_pton(AF_INET6, addr, &saddr6.sin6_addr);
|
|
||||||
-
|
|
||||||
- if (strchr(mask, '.')) {
|
|
||||||
- struct sockaddr_in maddr;
|
|
||||||
- uint32_t ma;
|
|
||||||
- int i = 0;
|
|
||||||
-
|
|
||||||
- ret = inet_aton(mask, &maddr.sin_addr);
|
|
||||||
- if (!ret) {
|
|
||||||
- close(sock);
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ma = ntohl((uint32_t) maddr.sin_addr.s_addr);
|
|
||||||
- while (!(ma & 1)) {
|
|
||||||
- i++;
|
|
||||||
- ma = ma >> 1;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- msize = i;
|
|
||||||
- } else
|
|
||||||
- msize = atoi(mask);
|
|
||||||
-
|
|
||||||
- i = 0;
|
|
||||||
- ptr = (char *) &ifc.ifc_buf[0];
|
|
||||||
-
|
|
||||||
- while (ptr < buf + ifc.ifc_len) {
|
|
||||||
- ifr = (struct ifreq *) ptr;
|
|
||||||
-
|
|
||||||
- switch (ifr->ifr_addr.sa_family) {
|
|
||||||
- case AF_INET:
|
|
||||||
- {
|
|
||||||
- struct sockaddr_in *if_addr;
|
|
||||||
- uint32_t m, ia, ha;
|
|
||||||
-
|
|
||||||
- if (!is_ipv4 || msize > 32)
|
|
||||||
- break;
|
|
||||||
-
|
|
||||||
- m = -1;
|
|
||||||
- m = m << (32 - msize);
|
|
||||||
- ha = ntohl((uint32_t) saddr.sin_addr.s_addr);
|
|
||||||
-
|
|
||||||
- if_addr = (struct sockaddr_in *) &ifr->ifr_addr;
|
|
||||||
- ia = ntohl((uint32_t) if_addr->sin_addr.s_addr);
|
|
||||||
-
|
|
||||||
- if ((ia & m) == (ha & m)) {
|
|
||||||
- close(sock);
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* glibc rpc only understands IPv4 atm */
|
|
||||||
- case AF_INET6:
|
|
||||||
- break;
|
|
||||||
-
|
|
||||||
- default:
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- i++;
|
|
||||||
- ptr = (char *) &ifc.ifc_req[i];
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- close(sock);
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-/*
|
|
||||||
- * This function has been adapted from the match_patern function
|
|
||||||
- * found in OpenSSH and is used in accordance with the copyright
|
|
||||||
- * notice found their.
|
|
||||||
- *
|
|
||||||
- * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland.
|
|
||||||
- */
|
|
||||||
-/*
|
|
||||||
- * Returns true if the given string matches the pattern (which
|
|
||||||
- * may contain ? and * as wildcards), and zero if it does not
|
|
||||||
- * match.
|
|
||||||
- */
|
|
||||||
-static int pattern_match(const char *s, const char *pattern)
|
|
||||||
-{
|
|
||||||
- for (;;) {
|
|
||||||
- /* If at end of pattern, accept if also at end of string. */
|
|
||||||
- if (!*pattern)
|
|
||||||
- return !*s;
|
|
||||||
-
|
|
||||||
- if (*pattern == '*') {
|
|
||||||
- /* Skip the asterisk. */
|
|
||||||
- pattern++;
|
|
||||||
-
|
|
||||||
- /* If at end of pattern, accept immediately. */
|
|
||||||
- if (!*pattern)
|
|
||||||
- return 1;
|
|
||||||
-
|
|
||||||
- /* If next character in pattern is known, optimize. */
|
|
||||||
- if (*pattern != '?' && *pattern != '*') {
|
|
||||||
- /*
|
|
||||||
- * Look instances of the next character in
|
|
||||||
- * pattern, and try to match starting from
|
|
||||||
- * those.
|
|
||||||
- */
|
|
||||||
- for (; *s; s++)
|
|
||||||
- if (*s == *pattern &&
|
|
||||||
- pattern_match(s + 1, pattern + 1))
|
|
||||||
- return 1;
|
|
||||||
-
|
|
||||||
- /* Failed. */
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
- /*
|
|
||||||
- * Move ahead one character at a time and try to
|
|
||||||
- * match at each position.
|
|
||||||
- */
|
|
||||||
- for (; *s; s++)
|
|
||||||
- if (pattern_match(s, pattern))
|
|
||||||
- return 1;
|
|
||||||
- /* Failed. */
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
- /*
|
|
||||||
- * There must be at least one more character in the string.
|
|
||||||
- * If we are at the end, fail.
|
|
||||||
- */
|
|
||||||
- if (!*s)
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- /* Check if the next character of the string is acceptable. */
|
|
||||||
- if (*pattern != '?' && *pattern != *s)
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- /* Move to the next character, both in string and in pattern. */
|
|
||||||
- s++;
|
|
||||||
- pattern++;
|
|
||||||
- }
|
|
||||||
- /* NOTREACHED */
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int name_match(const char *name, const char *pattern)
|
|
||||||
-{
|
|
||||||
- int ret;
|
|
||||||
-
|
|
||||||
- if (strchr(pattern, '*') || strchr(pattern, '?'))
|
|
||||||
- ret = pattern_match(name, pattern);
|
|
||||||
- else {
|
|
||||||
- ret = !memcmp(name, pattern, strlen(pattern));
|
|
||||||
- /* Name could still be a netgroup (Solaris) */
|
|
||||||
- if (!ret)
|
|
||||||
- ret = innetgr(pattern, name, NULL, domain);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return ret;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int fqdn_match(const char *pattern)
|
|
||||||
-{
|
|
||||||
- char buf[MAX_IFC_BUF], *ptr;
|
|
||||||
- struct ifconf ifc;
|
|
||||||
- struct ifreq *ifr;
|
|
||||||
- int sock, cl_flags, ret, i;
|
|
||||||
- char fqdn[NI_MAXHOST + 1];
|
|
||||||
-
|
|
||||||
- sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
- if (sock < 0) {
|
|
||||||
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
- error(LOGOPT_ANY, "socket creation failed: %s", estr);
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if ((cl_flags = fcntl(sock, F_GETFD, 0)) != -1) {
|
|
||||||
- cl_flags |= FD_CLOEXEC;
|
|
||||||
- fcntl(sock, F_SETFD, cl_flags);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ifc.ifc_len = sizeof(buf);
|
|
||||||
- ifc.ifc_req = (struct ifreq *) buf;
|
|
||||||
- ret = ioctl(sock, SIOCGIFCONF, &ifc);
|
|
||||||
- if (ret == -1) {
|
|
||||||
- close(sock);
|
|
||||||
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
||||||
- error(LOGOPT_ANY, "ioctl: %s", estr);
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- i = 0;
|
|
||||||
- ptr = (char *) &ifc.ifc_buf[0];
|
|
||||||
-
|
|
||||||
- while (ptr < buf + ifc.ifc_len) {
|
|
||||||
- ifr = (struct ifreq *) ptr;
|
|
||||||
-
|
|
||||||
- switch (ifr->ifr_addr.sa_family) {
|
|
||||||
- case AF_INET:
|
|
||||||
- {
|
|
||||||
- socklen_t slen = sizeof(struct sockaddr);
|
|
||||||
-
|
|
||||||
- ret = getnameinfo(&ifr->ifr_addr, slen, fqdn,
|
|
||||||
- NI_MAXHOST, NULL, 0, NI_NAMEREQD);
|
|
||||||
- if (!ret) {
|
|
||||||
- ret = name_match(fqdn, pattern);
|
|
||||||
- if (ret) {
|
|
||||||
- close(sock);
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* glibc rpc only understands IPv4 atm */
|
|
||||||
- case AF_INET6:
|
|
||||||
- break;
|
|
||||||
-
|
|
||||||
- default:
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- i++;
|
|
||||||
- ptr = (char *) &ifc.ifc_req[i];
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- close(sock);
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int string_match(const char *myname, const char *pattern)
|
|
||||||
-{
|
|
||||||
- struct addrinfo hints, *ni;
|
|
||||||
- int ret;
|
|
||||||
-
|
|
||||||
- /* Try simple name match first */
|
|
||||||
- ret = name_match(myname, pattern);
|
|
||||||
- if (ret)
|
|
||||||
- goto done;
|
|
||||||
-
|
|
||||||
- memset(&hints, 0, sizeof(hints));
|
|
||||||
- hints.ai_flags = AI_CANONNAME;
|
|
||||||
- hints.ai_family = 0;
|
|
||||||
- hints.ai_socktype = 0;
|
|
||||||
-
|
|
||||||
- /* See if our canonical name matches */
|
|
||||||
- if (getaddrinfo(myname, NULL, &hints, &ni) == 0) {
|
|
||||||
- ret = name_match(ni->ai_canonname, pattern);
|
|
||||||
- freeaddrinfo(ni);
|
|
||||||
- } else
|
|
||||||
- warn(LOGOPT_ANY, "name lookup failed: %s", gai_strerror(ret));
|
|
||||||
- if (ret)
|
|
||||||
- goto done;
|
|
||||||
-
|
|
||||||
- /* Lastly see if the name of an interfaces matches */
|
|
||||||
- ret = fqdn_match(pattern);
|
|
||||||
-done:
|
|
||||||
- return ret;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static unsigned int inet_get_net_len(uint32_t net)
|
|
||||||
-{
|
|
||||||
- int i;
|
|
||||||
-
|
|
||||||
- for (i = 0; i < 32; i += 8) {
|
|
||||||
- if (getbits(net, i + 7, 8))
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return (unsigned int) 32 - i;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static char *inet_fill_net(const char *net_num, char *net)
|
|
||||||
-{
|
|
||||||
- char *np;
|
|
||||||
- unsigned int dots = 3;
|
|
||||||
-
|
|
||||||
- if (strlen(net_num) > INET_ADDRSTRLEN)
|
|
||||||
- return NULL;
|
|
||||||
-
|
|
||||||
- if (!isdigit(*net_num))
|
|
||||||
- return NULL;
|
|
||||||
-
|
|
||||||
- *net = '\0';
|
|
||||||
- strcpy(net, net_num);
|
|
||||||
-
|
|
||||||
- np = net;
|
|
||||||
- while (*np++) {
|
|
||||||
- if (*np == '.') {
|
|
||||||
- np++;
|
|
||||||
- dots--;
|
|
||||||
- if (!*np && dots)
|
|
||||||
- strcat(net, "0");
|
|
||||||
- continue;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if ((*np && !isdigit(*np)) || dots < 0) {
|
|
||||||
- *net = '\0';
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- while (dots--)
|
|
||||||
- strcat(net, ".0");
|
|
||||||
-
|
|
||||||
- return net;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int match_network(const char *network)
|
|
||||||
-{
|
|
||||||
- struct netent *pnent, nent;
|
|
||||||
- const char *pcnet;
|
|
||||||
- char *net, cnet[MAX_NETWORK_LEN], mask[4], *pmask;
|
|
||||||
- unsigned int size;
|
|
||||||
- size_t l_network = strlen(network) + 1;
|
|
||||||
- int status;
|
|
||||||
-
|
|
||||||
- if (l_network > MAX_NETWORK_LEN) {
|
|
||||||
- error(LOGOPT_ANY,
|
|
||||||
- "match string \"%s\" too long", network);
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- net = alloca(l_network);
|
|
||||||
- if (!net)
|
|
||||||
- return 0;
|
|
||||||
- memset(net, 0, l_network);
|
|
||||||
- strcpy(net, network);
|
|
||||||
-
|
|
||||||
- if ((pmask = strchr(net, '/')))
|
|
||||||
- *pmask++ = '\0';
|
|
||||||
-
|
|
||||||
- status = pthread_mutex_lock(&networks_mutex);
|
|
||||||
- if (status)
|
|
||||||
- fatal(status);
|
|
||||||
-
|
|
||||||
- pnent = getnetbyname(net);
|
|
||||||
- if (pnent)
|
|
||||||
- memcpy(&nent, pnent, sizeof(struct netent));
|
|
||||||
-
|
|
||||||
- status = pthread_mutex_unlock(&networks_mutex);
|
|
||||||
- if (status)
|
|
||||||
- fatal(status);
|
|
||||||
-
|
|
||||||
- if (pnent) {
|
|
||||||
- uint32_t n_net;
|
|
||||||
-
|
|
||||||
- switch (nent.n_addrtype) {
|
|
||||||
- case AF_INET:
|
|
||||||
- n_net = ntohl(nent.n_net);
|
|
||||||
- pcnet = inet_ntop(AF_INET, &n_net, cnet, INET_ADDRSTRLEN);
|
|
||||||
- if (!pcnet)
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- if (!pmask) {
|
|
||||||
- size = inet_get_net_len(nent.n_net);
|
|
||||||
- if (!size)
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
- break;
|
|
||||||
-
|
|
||||||
- case AF_INET6:
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- default:
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
- } else {
|
|
||||||
- int ret;
|
|
||||||
-
|
|
||||||
- if (strchr(net, ':')) {
|
|
||||||
- return 0;
|
|
||||||
- } else {
|
|
||||||
- struct in_addr addr;
|
|
||||||
-
|
|
||||||
- pcnet = inet_fill_net(net, cnet);
|
|
||||||
- if (!pcnet)
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- ret = inet_pton(AF_INET, pcnet, &addr);
|
|
||||||
- if (ret <= 0)
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- if (!pmask) {
|
|
||||||
- uint32_t nl_addr = htonl(addr.s_addr);
|
|
||||||
- size = inet_get_net_len(nl_addr);
|
|
||||||
- if (!size)
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (!pmask) {
|
|
||||||
- if (sprintf(mask, "%u", size) <= 0)
|
|
||||||
- return 0;
|
|
||||||
- pmask = mask;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- debug(LOGOPT_ANY, "pcnet %s pmask %s", pcnet, pmask);
|
|
||||||
-
|
|
||||||
- return masked_match(pcnet, pmask);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-/*
|
|
||||||
- * Two export formats need to be understood to cater for different
|
|
||||||
- * NFS server exports.
|
|
||||||
- *
|
|
||||||
- * (host|wildcard|network[/mask]|@netgroup)
|
|
||||||
- *
|
|
||||||
- * A host name which can be cannonical.
|
|
||||||
- * A wildcard host name containing "*" and "?" with the usual meaning.
|
|
||||||
- * A network in numbers and dots form with optional mask given as
|
|
||||||
- * either a length or as numbers and dots.
|
|
||||||
- * A netgroup identified by the prefix "@".
|
|
||||||
- *
|
|
||||||
- * [-](host|domain suffix|netgroup|@network[/mask])
|
|
||||||
- *
|
|
||||||
- * A host name which can be cannonical.
|
|
||||||
- * A domain suffix identified by a leading "." which will match all
|
|
||||||
- * hosts in the given domain.
|
|
||||||
- * A netgroup.
|
|
||||||
- * A network identified by the prefix "@" given in numbers and dots
|
|
||||||
- * form or as a network name with optional mask given as either a
|
|
||||||
- * length or as numbers and dots.
|
|
||||||
- * A "-" prefix can be appended to indicate access is denied.
|
|
||||||
- */
|
|
||||||
-static int host_match(char *pattern)
|
|
||||||
-{
|
|
||||||
- unsigned int negate = (*pattern == '-');
|
|
||||||
- const char *m_pattern = (negate ? pattern + 1 : pattern);
|
|
||||||
- char myname[MAXHOSTNAMELEN + 1] = "\0";
|
|
||||||
- int ret = 0;
|
|
||||||
-
|
|
||||||
- if (gethostname(myname, MAXHOSTNAMELEN))
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- if (yp_get_default_domain(&domain))
|
|
||||||
- domain = NULL;
|
|
||||||
-
|
|
||||||
- if (*m_pattern == '@') {
|
|
||||||
- /*
|
|
||||||
- * The pattern begins with an "@" so it's a network
|
|
||||||
- * spec or it's a netgroup.
|
|
||||||
- */
|
|
||||||
- ret = match_network(m_pattern + 1);
|
|
||||||
- if (!ret)
|
|
||||||
- ret = innetgr(m_pattern + 1, myname, NULL, domain);
|
|
||||||
- } else if (*m_pattern == '.') {
|
|
||||||
- size_t m_len = strlen(m_pattern);
|
|
||||||
- char *has_dot = strchr(myname, '.');
|
|
||||||
- /*
|
|
||||||
- * The pattern starts with a "." so it's a domain spec
|
|
||||||
- * of some sort.
|
|
||||||
- *
|
|
||||||
- * If the host name contains a dot then it must be either
|
|
||||||
- * a cannonical name or a simple NIS name.domain. So
|
|
||||||
- * perform a string match. Otherwise, append the domain
|
|
||||||
- * pattern to our simple name and try a wildcard pattern
|
|
||||||
- * match against the interfaces.
|
|
||||||
- */
|
|
||||||
- if (has_dot) {
|
|
||||||
- if (strlen(has_dot) == m_len)
|
|
||||||
- ret = !memcmp(has_dot, m_pattern, m_len);
|
|
||||||
- } else {
|
|
||||||
- char *w_pattern = alloca(m_len + 2);
|
|
||||||
- if (w_pattern) {
|
|
||||||
- strcpy(w_pattern, "*");
|
|
||||||
- strcat(w_pattern, m_pattern);
|
|
||||||
- ret = fqdn_match(w_pattern);
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- } else if (!strcmp(m_pattern, "gss/krb5")) {
|
|
||||||
- /* Leave this to the GSS layer */
|
|
||||||
- return 1;
|
|
||||||
- } else {
|
|
||||||
- /*
|
|
||||||
- * Otherwise it's a network name or host name
|
|
||||||
- */
|
|
||||||
- ret = match_network(m_pattern);
|
|
||||||
- if (!ret)
|
|
||||||
- /* if not then try to match host name */
|
|
||||||
- ret = string_match(myname, m_pattern);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (negate && ret)
|
|
||||||
- ret = -1;
|
|
||||||
-
|
|
||||||
- return ret;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int rpc_export_allowed(groups grouplist)
|
|
||||||
-{
|
|
||||||
- groups grp = grouplist;
|
|
||||||
-
|
|
||||||
- /* NULL group list => everyone */
|
|
||||||
- if (!grp)
|
|
||||||
- return 1;
|
|
||||||
-
|
|
||||||
- while (grp) {
|
|
||||||
- int allowed = host_match(grp->gr_name);
|
|
||||||
- /* Explicitly denied access */
|
|
||||||
- if (allowed == -1)
|
|
||||||
- return 0;
|
|
||||||
- else if (allowed)
|
|
||||||
- return 1;
|
|
||||||
- grp = grp->gr_next;
|
|
||||||
- }
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-exports rpc_exports_prune(exports list)
|
|
||||||
-{
|
|
||||||
- exports head = list;
|
|
||||||
- exports exp;
|
|
||||||
- exports last;
|
|
||||||
- int res;
|
|
||||||
-
|
|
||||||
- exp = list;
|
|
||||||
- last = NULL;
|
|
||||||
- while (exp) {
|
|
||||||
- res = rpc_export_allowed(exp->ex_groups);
|
|
||||||
- if (!res) {
|
|
||||||
- if (last == NULL) {
|
|
||||||
- head = exp->ex_next;
|
|
||||||
- rpc_export_free(exp);
|
|
||||||
- exp = head;
|
|
||||||
- } else {
|
|
||||||
- last->ex_next = exp->ex_next;
|
|
||||||
- rpc_export_free(exp);
|
|
||||||
- exp = last->ex_next;
|
|
||||||
- }
|
|
||||||
- continue;
|
|
||||||
- }
|
|
||||||
- last = exp;
|
|
||||||
- exp = exp->ex_next;
|
|
||||||
- }
|
|
||||||
- return head;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option)
|
|
||||||
{
|
|
||||||
struct conn_info info;
|
|
||||||
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
|
|
||||||
index 1f8fa15..d711611 100644
|
|
||||||
--- a/modules/lookup_hosts.c
|
|
||||||
+++ b/modules/lookup_hosts.c
|
|
||||||
@@ -45,7 +45,6 @@ struct lookup_context {
|
|
||||||
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
|
|
||||||
|
|
||||||
exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option);
|
|
||||||
-exports rpc_exports_prune(exports list);
|
|
||||||
void rpc_exports_free(exports list);
|
|
||||||
|
|
||||||
int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
|
|
||||||
@@ -207,9 +206,6 @@ done:
|
|
||||||
|
|
||||||
exp = rpc_get_exports(name, 10, 0, RPC_CLOSE_NOLINGER);
|
|
||||||
|
|
||||||
- /* Check exports for obvious ones we don't have access to */
|
|
||||||
- /*exp = rpc_exports_prune(exp);*/
|
|
||||||
-
|
|
||||||
mapent = NULL;
|
|
||||||
while (exp) {
|
|
||||||
if (mapent) {
|
|
@ -1,123 +0,0 @@
|
|||||||
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
|
|
||||||
index 1007de4..23ea07d 100644
|
|
||||||
--- a/modules/lookup_file.c
|
|
||||||
+++ b/modules/lookup_file.c
|
|
||||||
@@ -1088,8 +1088,9 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
if (status == NSS_STATUS_COMPLETED)
|
|
||||||
return NSS_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
- debug(ap->logopt,
|
|
||||||
- MODPREFIX "check indirect map lookup failed");
|
|
||||||
+ error(ap->logopt,
|
|
||||||
+ MODPREFIX "key \"%s\" not found in map",
|
|
||||||
+ name);
|
|
||||||
|
|
||||||
return NSS_STATUS_NOTFOUND;
|
|
||||||
}
|
|
||||||
@@ -1130,7 +1131,9 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
}
|
|
||||||
cache_unlock(mc);
|
|
||||||
}
|
|
||||||
- }
|
|
||||||
+ } else
|
|
||||||
+ error(ap->logopt,
|
|
||||||
+ MODPREFIX "key \"%s\" not found in map.", name);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
return NSS_STATUS_TRYAGAIN;
|
|
||||||
diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c
|
|
||||||
index 649e24c..737a47e 100644
|
|
||||||
--- a/modules/lookup_hesiod.c
|
|
||||||
+++ b/modules/lookup_hesiod.c
|
|
||||||
@@ -129,8 +129,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
if (!hes_result || !hes_result[0]) {
|
|
||||||
/* Note: it is not clear to me how to distinguish between
|
|
||||||
* the "no search results" case and other failures. --JM */
|
|
||||||
- warn(ap->logopt,
|
|
||||||
- MODPREFIX "entry \"%s\" not found in map", name);
|
|
||||||
+ error(ap->logopt,
|
|
||||||
+ MODPREFIX "key \"%s\" not found in map", name);
|
|
||||||
status = pthread_mutex_unlock(&hesiod_mutex);
|
|
||||||
if (status)
|
|
||||||
fatal(status);
|
|
||||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
|
||||||
index 4dea3b2..bad48bb 100644
|
|
||||||
--- a/modules/lookup_ldap.c
|
|
||||||
+++ b/modules/lookup_ldap.c
|
|
||||||
@@ -2089,8 +2089,9 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt);
|
|
||||||
free(lkp_key);
|
|
||||||
if (status) {
|
|
||||||
- debug(ap->logopt,
|
|
||||||
- MODPREFIX "check indirect map failure");
|
|
||||||
+ error(ap->logopt,
|
|
||||||
+ MODPREFIX "key \"%s\" not found in map",
|
|
||||||
+ name);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2129,7 +2130,9 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
}
|
|
||||||
cache_unlock(mc);
|
|
||||||
}
|
|
||||||
- }
|
|
||||||
+ } else
|
|
||||||
+ error(ap->logopt,
|
|
||||||
+ MODPREFIX "key \"%s\" not found in map", name);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
return NSS_STATUS_TRYAGAIN;
|
|
||||||
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
|
|
||||||
index e948c14..bb1ca42 100644
|
|
||||||
--- a/modules/lookup_nisplus.c
|
|
||||||
+++ b/modules/lookup_nisplus.c
|
|
||||||
@@ -512,8 +512,9 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
|
|
||||||
status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt);
|
|
||||||
if (status) {
|
|
||||||
- debug(ap->logopt,
|
|
||||||
- MODPREFIX "check indirect map failure");
|
|
||||||
+ error(ap->logopt,
|
|
||||||
+ MODPREFIX "key \"%s\" not found in map",
|
|
||||||
+ name);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -551,7 +552,9 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
}
|
|
||||||
cache_unlock(mc);
|
|
||||||
}
|
|
||||||
- }
|
|
||||||
+ } else
|
|
||||||
+ error(ap->logopt,
|
|
||||||
+ MODPREFIX "key \"%s\" not found in map", name);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
return NSS_STATUS_NOTFOUND;
|
|
||||||
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
|
|
||||||
index 6c20145..e8ca8e8 100644
|
|
||||||
--- a/modules/lookup_yp.c
|
|
||||||
+++ b/modules/lookup_yp.c
|
|
||||||
@@ -604,8 +604,9 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt);
|
|
||||||
free(lkp_key);
|
|
||||||
if (status) {
|
|
||||||
- debug(ap->logopt,
|
|
||||||
- MODPREFIX "check indirect map lookup failed");
|
|
||||||
+ error(ap->logopt,
|
|
||||||
+ MODPREFIX "key \"%s\" not found in map",
|
|
||||||
+ name);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -643,7 +644,9 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
||||||
}
|
|
||||||
cache_unlock(mc);
|
|
||||||
}
|
|
||||||
- }
|
|
||||||
+ } else
|
|
||||||
+ error(ap->logopt,
|
|
||||||
+ MODPREFIX "key \"%s\" not found in map", name);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
return NSS_STATUS_TRYAGAIN;
|
|
@ -1,124 +0,0 @@
|
|||||||
diff -up autofs-5.0.2/modules/cyrus-sasl.c.reread-config-on-hup autofs-5.0.2/modules/cyrus-sasl.c
|
|
||||||
--- autofs-5.0.2/modules/cyrus-sasl.c.reread-config-on-hup 2007-11-20 15:00:13.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/modules/cyrus-sasl.c 2007-11-20 15:00:13.000000000 +0900
|
|
||||||
@@ -528,6 +528,7 @@ sasl_do_kinit(struct lookup_context *ctx
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out_cleanup_unparse:
|
|
||||||
+ krb5cc_in_use--;
|
|
||||||
krb5_free_unparsed_name(ctxt->krb5ctxt, tgs_name);
|
|
||||||
out_cleanup_cc:
|
|
||||||
status = pthread_mutex_lock(&krb5cc_mutex);
|
|
||||||
diff -up autofs-5.0.2/modules/lookup_ldap.c.reread-config-on-hup autofs-5.0.2/modules/lookup_ldap.c
|
|
||||||
--- autofs-5.0.2/modules/lookup_ldap.c.reread-config-on-hup 2007-11-20 15:00:13.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/modules/lookup_ldap.c 2007-11-20 15:00:13.000000000 +0900
|
|
||||||
@@ -174,7 +174,7 @@ LDAP *init_ldap_connection(struct lookup
|
|
||||||
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;
|
|
||||||
+ char *query, *dn, *qdn;
|
|
||||||
LDAPMessage *result = NULL, *e;
|
|
||||||
struct ldap_searchdn *sdns = NULL;
|
|
||||||
char *attrs[2];
|
|
||||||
@@ -225,15 +225,18 @@ static int get_query_dn(LDAP *ldap, stru
|
|
||||||
|
|
||||||
if (!ctxt->base) {
|
|
||||||
sdns = defaults_get_searchdns();
|
|
||||||
- if (sdns)
|
|
||||||
+ if (sdns) {
|
|
||||||
+ if (ctxt->sdns)
|
|
||||||
+ defaults_free_searchdns(ctxt->sdns);
|
|
||||||
ctxt->sdns = sdns;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!sdns)
|
|
||||||
+ if (!ctxt->sdns)
|
|
||||||
rv = ldap_search_s(ldap, ctxt->base,
|
|
||||||
scope, query, attrs, 0, &result);
|
|
||||||
else {
|
|
||||||
- struct ldap_searchdn *this = sdns;
|
|
||||||
+ struct ldap_searchdn *this = ctxt->sdns;
|
|
||||||
|
|
||||||
debug(LOGOPT_NONE, MODPREFIX
|
|
||||||
"check search base list");
|
|
||||||
@@ -269,7 +272,6 @@ static int get_query_dn(LDAP *ldap, stru
|
|
||||||
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",
|
|
||||||
@@ -278,7 +280,16 @@ static int get_query_dn(LDAP *ldap, stru
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- ctxt->qdn = dn;
|
|
||||||
+ qdn = strdup(dn);
|
|
||||||
+ ldap_memfree(dn);
|
|
||||||
+ ldap_msgfree(result);
|
|
||||||
+ if (!qdn)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ if (ctxt->qdn)
|
|
||||||
+ free(ctxt->qdn);
|
|
||||||
+
|
|
||||||
+ ctxt->qdn = qdn;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1018,7 +1029,7 @@ static void free_context(struct lookup_c
|
|
||||||
if (ctxt->mapname)
|
|
||||||
free(ctxt->mapname);
|
|
||||||
if (ctxt->qdn)
|
|
||||||
- ldap_memfree(ctxt->qdn);
|
|
||||||
+ free(ctxt->qdn);
|
|
||||||
if (ctxt->server)
|
|
||||||
free(ctxt->server);
|
|
||||||
if (ctxt->cur_host)
|
|
||||||
@@ -1600,14 +1611,14 @@ static int lookup_one(struct autofs_poin
|
|
||||||
}
|
|
||||||
query[ql] = '\0';
|
|
||||||
|
|
||||||
- debug(ap->logopt,
|
|
||||||
- MODPREFIX "searching for \"%s\" under \"%s\"", query, ctxt->qdn);
|
|
||||||
-
|
|
||||||
/* Initialize the LDAP context. */
|
|
||||||
ldap = do_connect(ctxt);
|
|
||||||
if (!ldap)
|
|
||||||
return CHE_FAIL;
|
|
||||||
|
|
||||||
+ debug(ap->logopt,
|
|
||||||
+ MODPREFIX "searching for \"%s\" under \"%s\"", query, ctxt->qdn);
|
|
||||||
+
|
|
||||||
rv = ldap_search_s(ldap, ctxt->qdn, scope, query, attrs, 0, &result);
|
|
||||||
|
|
||||||
if ((rv != LDAP_SUCCESS) || !result) {
|
|
||||||
diff -up autofs-5.0.2/daemon/automount.c.reread-config-on-hup autofs-5.0.2/daemon/automount.c
|
|
||||||
--- autofs-5.0.2/daemon/automount.c.reread-config-on-hup 2007-11-20 15:00:13.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/daemon/automount.c 2007-11-20 15:00:13.000000000 +0900
|
|
||||||
@@ -978,6 +978,8 @@ static void *do_read_master(void *arg)
|
|
||||||
if (status)
|
|
||||||
fatal(status);
|
|
||||||
|
|
||||||
+ defaults_read_config();
|
|
||||||
+
|
|
||||||
status = master_read_master(master, age, readall);
|
|
||||||
|
|
||||||
master->reading = 0;
|
|
||||||
diff -up autofs-5.0.2/lib/master.c.reread-config-on-hup autofs-5.0.2/lib/master.c
|
|
||||||
--- autofs-5.0.2/lib/master.c.reread-config-on-hup 2007-11-20 15:00:13.000000000 +0900
|
|
||||||
+++ autofs-5.0.2/lib/master.c 2007-11-20 15:00:13.000000000 +0900
|
|
||||||
@@ -1170,6 +1170,10 @@ int master_mount_mounts(struct master *m
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ master_source_writelock(this);
|
|
||||||
+ lookup_close_lookup(ap);
|
|
||||||
+ master_source_unlock(this);
|
|
||||||
+
|
|
||||||
cache_readlock(nc);
|
|
||||||
ne = cache_lookup_distinct(nc, this->path);
|
|
||||||
if (ne && this->age > ne->age) {
|
|
@ -1,45 +0,0 @@
|
|||||||
diff --git a/modules/replicated.c b/modules/replicated.c
|
|
||||||
index 14b20a9..90b2925 100644
|
|
||||||
--- a/modules/replicated.c
|
|
||||||
+++ b/modules/replicated.c
|
|
||||||
@@ -725,19 +725,21 @@ int prune_host_list(unsigned logopt, struct host **list,
|
|
||||||
while (this && this->proximity == PROXIMITY_LOCAL)
|
|
||||||
this = this->next;
|
|
||||||
|
|
||||||
- proximity = PROXIMITY_LOCAL;
|
|
||||||
- if (this)
|
|
||||||
- proximity = this->proximity;
|
|
||||||
+ /*
|
|
||||||
+ * Check for either a list containing only proximity local hosts
|
|
||||||
+ * or a single host entry whose proximity isn't local. If so
|
|
||||||
+ * return immediately as we don't want to add probe latency for
|
|
||||||
+ * the common case of a single filesystem mount request.
|
|
||||||
+ */
|
|
||||||
+ if (!this || !this->next)
|
|
||||||
+ return 1;
|
|
||||||
|
|
||||||
+ proximity = this->proximity;
|
|
||||||
+ first = this;
|
|
||||||
this = first;
|
|
||||||
while (this) {
|
|
||||||
struct host *next = this->next;
|
|
||||||
|
|
||||||
- if (this->proximity == PROXIMITY_LOCAL) {
|
|
||||||
- this = next;
|
|
||||||
- continue;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
if (this->proximity != proximity)
|
|
||||||
break;
|
|
||||||
|
|
||||||
@@ -758,10 +760,6 @@ int prune_host_list(unsigned logopt, struct host **list,
|
|
||||||
|
|
||||||
last = this;
|
|
||||||
|
|
||||||
- /* If there are only local entries on the list, just return it. */
|
|
||||||
- if (!first)
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
/* Select NFS version of highest number of closest servers */
|
|
||||||
|
|
||||||
v4_tcp_count = v3_tcp_count = v2_tcp_count = 0;
|
|
@ -1,22 +0,0 @@
|
|||||||
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
|
|
||||||
index f8d8ed2..c45b91b 100644
|
|
||||||
--- a/modules/mount_autofs.c
|
|
||||||
+++ b/modules/mount_autofs.c
|
|
||||||
@@ -215,6 +215,8 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ mounts_mutex_lock(ap);
|
|
||||||
+
|
|
||||||
status = pthread_mutex_lock(&suc.mutex);
|
|
||||||
if (status) {
|
|
||||||
crit(ap->logopt,
|
|
||||||
@@ -227,8 +229,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
|
||||||
suc.done = 0;
|
|
||||||
suc.status = 0;
|
|
||||||
|
|
||||||
- mounts_mutex_lock(ap);
|
|
||||||
-
|
|
||||||
if (pthread_create(&thid, NULL, handle_mounts, nap)) {
|
|
||||||
crit(ap->logopt,
|
|
||||||
MODPREFIX
|
|
@ -1,24 +0,0 @@
|
|||||||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|
||||||
index 5e14c75..079bda6 100644
|
|
||||||
--- a/modules/parse_sun.c
|
|
||||||
+++ b/modules/parse_sun.c
|
|
||||||
@@ -186,8 +186,7 @@ int expandsunent(const char *src, char *dst, const char *key,
|
|
||||||
dst += l;
|
|
||||||
}
|
|
||||||
len += l;
|
|
||||||
- } else
|
|
||||||
- return 0;
|
|
||||||
+ }
|
|
||||||
src = p + 1;
|
|
||||||
} else {
|
|
||||||
p = src;
|
|
||||||
@@ -201,8 +200,7 @@ int expandsunent(const char *src, char *dst, const char *key,
|
|
||||||
dst += l;
|
|
||||||
}
|
|
||||||
len += l;
|
|
||||||
- } else
|
|
||||||
- return 0;
|
|
||||||
+ }
|
|
||||||
src = p;
|
|
||||||
}
|
|
||||||
break;
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/lib/master_tok.l b/lib/master_tok.l
|
|
||||||
index 013a15a..2735223 100644
|
|
||||||
--- a/lib/master_tok.l
|
|
||||||
+++ b/lib/master_tok.l
|
|
||||||
@@ -313,7 +313,7 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
|
|
||||||
return(DDASH);
|
|
||||||
}
|
|
||||||
|
|
||||||
- {OPTTOUT} { return(OPT_TIMEOUT); }
|
|
||||||
+ {OPTTOUT}/{NUMBER} { return(OPT_TIMEOUT); }
|
|
||||||
|
|
||||||
{NUMBER} {
|
|
||||||
master_lval.longtype = atol(master_text);
|
|
103
autofs.spec
103
autofs.spec
@ -3,61 +3,13 @@
|
|||||||
#
|
#
|
||||||
Summary: A tool for automatically mounting and unmounting filesystems
|
Summary: A tool for automatically mounting and unmounting filesystems
|
||||||
Name: autofs
|
Name: autofs
|
||||||
Version: 5.0.2
|
Version: 5.0.3
|
||||||
Release: 25
|
Release: 1
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
License: GPL
|
License: GPL
|
||||||
Group: System Environment/Daemons
|
Group: System Environment/Daemons
|
||||||
URL: http://wiki.autofs.net/
|
URL: http://wiki.autofs.net/
|
||||||
Source: ftp://ftp.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.bz2
|
Source: ftp://ftp.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.bz2
|
||||||
Patch0: autofs-5.0.2-add-krb5-include.patch
|
|
||||||
Patch1: autofs-5.0.2-bad-proto-init.patch
|
|
||||||
Patch2: autofs-5.0.2-add-missing-multi-support.patch
|
|
||||||
Patch3: autofs-5.0.2-add-multi-nsswitch-lookup.patch
|
|
||||||
Patch4: autofs-5.0.2-fix-offset-dir-create.patch
|
|
||||||
Patch5: autofs-5.0.2-quote-exports.patch
|
|
||||||
Patch6: autofs-5.0.2-hi-res-time.patch
|
|
||||||
Patch7: autofs-5.0.2-quoted-slash-alone.patch
|
|
||||||
Patch8: autofs-5.0.2-fix-dnattr-parse.patch
|
|
||||||
Patch9: autofs-5.0.2-fix-nfs-version-in-get-supported-ver-and-cost.patch
|
|
||||||
Patch10: autofs-5.0.2-fix-largefile-dumbness.patch
|
|
||||||
Patch11: autofs-5.0.2-instance-stale-mark.patch
|
|
||||||
Patch12: autofs-5.0.2-dont-fail-on-empty-master.patch
|
|
||||||
Patch13: autofs-5.0.2-ldap-percent-hack.patch
|
|
||||||
Patch14: autofs-5.0.2-consistent-random-selection-option-name.patch
|
|
||||||
Patch15: autofs-5.0.2-fix-mount-nfs-nosymlink.patch
|
|
||||||
Patch16: autofs-5.0.2-default-nsswitch.patch
|
|
||||||
Patch17: autofs-5.0.2-add-ldap-schema-discovery.patch
|
|
||||||
Patch18: autofs-5.0.2-ldap-schema-discovery-config-update.patch
|
|
||||||
Patch19: autofs-5.0.2-libxml2-workaround.patch
|
|
||||||
Patch20: autofs-5.0.2-foreground-logging.patch
|
|
||||||
Patch21: autofs-5.0.2-add-ldap-schema-discovery-fix-2.patch
|
|
||||||
Patch22: autofs-5.0.2-ldap-check-star.patch
|
|
||||||
Patch23: autofs-5.0.2-timeout-option-parse-fix.patch
|
|
||||||
Patch24: autofs-5.0.2-ldap-search-basedn-list.patch
|
|
||||||
Patch25: autofs-5.0.2-random-selection-fix.patch
|
|
||||||
Patch26: autofs-5.0.2-reread-config-on-hup.patch
|
|
||||||
Patch27: autofs-5.0.2-add-multiple-server-selection-option.patch
|
|
||||||
Patch28: autofs-5.0.2-submount-deadlock.patch
|
|
||||||
Patch29: autofs-5.0.2-add-ferror-check.patch
|
|
||||||
Patch30: autofs-5.0.2-autofs-5-typo.patch
|
|
||||||
Patch31: autofs-5.0.2-swallow-null-macro.patch
|
|
||||||
Patch32: autofs-5.0.2-remove-unused-export-validation-code.patch
|
|
||||||
Patch33: autofs-5.0.2-dynamic-logging.patch
|
|
||||||
Patch34: autofs-5.0.2-fix-recursive-loopback-mounts.patch
|
|
||||||
Patch35: autofs-5.0.2-log-map-reload.patch
|
|
||||||
Patch36: autofs-5.0.2-dynamic-logging-fixes.patch
|
|
||||||
Patch37: autofs-5.0.2-basedn-with-spaces.patch
|
|
||||||
Patch38: autofs-5.0.2-check-mtab-updated.patch
|
|
||||||
Patch39: autofs-5.0.2-check-auto_master.patch
|
|
||||||
Patch40: autofs-5.0.2-negative-timeout-update.patch
|
|
||||||
Patch41: autofs-5.0.2-large-groups.patch
|
|
||||||
Patch42: autofs-5.0.2-report-failed-lookups.patch
|
|
||||||
Patch43: autofs-5.0.2-dynamic-logging-non-sasl.patch
|
|
||||||
Patch44: autofs-5.0.2-singleton-host-list.patch
|
|
||||||
Patch45: autofs-5.0.2-hosts-nosuid-default.patch
|
|
||||||
Patch46: autofs-5.0.2-fd-close-on-exec-mutex.patch
|
|
||||||
Patch47: autofs-5.0.2-hosts-nodev-default.patch
|
|
||||||
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||||
BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs
|
BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs
|
||||||
Conflicts: kernel < 2.6.17
|
Conflicts: kernel < 2.6.17
|
||||||
@ -99,54 +51,6 @@ inkludera nätfilsystem, CD-ROM, floppydiskar, och så vidare.
|
|||||||
%prep
|
%prep
|
||||||
%setup -q
|
%setup -q
|
||||||
echo %{version}-%{release} > .version
|
echo %{version}-%{release} > .version
|
||||||
%patch0 -p1
|
|
||||||
%patch1 -p1
|
|
||||||
%patch2 -p1
|
|
||||||
%patch3 -p1
|
|
||||||
%patch4 -p1
|
|
||||||
%patch5 -p1
|
|
||||||
%patch6 -p1
|
|
||||||
%patch7 -p1
|
|
||||||
%patch8 -p1
|
|
||||||
%patch9 -p1
|
|
||||||
%patch10 -p1
|
|
||||||
%patch11 -p1
|
|
||||||
%patch12 -p1
|
|
||||||
%patch13 -p1
|
|
||||||
%patch14 -p1
|
|
||||||
%patch15 -p1
|
|
||||||
%patch16 -p1
|
|
||||||
%patch17 -p1
|
|
||||||
%patch18 -p1
|
|
||||||
%patch19 -p1
|
|
||||||
%patch20 -p1
|
|
||||||
%patch21 -p1
|
|
||||||
%patch22 -p1
|
|
||||||
%patch23 -p1
|
|
||||||
%patch24 -p1
|
|
||||||
%patch25 -p1
|
|
||||||
%patch26 -p1
|
|
||||||
%patch27 -p1
|
|
||||||
%patch28 -p1
|
|
||||||
%patch29 -p1
|
|
||||||
%patch30 -p1
|
|
||||||
%patch31 -p1
|
|
||||||
%patch32 -p1
|
|
||||||
%patch33 -p1
|
|
||||||
%patch34 -p1
|
|
||||||
%patch35 -p1
|
|
||||||
%patch36 -p1
|
|
||||||
%patch37 -p1
|
|
||||||
%patch38 -p1
|
|
||||||
%patch39 -p1
|
|
||||||
%patch40 -p1
|
|
||||||
%patch41 -p1
|
|
||||||
%patch42 -p1
|
|
||||||
%patch43 -p1
|
|
||||||
%patch44 -p1
|
|
||||||
%patch45 -p1
|
|
||||||
%patch46 -p1
|
|
||||||
%patch47 -p1
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
#CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
|
#CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
|
||||||
@ -199,6 +103,9 @@ fi
|
|||||||
%{_libdir}/autofs/
|
%{_libdir}/autofs/
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Jan 14 2008 Ian Kent <ikent@redhat.com> - 5.0.3-1
|
||||||
|
- update source to version 5.0.3.
|
||||||
|
|
||||||
* Fri Dec 21 2007 Ian Kent <ikent@redhat.com> - 5.0.2-25
|
* Fri Dec 21 2007 Ian Kent <ikent@redhat.com> - 5.0.2-25
|
||||||
- Bug 426401: CVE-2007-6285 autofs default doesn't set nodev in /net [rawhide]
|
- Bug 426401: CVE-2007-6285 autofs default doesn't set nodev in /net [rawhide]
|
||||||
- use mount option "nodev" for "-hosts" map unless "dev" is explicily specified.
|
- use mount option "nodev" for "-hosts" map unless "dev" is explicily specified.
|
||||||
|
Loading…
Reference in New Issue
Block a user