- update source to version 5.0.3.

This commit is contained in:
Ian Kent 2008-01-14 05:48:52 +00:00
parent 41a12c29f1
commit 4e3326018a
51 changed files with 7 additions and 14734 deletions

View File

@ -1 +1 @@
autofs-5.0.2.tar.bz2 autofs-5.0.3.tar.bz2

View File

@ -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);

View File

@ -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 {

View File

@ -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 {

View File

@ -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.

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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

View File

@ -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 {

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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",

View File

@ -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) {

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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" : "";

View File

@ -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);

View File

@ -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++;

View File

@ -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--) {

View File

@ -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.

View File

@ -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)

View File

@ -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
#

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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");

View File

@ -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;
}

View File

@ -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"

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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"

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -1 +1 @@
fd56817cba70814753bc98f5fb7f23ec autofs-5.0.2.tar.bz2 27839fe6fa8105b2b7d31bc922fd7cf6 autofs-5.0.3.tar.bz2