+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 2db9b39..dd08880 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -31,6 +31,7 @@
- - fix forground logging and add option to man page.
- - remove unjustified, nasty comment about krb5 package.
- - fix deadlock in submount mount module.
-+- fix lack of ferror() checking when reading files.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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);
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 172d0cd..6931791 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -1,3 +1,7 @@
-+??/??/2007 autofs-5.0.3
-+-----------------------
-+- include krb5.h in lookup_ldap.h (some openssl doesn't implicitly include it).
-+
- 18/06/2007 autofs-5.0.2
- -----------------------
- - fix return check for getpwuid_r and getgrgid_r.
-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 {
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 1c147c5..74d39fd 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -41,6 +41,7 @@
- - fix handling of LDAP base dns with spaces.
- - handle MTAB_NOTUPDATED status return from mount.
- - when default master map, auto.master, is used also check for auto_master.
-+- fix schema selection in LDAP schema discovery.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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 {
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index ef549cf..08afa7c 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -23,6 +23,7 @@
- - add random selection as a master map entry option.
- - fix couple of edge case parse fails of timeout option.
- - check for "*" when looking up wildcard in LDAP.
-+- fix LDAP schema discovery.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index a7b315e..9c18ca1 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -1009,6 +1009,15 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- 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);
-
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 92013ce..c36017a 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -19,6 +19,7 @@
- - fix "nosymlink" option handling and add desription to man page.
- - fix don't fail on empty master map.
- - if there's no "automount" entry in nsswitch.conf use "files" source.
-+- add LDAP schema discovery if no schema is configured.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/include/defaults.h b/include/defaults.h
-index ef58467..9aec11a 100644
---- a/include/defaults.h
-+++ b/include/defaults.h
-@@ -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 --git a/include/lookup_ldap.h b/include/lookup_ldap.h
-index 0a9deca..1378b9e 100644
---- a/include/lookup_ldap.h
-+++ b/include/lookup_ldap.h
-@@ -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 --git a/lib/defaults.c b/lib/defaults.c
-index 4b4acba..b146f13 100644
---- a/lib/defaults.c
-+++ b/lib/defaults.c
-@@ -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(void)
- 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 --git a/man/auto.master.5.in b/man/auto.master.5.in
-index 69c796e..249c9a7 100644
---- a/man/auto.master.5.in
-+++ b/man/auto.master.5.in
-@@ -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 --git a/man/automount.8 b/man/automount.8
-index fc1846a..da67a5c 100644
---- a/man/automount.8
-+++ b/man/automount.8
-@@ -102,6 +102,8 @@ started they will be recoverd unless they are no longer present in
- 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.
-diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index a412797..d5e666b 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -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_context *ctxt)
- 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, struct lookup_context *ctxt)
- 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 argc, const char *const *argv, void **co
- 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,22 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- 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;
-+ }
- }
-+ unbind_ldap_connection(ldap, ctxt);
-
- /* Open the parser, if we can. */
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
-@@ -990,9 +1040,9 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- 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 +1191,9 @@ static int read_one_map(struct autofs_point *ap,
-
- 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 +1488,9 @@ static int lookup_one(struct autofs_point *ap,
- 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;
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 91903e9..6b16b0f 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -2,6 +2,7 @@
- -----------------------
- - include krb5.h in lookup_ldap.h (some openssl doesn't implicitly include it).
- - correct initialization of local var in parse_server_string.
-+- add missing "multi" map support.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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;
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 6b16b0f..d66b8fc 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -3,6 +3,7 @@
- - include krb5.h in lookup_ldap.h (some openssl doesn't implicitly include it).
- - correct initialization of local var in parse_server_string.
- - add missing "multi" map support.
-+- add multi nsswitch lookup.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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);
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index a9e509d..85af0ad 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -49,6 +49,7 @@
- - fix incorrect read/write size of startup status token (Matthias Koenig).
- - fix off-by-one error for lookup of map keys exactly 255 characters long.
- - improve handling of server not available.
-+- fix LDAP_URI server selection.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
-index 18733f3..303b7f2 100644
---- a/modules/cyrus-sasl.c
-+++ b/modules/cyrus-sasl.c
-@@ -75,6 +75,7 @@ static const char *krb5ccval = "MEMORY:_autofstkt";
- static pthread_mutex_t krb5cc_mutex = PTHREAD_MUTEX_INITIALIZER;
- static unsigned int krb5cc_in_use = 0;
-
-+static unsigned int init_callbacks = 1;
- static int sasl_log_func(void *, int, const char *);
- static int getpass_func(sasl_conn_t *, void *, int, sasl_secret_t **);
- static int getuser_func(void *, int, const char **, unsigned *);
-@@ -386,7 +387,7 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
-
- debug(logopt,
- "initializing kerberos ticket: client principal %s ",
-- ctxt->client_princ ? "" : "autofsclient");
-+ ctxt->client_princ ? ctxt->client_princ : "autofsclient");
-
- ret = krb5_init_context(&ctxt->krb5ctxt);
- if (ret) {
-@@ -599,8 +600,8 @@ sasl_bind_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const c
-
- /* OK and CONTINUE are the only non-fatal return codes here. */
- if ((result != SASL_OK) && (result != SASL_CONTINUE)) {
-- error(logopt, "sasl_client start failed with error: %s",
-- sasl_errdetail(conn));
-+ warn(logopt, "sasl_client_start failed for %s", host);
-+ debug(logopt, "sasl_client_start: %s", sasl_errdetail(conn));
- ldap_memfree(host);
- sasl_dispose(&conn);
- return NULL;
-@@ -721,23 +722,30 @@ autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
- sasl_conn_t *conn;
-
- /* Start up Cyrus SASL--only needs to be done once. */
-- if (sasl_client_init(callbacks) != SASL_OK) {
-+ if (init_callbacks && sasl_client_init(callbacks) != SASL_OK) {
- error(logopt, "sasl_client_init failed");
- return -1;
- }
-+ init_callbacks = 0;
-
- sasl_auth_id = ctxt->user;
- sasl_auth_secret = ctxt->secret;
-
- /*
-- * If sasl_mech was not filled in, it means that there was no
-- * mechanism specified in the configuration file. Try to auto-
-- * select one.
-+ * If LDAP_AUTH_AUTODETECT is set, it means that there was no
-+ * mechanism specified in the configuration file or auto
-+ * selection has been requested, so try to auto-select an
-+ * auth mechanism.
- */
-- if (ctxt->sasl_mech)
-+ if (!(ctxt->auth_required & LDAP_AUTH_AUTODETECT))
- conn = sasl_bind_mech(logopt, ldap, ctxt, ctxt->sasl_mech);
-- else
-+ else {
-+ if (ctxt->sasl_mech) {
-+ free(ctxt->sasl_mech);
-+ ctxt->sasl_mech = NULL;
-+ }
- conn = sasl_choose_mech(logopt, ldap, ctxt);
-+ }
-
- if (conn) {
- sasl_dispose(&conn);
-diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index 7effbf1..93f0477 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -402,8 +402,7 @@ static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
- debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s",
- ctxt->auth_required, ctxt->sasl_mech);
-
-- if (ctxt->sasl_mech ||
-- (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT))) {
-+ if (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)) {
- rv = autofs_sasl_bind(logopt, ldap, ctxt);
- debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
- } else {
-@@ -497,7 +496,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c
- * Determine which authentication mechanism to use if we require
- * authentication.
- */
-- if (ctxt->auth_required & LDAP_AUTH_REQUIRED) {
-+ if (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)) {
- ldap = auth_init(logopt, uri, ctxt);
- if (!ldap && ctxt->auth_required & LDAP_AUTH_AUTODETECT)
- info(logopt,
-@@ -510,6 +509,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c
-
- if (!do_bind(logopt, ldap, ctxt)) {
- unbind_ldap_connection(logopt, ldap, ctxt);
-+ autofs_sasl_done(ctxt);
- error(logopt, MODPREFIX "cannot bind to server");
- return NULL;
- }
-@@ -541,6 +541,7 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
- while(p != ctxt->uri) {
- this = list_entry(p, struct ldap_uri, list);
- p = p->next;
-+ debug(logopt, "trying server %s", this->uri);
- ldap = connect_to_server(logopt, this->uri, ctxt);
- if (ldap) {
- info(logopt, "connected to uri %s", this->uri);
-@@ -563,22 +564,23 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
-
- static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
- {
-+ struct ldap_uri *this;
- LDAP *ldap;
-
- if (ctxt->server || !ctxt->uri) {
- ldap = do_connect(logopt, ctxt->server, ctxt);
- return ldap;
-- } else {
-- struct ldap_uri *this;
-- this = list_entry(ctxt->uri->next, struct ldap_uri, list);
-- ldap = do_connect(logopt, 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);
- }
-
-+ this = list_entry(ctxt->uri->next, struct ldap_uri, list);
-+ ldap = do_connect(logopt, 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);
-+
- #ifdef WITH_SASL
- autofs_sasl_done(ctxt);
- #endif
-@@ -844,6 +846,8 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
- ctxt->tls_required = tls_required;
- ctxt->auth_required = auth_required;
- ctxt->sasl_mech = authtype;
-+ if (!authtype && (auth_required & LDAP_AUTH_REQUIRED))
-+ ctxt->auth_required |= LDAP_AUTH_AUTODETECT;
- ctxt->user = user;
- ctxt->secret = secret;
- ctxt->client_princ = client_princ;
-@@ -886,16 +890,6 @@ static LDAP *auth_init(unsigned logopt, const char *uri, struct lookup_context *
- int ret;
- LDAP *ldap;
-
-- /*
-- * First, check to see if a preferred authentication method was
-- * specified by the user. parse_ldap_config will return error
-- * if the permissions on the file were incorrect, or if the
-- * specified authentication type is not valid.
-- */
-- ret = parse_ldap_config(logopt, ctxt);
-- if (ret)
-- return NULL;
--
- ldap = init_ldap_connection(logopt, uri, ctxt);
- if (!ldap)
- return NULL;
-@@ -909,10 +903,8 @@ static LDAP *auth_init(unsigned logopt, const char *uri, struct lookup_context *
- * the credential cache and the client and service principals.
- */
- ret = autofs_sasl_init(logopt, ldap, ctxt);
-- if (ret) {
-- ctxt->sasl_mech = NULL;
-+ if (ret)
- return NULL;
-- }
-
- return ldap;
- }
-@@ -1134,6 +1126,8 @@ static void free_context(struct lookup_context *ctxt)
- free(ctxt->user);
- if (ctxt->secret)
- free(ctxt->secret);
-+ if (ctxt->client_princ)
-+ free(ctxt->client_princ);
- if (ctxt->mapname)
- free(ctxt->mapname);
- if (ctxt->qdn)
-@@ -1184,6 +1178,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- struct lookup_context *ctxt;
- char buf[MAX_ERR_BUF];
- LDAP *ldap = NULL;
-+ int ret;
-
- *context = NULL;
-
-@@ -1224,6 +1219,20 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- }
- }
-
-+#ifdef WITH_SASL
-+ /*
-+ * First, check to see if a preferred authentication method was
-+ * specified by the user. parse_ldap_config will return error
-+ * if the permissions on the file were incorrect, or if the
-+ * specified authentication type is not valid.
-+ */
-+ ret = parse_ldap_config(LOGOPT_NONE, ctxt);
-+ if (ret) {
-+ free_context(ctxt);
-+ return 1;
-+ }
-+#endif
-+
- if (ctxt->server || !ctxt->uri) {
- ldap = connect_to_server(LOGOPT_NONE, ctxt->server, ctxt);
- if (!ldap) {
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 9a2a8c1..933b1a1 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -27,6 +27,7 @@
- - add SEARCH_BASE configuration option.
- - work around segv at exit due to libxml2 tsd usage.
- - re-read config on HUP signal.
-+- add LDAP_URI, LDAP_TIMEOUT and LDAP_NETWORK_TIMEOUT configuration options.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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.
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index dd08880..fdd07d1 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -32,6 +32,7 @@
- - remove unjustified, nasty comment about krb5 package.
- - fix deadlock in submount mount module.
- - fix lack of ferror() checking when reading files.
-+- fix typo in autofs(5) man page.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 6931791..91903e9 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -1,6 +1,7 @@
- ??/??/2007 autofs-5.0.3
- -----------------------
- - include krb5.h in lookup_ldap.h (some openssl doesn't implicitly include it).
-+- correct initialization of local var in parse_server_string.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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 {
+++ /dev/null
-diff --git a/lib/master_tok.l b/lib/master_tok.l
-index 5450753..36aa785 100644
---- a/lib/master_tok.l
-+++ b/lib/master_tok.l
-@@ -108,8 +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:]_.\- ]+)
--DNNAMETRM (,|{OPTWS}{NL}|{OPTWS}#.*|{OPTWS}\x00)
-+DNNAMESTR1 ([[:alnum:]_.\- ]+)
-+DNNAMESTR2 ([[:alnum:]_.\-]+)
-
- INTMAP (-hosts|-null)
- MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS}))
-@@ -282,7 +282,12 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
- return EQUAL;
- }
-
-- {DNNAMESTR}/{DNNAMETRM} {
-+ {DNNAMESTR1}/"," {
-+ strcpy(master_lval.strtype, master_text);
-+ return DNNAME;
-+ }
-+
-+ {DNNAMESTR2} {
- strcpy(master_lval.strtype, master_text);
- return DNNAME;
- }
+++ /dev/null
-diff --git a/lib/master_tok.l b/lib/master_tok.l
-index 48bc233..5450753 100644
---- a/lib/master_tok.l
-+++ b/lib/master_tok.l
-@@ -108,8 +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:]_.\-]+)
--DNNAMETRM (,|{WS}{NL}|{WS}#.*|\x00)
-+DNNAMESTR ([[:alnum:]_.\- ]+)
-+DNNAMETRM (,|{OPTWS}{NL}|{OPTWS}#.*|{OPTWS}\x00)
-
- INTMAP (-hosts|-null)
- MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS}))
-@@ -379,7 +379,13 @@ void master_set_scan_buffer(const char *buffer)
- {
- 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 --git a/modules/lookup_file.c b/modules/lookup_file.c
-index 921b32b..c093415 100644
---- a/modules/lookup_file.c
-+++ b/modules/lookup_file.c
-@@ -479,7 +479,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
-
- 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 --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index 00215af..dfb3054 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -1368,7 +1368,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- 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 --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
-index ff8bd49..bcdaeeb 100644
---- a/modules/lookup_nisplus.c
-+++ b/modules/lookup_nisplus.c
-@@ -90,7 +90,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- 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 *master, time_t age, void *context)
-
- 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 --git a/modules/lookup_yp.c b/modules/lookup_yp.c
-index 63fc8e3..7ba6940 100644
---- a/modules/lookup_yp.c
-+++ b/modules/lookup_yp.c
-@@ -178,7 +178,7 @@ int yp_all_master_callback(int status, char *ypkey, int ypkeylen,
- *(ypkey + ypkeylen) = '\0';
- *(val + vallen) = '\0';
-
-- len = ypkeylen + 1 + vallen + 1;
-+ len = ypkeylen + 1 + vallen + 2;
-
- buffer = alloca(len);
- if (!buffer) {
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index ca290f9..5e3a9ec 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -38,6 +38,7 @@
- - add dynamic logging (adapted from v4 patch from Jeff Moyer).
- - fix recursive loopback mounts (Matthias Koenig).
- - add map re-load to verbose logging.
-+- fix handling of LDAP base dns with spaces.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/lib/master_tok.l b/lib/master_tok.l
-index 00cd223..48bc233 100644
---- a/lib/master_tok.l
-+++ b/lib/master_tok.l
-@@ -109,6 +109,7 @@ AT_O ([oO])
- AT_C ([cC])
- DNATTRSTR {AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}
- DNNAMESTR ([[:alnum:]_.\-]+)
-+DNNAMETRM (,|{WS}{NL}|{WS}#.*|\x00)
-
- INTMAP (-hosts|-null)
- MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS}))
-@@ -281,7 +282,7 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
- return EQUAL;
- }
-
-- {DNNAMESTR} {
-+ {DNNAMESTR}/{DNNAMETRM} {
- strcpy(master_lval.strtype, master_text);
- return DNNAME;
- }
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 795ec30..1c147c5 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -40,6 +40,7 @@
- - add map re-load to verbose logging.
- - fix handling of LDAP base dns with spaces.
- - handle MTAB_NOTUPDATED status return from mount.
-+- when default master map, auto.master, is used also check for auto_master.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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;
+++ /dev/null
-diff --git a/daemon/spawn.c b/daemon/spawn.c
-index 0ed873e..78d69c6 100644
---- a/daemon/spawn.c
-+++ b/daemon/spawn.c
-@@ -25,6 +25,7 @@
- #include <time.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
-+#include <sys/mount.h>
-
- #include "automount.h"
-
-@@ -308,6 +309,8 @@ int spawn_mount(unsigned logopt, ...)
- while (retries--) {
- ret = do_spawn(logopt, options, prog, (const char **) argv);
- 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)
-@@ -329,6 +332,9 @@ int spawn_mount(unsigned logopt, ...)
- argv[argc - 1] = argv[argc - 2];
- argv[argc - 2] = arg_fake;
- }
-+
-+ nanosleep(&tm, NULL);
-+
- continue;
- }
- break;
-@@ -336,9 +342,16 @@ int spawn_mount(unsigned logopt, ...)
-
- /* 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;
-+ /*
-+ * 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;
-@@ -395,6 +408,8 @@ int spawn_bind_mount(unsigned logopt, ...)
- while (retries--) {
- ret = do_spawn(logopt, options, prog, (const char **) argv);
- 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)
-@@ -416,6 +431,9 @@ int spawn_bind_mount(unsigned logopt, ...)
- argv[argc - 1] = argv[argc - 2];
- argv[argc - 2] = arg_fake;
- }
-+
-+ nanosleep(&tm, NULL);
-+
- continue;
- }
- break;
-@@ -423,9 +441,16 @@ int spawn_bind_mount(unsigned logopt, ...)
-
- /* 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;
-+ /*
-+ * 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;
-diff --git a/include/automount.h b/include/automount.h
-index 4887da6..fa5cd97 100644
---- a/include/automount.h
-+++ b/include/automount.h
-@@ -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 --git a/modules/mount_bind.c b/modules/mount_bind.c
-index 04284f5..ef973e1 100644
---- a/modules/mount_bind.c
-+++ b/modules/mount_bind.c
-@@ -147,7 +147,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- 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 --git a/modules/mount_nfs.c b/modules/mount_nfs.c
-index bad21fc..0e7aebe 100644
---- a/modules/mount_nfs.c
-+++ b/modules/mount_nfs.c
-@@ -233,6 +233,10 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- 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, const char *root, const char *name, int
- this = this->next;
- }
-
-+forced_fail:
- free_host_list(&hosts);
- ap->ghost = save_ghost;
-
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 5e3a9ec..795ec30 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -39,6 +39,7 @@
- - fix recursive loopback mounts (Matthias Koenig).
- - add map re-load to verbose logging.
- - fix handling of LDAP base dns with spaces.
-+- handle MTAB_NOTUPDATED status return from mount.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/daemon/spawn.c b/daemon/spawn.c
-index ab3274c..0ed873e 100644
---- a/daemon/spawn.c
-+++ b/daemon/spawn.c
-@@ -268,9 +268,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 +285,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 +307,40 @@ int spawn_mount(unsigned logopt, ...)
-
- while (retries--) {
- ret = do_spawn(logopt, options, prog, (const char **) argv);
-- if (ret & MTAB_NOTUPDATED)
-+ if (ret & MTAB_NOTUPDATED) {
-+ /*
-+ * 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;
-+ }
- continue;
-+ }
- 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;
- }
-
-@@ -328,9 +360,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 +373,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 +394,40 @@ 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) {
-+ /*
-+ * 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;
-+ }
- continue;
-+ }
- 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;
- }
-
-@@ -373,7 +440,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 +464,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;
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 0340940..ddfa6f1 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -29,6 +29,7 @@
- - re-read config on HUP signal.
- - add LDAP_URI, LDAP_TIMEOUT and LDAP_NETWORK_TIMEOUT configuration options.
- - fix forground logging and add option to man page.
-+- remove unjustified, nasty comment about krb5 package.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/daemon/automount.c b/daemon/automount.c
-index 51f6a8b..930b13f 100644
---- a/daemon/automount.c
-+++ b/daemon/automount.c
-@@ -1263,22 +1263,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;
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index d66b8fc..8df22ae 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -4,6 +4,8 @@
- - correct initialization of local var in parse_server_string.
- - add missing "multi" map support.
- - add multi nsswitch lookup.
-+- change random multiple server selection option name to be consistent
-+ with existing downstream version 4 naming.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 9c99966..92013ce 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -18,6 +18,7 @@
- - add support for the "%" hack for case insensitive attribute schemas.
- - fix "nosymlink" option handling and add desription to man page.
- - fix don't fail on empty master map.
-+- if there's no "automount" entry in nsswitch.conf use "files" source.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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);
- }
-
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 5aee44c..9c99966 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -17,6 +17,7 @@
- - don't fail on empty master map.
- - add support for the "%" hack for case insensitive attribute schemas.
- - fix "nosymlink" option handling and add desription to man page.
-+- fix don't fail on empty master map.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/daemon/automount.c b/daemon/automount.c
-index 9809b9c..7b79f02 100644
---- 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",
-diff --git a/lib/master.c b/lib/master.c
-index 9f24f7e..da05bb6 100644
---- a/lib/master.c
-+++ b/lib/master.c
-@@ -802,7 +802,7 @@ int master_read_master(struct master *master, time_t age, int readall)
-
- if (list_empty(&master->mounts)) {
- master_mutex_unlock();
-- error(LOGOPT_ANY, "no mounts in table");
-+ warn(LOGOPT_ANY, "no mounts in table");
- return 1;
- }
-
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 20562bd..da8c599 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -14,6 +14,7 @@
- - fix version passed to get_supported_ver_and_cost.
- - mark map instances stale so they aren't "cleaned" during updates.
- - fix large file compile time option.
-+- don't fail on empty master map.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/lib/master.c b/lib/master.c
-index 4d31959..9f24f7e 100644
---- a/lib/master.c
-+++ b/lib/master.c
-@@ -803,7 +803,7 @@ int master_read_master(struct master *master, time_t age, int readall)
- if (list_empty(&master->mounts)) {
- master_mutex_unlock();
- error(LOGOPT_ANY, "no mounts in table");
-- return 0;
-+ return 1;
- }
-
- master_mutex_unlock();
+++ /dev/null
-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) {
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index f8260b1..be50aad 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -44,6 +44,7 @@
- - fix schema selection in LDAP schema discovery.
- - update negative mount timeout handling.
- - fix large group handling (Ryan Thomas).
-+- fix for dynamic logging breaking non-sasl build (Guillaume Rousse)
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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);
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index ca171a4..a7ac9fb 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -35,6 +35,7 @@
- - fix typo in autofs(5) man page.
- - fix map entry expansion when undefined macro is present.
- - remove unused export validation code.
-+- add dynamic logging (adapted from v4 patch from Jeff Moyer).
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/daemon/automount.c b/daemon/automount.c
-index 70a3b9d..9ec6923 100644
---- a/daemon/automount.c
-+++ b/daemon/automount.c
-@@ -173,7 +173,7 @@ int rmdir_path(struct autofs_point *ap, const char *path, dev_t dev)
- */
- memset(&st, 0, sizeof(st));
- if (lstat(buf, &st) != 0) {
-- crit(ap->logopt, "lstat of %s failed.", buf);
-+ crit(ap->logopt, "lstat of %s failed", buf);
- return -1;
- }
-
-@@ -234,14 +234,15 @@ int rmdir_path(struct autofs_point *ap, const char *path, dev_t dev)
- /* Like ftw, except fn gets called twice: before a directory is
- entered, and after. If the before call returns 0, the directory
- isn't entered. */
--static int walk_tree(const char *base, int (*fn) (const char *file,
-+static int walk_tree(const char *base, int (*fn) (unsigned logopt,
-+ const char *file,
- const struct stat * st,
-- int, void *), int incl, void *arg)
-+ int, void *), int incl, unsigned logopt, void *arg)
- {
- char buf[PATH_MAX + 1];
- struct stat st;
-
-- if (lstat(base, &st) != -1 && (fn) (base, &st, 0, arg)) {
-+ if (lstat(base, &st) != -1 && (fn) (logopt, base, &st, 0, arg)) {
- if (S_ISDIR(st.st_mode)) {
- struct dirent **de;
- int n;
-@@ -269,18 +270,18 @@ static int walk_tree(const char *base, int (*fn) (const char *file,
- return -1;
- }
-
-- walk_tree(buf, fn, 1, arg);
-+ walk_tree(buf, fn, 1, logopt, arg);
- free(de[n]);
- }
- free(de);
- }
- if (incl)
-- (fn) (base, &st, 1, arg);
-+ (fn) (logopt, base, &st, 1, arg);
- }
- return 0;
- }
-
--static int rm_unwanted_fn(const char *file, const struct stat *st, int when, void *arg)
-+static int rm_unwanted_fn(unsigned logopt, const char *file, const struct stat *st, int when, void *arg)
- {
- dev_t dev = *(dev_t *) arg;
- char buf[MAX_ERR_BUF];
-@@ -293,41 +294,38 @@ static int rm_unwanted_fn(const char *file, const struct stat *st, int when, voi
- }
-
- if (lstat(file, &newst)) {
-- crit(LOGOPT_ANY,
-- "unable to stat file, possible race condition");
-+ crit(logopt, "unable to stat file, possible race condition");
- return 0;
- }
-
- if (newst.st_dev != dev) {
-- crit(LOGOPT_ANY,
-- "file %s has the wrong device, possible race condition",
-+ crit(logopt, "file %s has the wrong device, possible race condition",
- file);
- return 0;
- }
-
- if (S_ISDIR(newst.st_mode)) {
-- debug(LOGOPT_ANY, "removing directory %s", file);
-+ debug(logopt, "removing directory %s", file);
- if (rmdir(file)) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- warn(LOGOPT_ANY,
-+ warn(logopt,
- "unable to remove directory %s: %s", file, estr);
- return 0;
- }
- } else if (S_ISREG(newst.st_mode)) {
-- crit(LOGOPT_ANY,
-- "attempting to remove files from a mounted "
-+ crit(logopt, "attempting to remove files from a mounted "
- "directory. file %s", file);
- return 0;
- } else if (S_ISLNK(newst.st_mode)) {
-- debug(LOGOPT_ANY, "removing symlink %s", file);
-+ debug(logopt, "removing symlink %s", file);
- unlink(file);
- }
- return 1;
- }
-
--void rm_unwanted(const char *path, int incl, dev_t dev)
-+void rm_unwanted(unsigned logopt, const char *path, int incl, dev_t dev)
- {
-- walk_tree(path, rm_unwanted_fn, incl, &dev);
-+ walk_tree(path, rm_unwanted_fn, incl, logopt, &dev);
- }
-
- struct counter_args {
-@@ -335,7 +333,7 @@ struct counter_args {
- dev_t dev;
- };
-
--static int counter_fn(const char *file, const struct stat *st, int when, void *arg)
-+static int counter_fn(unsigned logopt, const char *file, const struct stat *st, int when, void *arg)
- {
- struct counter_args *counter = (struct counter_args *) arg;
-
-@@ -349,14 +347,14 @@ static int counter_fn(const char *file, const struct stat *st, int when, void *a
- }
-
- /* Count mounted filesystems and symlinks */
--int count_mounts(const char *path, dev_t dev)
-+int count_mounts(unsigned logopt, const char *path, dev_t dev)
- {
- struct counter_args counter;
-
- counter.count = 0;
- counter.dev = dev;
-
-- if (walk_tree(path, counter_fn, 0, &counter) == -1)
-+ if (walk_tree(path, counter_fn, 0, logopt, &counter) == -1)
- return -1;
-
- return counter.count;
-@@ -368,9 +366,9 @@ static void check_rm_dirs(struct autofs_point *ap, const char *path, int incl)
- (ap->state == ST_SHUTDOWN_PENDING ||
- ap->state == ST_SHUTDOWN_FORCE ||
- ap->state == ST_SHUTDOWN))
-- rm_unwanted(path, incl, ap->dev);
-+ rm_unwanted(ap->logopt, path, incl, ap->dev);
- else if (ap->ghost && (ap->type == LKP_INDIRECT))
-- rm_unwanted(path, 0, ap->dev);
-+ rm_unwanted(ap->logopt, path, 0, ap->dev);
- }
-
- /* Try to purge cache entries kept around due to existing mounts */
-@@ -466,7 +464,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
- cache_multi_lock(me->parent);
- if (umount_multi_triggers(ap, root, me, base)) {
- warn(ap->logopt,
-- "could not umount some offsets under %s", path);
-+ "some offset mounts still present under %s", path);
- left++;
- }
- cache_multi_unlock(me->parent);
-@@ -483,7 +481,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
- * it already to ensure it's ok to remove any offset triggers.
- */
- if (!is_mm_root && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
-- msg("unmounting dir = %s", path);
-+ info(ap->logopt, "unmounting dir = %s", path);
- if (umount_ent(ap, path)) {
- warn(ap->logopt, "could not umount dir %s", path);
- left++;
-@@ -576,35 +574,35 @@ int umount_autofs(struct autofs_point *ap, int force)
- return ret;
- }
-
--int send_ready(int ioctlfd, unsigned int wait_queue_token)
-+int send_ready(unsigned logopt, int ioctlfd, unsigned int wait_queue_token)
- {
- char buf[MAX_ERR_BUF];
-
- if (wait_queue_token == 0)
- return 0;
-
-- debug(LOGOPT_NONE, "token = %d", wait_queue_token);
-+ debug(logopt, "token = %d", wait_queue_token);
-
- if (ioctl(ioctlfd, AUTOFS_IOC_READY, wait_queue_token) < 0) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(LOGOPT_ANY, "AUTOFS_IOC_READY: error %s", estr);
-+ logerr("AUTOFS_IOC_READY: error %s", estr);
- return 1;
- }
- return 0;
- }
-
--int send_fail(int ioctlfd, unsigned int wait_queue_token)
-+int send_fail(unsigned logopt, int ioctlfd, unsigned int wait_queue_token)
- {
- char buf[MAX_ERR_BUF];
-
- if (wait_queue_token == 0)
- return 0;
-
-- debug(LOGOPT_NONE, "token = %d", wait_queue_token);
-+ debug(logopt, "token = %d", wait_queue_token);
-
- if (ioctl(ioctlfd, AUTOFS_IOC_FAIL, wait_queue_token) < 0) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(LOGOPT_ANY, "AUTOFS_IOC_FAIL: error %s", estr);
-+ logerr("AUTOFS_IOC_FAIL: error %s", estr);
- return 1;
- }
- return 0;
-@@ -649,23 +647,245 @@ static int fullread(int fd, void *ptr, size_t len)
- return 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 ret;
-+
-+ fifo_name = malloc(name_len);
-+ if (!fifo_name)
-+ return NULL;
-+ ret = snprintf(fifo_name, name_len, "%s%s",
-+ AUTOFS_LOGPRI_FIFO, path);
-+ if (ret >= name_len) {
-+ info(logopt,
-+ "fifo path for \"%s\" truncated to \"%s\". This may "
-+ "lead to --set-log-priority commands being sent to the "
-+ "wrong automount daemon.", path, fifo_name);
-+ }
-+
-+ /*
-+ * An automount path can be made up of subdirectories. So, to
-+ * create the fifo name, we will just replace instances of '/' with
-+ * '-'.
-+ */
-+ p = fifo_name + strlen(AUTOFS_LOGPRI_FIFO);
-+ while (*p != '\0') {
-+ if (*p == '/')
-+ *p = '-';
-+ p++;
-+ }
-+
-+ debug(logopt, "fifo name %s",fifo_name);
-+
-+ return fifo_name;
-+}
-+
-+static int create_logpri_fifo(struct autofs_point *ap)
-+{
-+ int ret = -1;
-+ int fd;
-+ char *fifo_name;
-+
-+ fifo_name = automount_path_to_fifo(ap->logopt, ap->path);
-+ if (!fifo_name) {
-+ crit(ap->logopt, "Failed to allocate memory!");
-+ goto out_free; /* free(NULL) is okay */
-+ }
-+
-+ ret = unlink(fifo_name);
-+ if (ret != 0 && errno != ENOENT) {
-+ crit(ap->logopt,
-+ "Failed to unlink FIFO. Is the automount daemon "
-+ "already running?");
-+ goto out_free;
-+ }
-+
-+ ret = mkfifo(fifo_name, S_IRUSR|S_IWUSR);
-+ if (ret != 0) {
-+ crit(ap->logopt,
-+ "mkfifo for %s returned %d", fifo_name, errno);
-+ goto out_free;
-+ }
-+
-+ fd = open(fifo_name, O_RDWR|O_NONBLOCK);
-+ if (fd < 0) {
-+ crit(ap->logopt,
-+ "Failed to open %s, errno %d", fifo_name, errno);
-+ goto out_free;
-+ }
-+
-+ ap->logpri_fifo = fd;
-+
-+out_free:
-+ free(fifo_name);
-+ return ret;
-+}
-+
-+static int destroy_logpri_fifo(struct autofs_point *ap)
-+{
-+ int ret = -1;
-+ int fd = ap->logpri_fifo;
-+ char *fifo_name;
-+
-+ fifo_name = automount_path_to_fifo(ap->logopt, ap->path);
-+ if (!fifo_name) {
-+ crit(ap->logopt, "Failed to allocate memory!");
-+ goto out_free; /* free(NULL) is okay */
-+ }
-+
-+ ap->logpri_fifo = -1;
-+
-+ ret = close(fd);
-+ if (ret != 0) {
-+ warn(ap->logopt,
-+ "close for fifo %s returned %d", fifo_name, errno);
-+ }
-+
-+ ret = unlink(fifo_name);
-+ if (ret != 0) {
-+ warn(ap->logopt,
-+ "Failed to unlink FIFO. Was the fifo created OK?");
-+ }
-+
-+out_free:
-+ free(fifo_name);
-+ return ret;
-+}
-+
-+static void handle_fifo_message(struct autofs_point *ap, int fd)
-+{
-+ int ret;
-+ char buffer[PIPE_BUF];
-+ char *end;
-+ long pri;
-+
-+ memset(buffer, 0, sizeof(buffer));
-+ ret = read(fd, &buffer, sizeof(buffer));
-+ if (ret < 0) {
-+ warn(ap->logopt, "read on fifo returned error %d", errno);
-+ return;
-+ }
-+
-+ if (ret != 2) {
-+ debug(ap->logopt, "expected 2 bytes, received %d.", ret);
-+ return;
-+ }
-+
-+ errno = 0;
-+ pri = strtol(buffer, &end, 10);
-+ if ((pri == LONG_MIN || pri == LONG_MAX) && errno == ERANGE) {
-+ debug(ap->logopt, "strtol reported an %s. Failed to set "
-+ "log priority.", pri == LONG_MIN ? "underflow" : "overflow");
-+ return;
-+ }
-+ if ((pri == 0 && errno == EINVAL) || end == buffer) {
-+ debug(ap->logopt, "priority is expected to be an integer "
-+ "in the range 0-7 inclusive.");
-+ return;
-+ }
-+
-+ if (pri > LOG_DEBUG || pri < LOG_EMERG) {
-+ debug(ap->logopt, "invalid log priority (%ld) received "
-+ "on fifo", pri);
-+ return;
-+ }
-+
-+ /*
-+ * OK, the message passed all of the sanity checks. The
-+ * automounter actually only supports three log priorities.
-+ * Everything is logged at log level debug, deamon messages
-+ * and everything except debug messages are logged with the
-+ * verbose setting and only error and critical messages are
-+ * logged when debugging isn't enabled.
-+ */
-+ if (pri >= LOG_WARNING) {
-+ if (pri == LOG_DEBUG) {
-+ set_log_debug_ap(ap);
-+ info(ap->logopt, "Debug logging set for %s", ap->path);
-+ } else {
-+ set_log_verbose_ap(ap);
-+ info(ap->logopt, "Verbose logging set for %s", ap->path);
-+ }
-+ } else {
-+ if (ap->logopt & LOGOPT_ANY)
-+ info(ap->logopt, "Basic logging set for %s", ap->path);
-+ set_log_norm_ap(ap);
-+ }
-+}
-+
-+static int set_log_priority(const char *path, int priority)
-+{
-+ int fd;
-+ char *fifo_name;
-+ char buf[2];
-+
-+ if (priority > LOG_DEBUG || priority < LOG_EMERG) {
-+ fprintf(stderr, "Log priority %d is invalid.\n", priority);
-+ fprintf(stderr, "Please spcify a number in the range 0-7.\n");
-+ return -1;
-+ }
-+
-+ /*
-+ * This is an ascii based protocol, so we want the string
-+ * representation of the integer log priority.
-+ */
-+ snprintf(buf, sizeof(buf), "%d", priority);
-+
-+ fifo_name = automount_path_to_fifo(LOGOPT_NONE, path);
-+ if (!fifo_name) {
-+ fprintf(stderr, "%s: Failed to allocate memory!\n",
-+ __FUNCTION__);
-+ return -1;
-+ }
-+
-+ /*
-+ * Specify O_NONBLOCK so that the open will fail if there is no
-+ * daemon reading from the other side of the FIFO.
-+ */
-+ 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);
-+ 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);
-+ close(fd);
-+ free(fifo_name);
-+ return -1;
-+ }
-+ close(fd);
-+ free(fifo_name);
-+ fprintf(stdout, "Successfully set log priority for %s.\n", path);
-+
-+ return 0;
-+}
-+
- static int get_pkt(struct autofs_point *ap, union autofs_packet_union *pkt)
- {
-- struct pollfd fds[2];
-+ struct pollfd fds[3];
- char buf[MAX_ERR_BUF];
-
- fds[0].fd = ap->pipefd;
- fds[0].events = POLLIN;
- fds[1].fd = ap->state_pipe[0];
- fds[1].events = POLLIN;
-+ fds[2].fd = ap->logpri_fifo;
-+ fds[2].events = POLLIN;
-
- for (;;) {
-- if (poll(fds, 2, -1) == -1) {
-+ if (poll(fds, 3, -1) == -1) {
- char *estr;
- if (errno == EINTR)
- continue;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, "poll failed: %s", estr);
-+ logerr("poll failed: %s", estr);
- return -1;
- }
-
-@@ -709,6 +929,11 @@ 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) {
-+ debug(ap->logopt, "message pending on control fifo.");
-+ handle_fifo_message(ap, fds[2].fd);
-+ }
- }
- }
-
-@@ -730,21 +955,93 @@ int do_expire(struct autofs_point *ap, const char *name, int namelen)
- return 1;
- }
-
-- msg("expiring path %s", buf);
-+ info(ap->logopt, "expiring path %s", buf);
-
- ret = umount_multi(ap, buf, 1);
- if (ret == 0)
-- msg("expired %s", buf);
-+ info(ap->logopt, "expired %s", buf);
- else
- warn(ap->logopt, "couldn't complete expire of %s", buf);
-
- return ret;
- }
-
-+static int autofs_init_ap(struct autofs_point *ap)
-+{
-+ int pipefd[2], cl_flags;
-+
-+ if ((ap->state != ST_INIT)) {
-+ /* This can happen if an autofs process is already running*/
-+ error(ap->logopt, "bad state %d", ap->state);
-+ return -1;
-+ }
-+
-+ ap->pipefd = ap->kpipefd = ap->ioctlfd = -1;
-+
-+ /* Pipe for kernel communications */
-+ if (pipe(pipefd) < 0) {
-+ crit(ap->logopt,
-+ "failed to create commumication pipe for autofs path %s",
-+ ap->path);
-+ free(ap->path);
-+ return -1;
-+ }
-+
-+ ap->pipefd = pipefd[0];
-+ ap->kpipefd = pipefd[1];
-+
-+ if ((cl_flags = fcntl(ap->pipefd, F_GETFD, 0)) != -1) {
-+ cl_flags |= FD_CLOEXEC;
-+ fcntl(ap->pipefd, F_SETFD, cl_flags);
-+ }
-+
-+ if ((cl_flags = fcntl(ap->kpipefd, F_GETFD, 0)) != -1) {
-+ cl_flags |= FD_CLOEXEC;
-+ fcntl(ap->kpipefd, F_SETFD, cl_flags);
-+ }
-+
-+ /* Pipe state changes from signal handler to main loop */
-+ if (pipe(ap->state_pipe) < 0) {
-+ crit(ap->logopt,
-+ "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;
-+ }
-+
-+ if ((cl_flags = fcntl(ap->state_pipe[0], F_GETFD, 0)) != -1) {
-+ cl_flags |= FD_CLOEXEC;
-+ fcntl(ap->state_pipe[0], F_SETFD, cl_flags);
-+ }
-+
-+ if ((cl_flags = fcntl(ap->state_pipe[1], F_GETFD, 0)) != -1) {
-+ cl_flags |= FD_CLOEXEC;
-+ fcntl(ap->state_pipe[1], F_SETFD, cl_flags);
-+ }
-+
-+ 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;
-+ }
-+
-+ return 0;
-+}
-+
- static int mount_autofs(struct autofs_point *ap)
- {
- int status = 0;
-
-+ if (autofs_init_ap(ap) != 0)
-+ return -1;
-+
- if (ap->type == LKP_DIRECT)
- status = mount_autofs_direct(ap);
- else
-@@ -841,9 +1138,8 @@ static void become_daemon(unsigned foreground)
- fclose(pidfp);
- } else {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- warn(LOGOPT_ANY,
-- "failed to write pid file %s: %s",
-- pid_file, estr);
-+ logerr("failed to write pid file %s: %s",
-+ pid_file, estr);
- pid_file = NULL;
- }
- }
-@@ -889,12 +1185,12 @@ static void *do_notify_state(void *arg)
-
- master = mrc.master;
-
-- debug(master->default_logging, "signal %d", sig);
-+ debug(master->logopt, "signal %d", sig);
-
- mrc.signaled = 1;
- status = pthread_cond_signal(&mrc.cond);
- if (status) {
-- error(master->default_logging,
-+ error(master->logopt,
- "failed to signal state notify condition");
- status = pthread_mutex_unlock(&mrc.mutex);
- if (status)
-@@ -923,7 +1219,7 @@ static pthread_t do_signals(struct master *master, int sig)
-
- status = pthread_create(&thid, &thread_attr, do_notify_state, &r_sig);
- if (status) {
-- error(master->default_logging,
-+ error(master->logopt,
- "mount state notify thread create failed");
- status = pthread_mutex_unlock(&mrc.mutex);
- if (status)
-@@ -951,6 +1247,7 @@ static pthread_t do_signals(struct master *master, int sig)
- static void *do_read_master(void *arg)
- {
- struct master *master;
-+ unsigned int logopt;
- time_t age;
- int readall = 1;
- int status;
-@@ -961,11 +1258,12 @@ static void *do_read_master(void *arg)
-
- master = mrc.master;
- age = mrc.age;
-+ logopt = master->logopt;
-
- mrc.signaled = 1;
- status = pthread_cond_signal(&mrc.cond);
- if (status) {
-- error(master->default_logging,
-+ error(logopt,
- "failed to signal master read map condition");
- master->reading = 0;
- status = pthread_mutex_unlock(&mrc.mutex);
-@@ -989,6 +1287,7 @@ static void *do_read_master(void *arg)
-
- static int do_hup_signal(struct master *master, time_t age)
- {
-+ unsigned int logopt = master->logopt;
- pthread_t thid;
- int status;
-
-@@ -1007,7 +1306,7 @@ static int do_hup_signal(struct master *master, time_t age)
-
- status = pthread_create(&thid, &thread_attr, do_read_master, NULL);
- if (status) {
-- error(master->default_logging,
-+ error(logopt,
- "master read map thread create failed");
- master->reading = 0;
- status = pthread_mutex_unlock(&mrc.mutex);
-@@ -1062,8 +1361,7 @@ static void *statemachine(void *arg)
- break;
-
- default:
-- error(master_list->default_logging,
-- "got unexpected signal %d!", sig);
-+ logerr("got unexpected signal %d!", sig);
- continue;
- }
- }
-@@ -1134,10 +1432,11 @@ static void handle_mounts_cleanup(void *arg)
- struct autofs_point *ap;
- char path[PATH_MAX + 1];
- char buf[MAX_ERR_BUF];
-- unsigned int clean = 0, submount;
-+ unsigned int clean = 0, submount, logopt;
-
- ap = (struct autofs_point *) arg;
-
-+ logopt = ap->logopt;
- submount = ap->submount;
-
- strcpy(path, ap->path);
-@@ -1152,6 +1451,7 @@ static void handle_mounts_cleanup(void *arg)
-
- umount_autofs(ap, 1);
-
-+ destroy_logpri_fifo(ap);
- master_signal_submount(ap, MASTER_SUBMNT_JOIN);
- master_remove_mapent(ap->entry);
- master_free_mapent_sources(ap->entry, 1);
-@@ -1162,12 +1462,12 @@ static void handle_mounts_cleanup(void *arg)
- if (clean) {
- if (rmdir(path) == -1) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- warn(LOGOPT_NONE, "failed to remove dir %s: %s",
-+ warn(logopt, "failed to remove dir %s: %s",
- path, estr);
- }
- }
-
-- msg("shut down path %s", path);
-+ info(logopt, "shut down path %s", path);
-
- /* If we are the last tell the state machine to shutdown */
- if (!submount && master_list_empty(master_list))
-@@ -1190,7 +1490,7 @@ void *handle_mounts(void *arg)
-
- status = pthread_mutex_lock(&suc.mutex);
- if (status) {
-- crit(ap->logopt, "failed to lock startup condition mutex!");
-+ logerr("failed to lock startup condition mutex!");
- fatal(status);
- }
-
-@@ -1204,7 +1504,7 @@ void *handle_mounts(void *arg)
- }
-
- if (ap->ghost && ap->type != LKP_DIRECT)
-- msg("ghosting enabled");
-+ info(ap->logopt, "ghosting enabled");
-
- suc.status = 0;
- pthread_cleanup_pop(1);
-@@ -1356,6 +1656,8 @@ static void usage(void)
- " use ramdom replicated server selection\n"
- " -O --global-options\n"
- " specify global mount options\n"
-+ " -l --set-log-priority priority path [path,...]\n"
-+ " set daemon log verbosity\n"
- " -V --version print version, build config and exit\n"
- , program);
- }
-@@ -1437,9 +1739,45 @@ static void show_build_info(void)
- return;
- }
-
-+typedef struct _code {
-+ char *c_name;
-+ int c_val;
-+} CODE;
-+
-+CODE prioritynames[] = {
-+ { "alert", LOG_ALERT },
-+ { "crit", LOG_CRIT },
-+ { "debug", LOG_DEBUG },
-+ { "emerg", LOG_EMERG },
-+ { "err", LOG_ERR },
-+ { "error", LOG_ERR }, /* DEPRECATED */
-+ { "info", LOG_INFO },
-+ { "notice", LOG_NOTICE },
-+ { "panic", LOG_EMERG }, /* DEPRECATED */
-+ { "warn", LOG_WARNING }, /* DEPRECATED */
-+ { "warning", LOG_WARNING },
-+ { NULL, -1 },
-+};
-+
-+static int convert_log_priority(char *priority_name)
-+{
-+ CODE *priority_mapping;
-+
-+ for (priority_mapping = prioritynames;
-+ priority_mapping->c_name != NULL;
-+ priority_mapping++) {
-+
-+ if (!strcasecmp(priority_name, priority_mapping->c_name))
-+ return priority_mapping->c_val;
-+ }
-+
-+ return -1;
-+}
-+
- int main(int argc, char *argv[])
- {
- int res, opt, status;
-+ int logpri = -1;
- unsigned ghost, logging;
- unsigned foreground, have_global_options;
- time_t timeout;
-@@ -1457,6 +1795,7 @@ int main(int argc, char *argv[])
- {"random-multimount-selection", 0, 0, 'r'},
- {"global-options", 1, 0, 'O'},
- {"version", 0, 0, 'V'},
-+ {"set-log-priority", 1, 0, 'l'},
- {0, 0, 0, 0}
- };
-
-@@ -1477,7 +1816,7 @@ int main(int argc, char *argv[])
- foreground = 0;
-
- opterr = 0;
-- while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:", long_options, NULL)) != EOF) {
-+ while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:", long_options, NULL)) != EOF) {
- switch (opt) {
- case 'h':
- usage();
-@@ -1525,6 +1864,23 @@ int main(int argc, char *argv[])
- program);
- break;
-
-+ case 'l':
-+ if (isalpha(*optarg)) {
-+ logpri = convert_log_priority(optarg);
-+ if (logpri < 0) {
-+ fprintf(stderr, "Invalid log priority:"
-+ " %s\n", optarg);
-+ exit(1);
-+ }
-+ } else if (isdigit(*optarg)) {
-+ logpri = getnumopt(optarg, opt);
-+ } else {
-+ fprintf(stderr, "non-alphanumeric character "
-+ "found in log priority. Aborting.\n");
-+ exit(1);
-+ }
-+ break;
-+
- case '?':
- case ':':
- printf("%s: Ambiguous or unknown options\n", program);
-@@ -1548,6 +1904,26 @@ int main(int argc, char *argv[])
- argv += optind;
- argc -= optind;
-
-+ if (logpri >= 0) {
-+ int exit_code = 0;
-+ int i;
-+
-+ /*
-+ * The remaining argv elements are the paths for which
-+ * log priorities must be changed.
-+ */
-+ for (i = 0; i < argc; i++) {
-+ if (set_log_priority(argv[i], logpri) < 0)
-+ exit_code = 1;
-+ }
-+ if (argc < 1) {
-+ fprintf(stderr,
-+ "--set-log-priority requires a path.\n");
-+ exit_code = 1;
-+ }
-+ exit(exit_code);
-+ }
-+
- if (is_automount_running() > 0) {
- fprintf(stderr, "%s: program is already running.\n",
- program);
-@@ -1572,7 +1948,7 @@ int main(int argc, char *argv[])
- rlim.rlim_max = MAX_OPEN_FILES;
- res = setrlimit(RLIMIT_NOFILE, &rlim);
- if (res)
-- warn(LOGOPT_NONE,
-+ warn(logging,
- "can't increase open file limit - continuing");
-
- #if ENABLE_CORES
-@@ -1580,7 +1956,7 @@ int main(int argc, char *argv[])
- rlim.rlim_max = RLIM_INFINITY;
- res = setrlimit(RLIMIT_CORE, &rlim);
- if (res)
-- warn(LOGOPT_NONE,
-+ warn(logging,
- "can't increase core file limit - continuing");
- #endif
-
-@@ -1592,15 +1968,14 @@ int main(int argc, char *argv[])
- master_list = master_new(argv[0], timeout, ghost);
-
- if (!master_list) {
-- crit(LOGOPT_ANY, "%s: can't create master map %s",
-+ logerr("%s: can't create master map %s",
- program, argv[0]);
- close(start_pipefd[1]);
- exit(1);
- }
-
- if (pthread_attr_init(&thread_attr)) {
-- crit(LOGOPT_ANY,
-- "%s: failed to init thread attribute struct!",
-+ logerr("%s: failed to init thread attribute struct!",
- program);
- close(start_pipefd[1]);
- exit(1);
-@@ -1608,8 +1983,7 @@ int main(int argc, char *argv[])
-
- if (pthread_attr_setdetachstate(
- &thread_attr, PTHREAD_CREATE_DETACHED)) {
-- crit(LOGOPT_ANY,
-- "%s: failed to set detached thread attribute!",
-+ logerr("%s: failed to set detached thread attribute!",
- program);
- close(start_pipefd[1]);
- exit(1);
-@@ -1618,38 +1992,37 @@ int main(int argc, char *argv[])
- #ifdef _POSIX_THREAD_ATTR_STACKSIZE
- if (pthread_attr_setstacksize(
- &thread_attr, PTHREAD_STACK_MIN*64)) {
-- crit(LOGOPT_ANY,
-- "%s: failed to set stack size thread attribute!",
-- program);
-+ logerr("%s: failed to set stack size thread attribute!",
-+ program);
- close(start_pipefd[1]);
- exit(1);
- }
- #endif
-
-- msg("Starting automounter version %s, master map %s",
-+ info(logging, "Starting automounter version %s, master map %s",
- version, master_list->name);
-- msg("using kernel protocol version %d.%02d",
-+ info(logging, "using kernel protocol version %d.%02d",
- get_kver_major(), get_kver_minor());
-
- status = pthread_key_create(&key_thread_stdenv_vars,
- key_thread_stdenv_vars_destroy);
- if (status) {
-- crit(LOGOPT_ANY,
-- "failed to create thread data key for std env vars!");
-+ logerr("%s: failed to create thread data key for std env vars!",
-+ program);
- master_kill(master_list);
- close(start_pipefd[1]);
- exit(1);
- }
-
- if (!alarm_start_handler()) {
-- crit(LOGOPT_ANY, "failed to create alarm handler thread!");
-+ logerr("%s: failed to create alarm handler thread!", program);
- master_kill(master_list);
- close(start_pipefd[1]);
- exit(1);
- }
-
- if (!st_start_handler()) {
-- crit(LOGOPT_ANY, "failed to create FSM handler thread!");
-+ logerr("%s: failed to create FSM handler thread!", program);
- master_kill(master_list);
- close(start_pipefd[1]);
- exit(1);
-@@ -1685,5 +2058,7 @@ int main(int argc, char *argv[])
- if (dh)
- dlclose(dh);
- #endif
-+ info(logging, "autofs stopped");
-+
- exit(0);
- }
-diff --git a/daemon/direct.c b/daemon/direct.c
-index 9a39a6f..4ab4204 100644
---- a/daemon/direct.c
-+++ b/daemon/direct.c
-@@ -86,61 +86,6 @@ static void mnts_cleanup(void *arg)
- return;
- }
-
--static int autofs_init_direct(struct autofs_point *ap)
--{
-- int pipefd[2], cl_flags;
--
-- if ((ap->state != ST_INIT)) {
-- /* This can happen if an autofs process is already running*/
-- error(ap->logopt, "bad state %d", ap->state);
-- return -1;
-- }
--
-- ap->pipefd = ap->kpipefd = ap->ioctlfd = -1;
--
-- /* Pipe for kernel communications */
-- if (pipe(pipefd) < 0) {
-- crit(ap->logopt,
-- "failed to create commumication pipe for autofs path %s",
-- ap->path);
-- return -1;
-- }
--
-- ap->pipefd = pipefd[0];
-- ap->kpipefd = pipefd[1];
--
-- if ((cl_flags = fcntl(ap->pipefd, F_GETFD, 0)) != -1) {
-- cl_flags |= FD_CLOEXEC;
-- fcntl(ap->pipefd, F_SETFD, cl_flags);
-- }
--
-- if ((cl_flags = fcntl(ap->kpipefd, F_GETFD, 0)) != -1) {
-- cl_flags |= FD_CLOEXEC;
-- fcntl(ap->kpipefd, F_SETFD, cl_flags);
-- }
--
-- /* Pipe state changes from signal handler to main loop */
-- if (pipe(ap->state_pipe) < 0) {
-- crit(ap->logopt, "failed create state pipe for autofs path %s",
-- ap->path);
-- close(ap->pipefd);
-- close(ap->kpipefd);
-- return -1;
-- }
--
-- if ((cl_flags = fcntl(ap->state_pipe[0], F_GETFD, 0)) != -1) {
-- cl_flags |= FD_CLOEXEC;
-- fcntl(ap->state_pipe[0], F_SETFD, cl_flags);
-- }
--
-- if ((cl_flags = fcntl(ap->state_pipe[1], F_GETFD, 0)) != -1) {
-- cl_flags |= FD_CLOEXEC;
-- fcntl(ap->state_pipe[1], F_SETFD, cl_flags);
-- }
--
-- return 0;
--}
--
- int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me)
- {
- char buf[MAX_ERR_BUF];
-@@ -241,10 +186,10 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, stru
-
- force_umount:
- if (rv != 0) {
-- msg("forcing umount of direct mount %s", me->key);
-+ info(ap->logopt, "forcing umount of direct mount %s", me->key);
- rv = umount2(me->key, MNT_DETACH);
- } else
-- msg("umounted direct mount %s", me->key);
-+ info(ap->logopt, "umounted direct mount %s", me->key);
-
- if (!rv && me->dir_created) {
- if (rmdir(me->key) == -1) {
-@@ -326,7 +271,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct list_head *list)
- continue;
-
- if (strcmp(mnt->fs_type, "autofs"))
-- rv = spawn_umount(log_debug, "-l", mnt->path, NULL);
-+ rv = spawn_umount(ap->logopt, "-l", mnt->path, NULL);
- else
- rv = umount2(mnt->path, MNT_DETACH);
- if (rv == -1) {
-@@ -475,13 +420,15 @@ int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struc
- ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
-
- if (ap->exp_timeout)
-- msg("mounted direct mount on %s "
-+ info(ap->logopt,
-+ "mounted direct mount on %s "
- "with timeout %u, freq %u seconds", me->key,
- (unsigned int) ap->exp_timeout,
- (unsigned int) ap->exp_runfreq);
- else
-- msg("mounted direct mount on %s with timeouts disabled",
-- me->key);
-+ info(ap->logopt,
-+ "mounted direct mount on %s with timeouts disabled",
-+ me->key);
-
- ret = fstat(ioctlfd, &st);
- if (ret == -1) {
-@@ -522,9 +469,6 @@ int mount_autofs_direct(struct autofs_point *ap)
- return -1;
- }
-
-- if (autofs_init_direct(ap))
-- return -1;
--
- /* TODO: check map type */
- if (lookup_nss_read_map(ap, NULL, now))
- lookup_prune_cache(ap, now);
-@@ -607,7 +551,7 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
- /* 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",
-+ "offset %s not mounted",
- me->key);
- return 0;
- }
-@@ -627,7 +571,7 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
- rv = ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
- if (rv) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, "ioctl failed: %s", estr);
-+ logerr("ioctl failed: %s", estr);
- return 1;
- } else if (!status) {
- if (ap->state != ST_SHUTDOWN_FORCE) {
-@@ -692,10 +636,10 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
-
- force_umount:
- if (rv != 0) {
-- msg("forcing umount of offset mount %s", me->key);
-+ info(ap->logopt, "forcing umount of offset mount %s", me->key);
- rv = umount2(me->key, MNT_DETACH);
- } else
-- msg("umounted offset mount %s", me->key);
-+ info(ap->logopt, "umounted offset mount %s", me->key);
-
- if (!rv && me->dir_created) {
- if (rmdir(me->key) == -1) {
-@@ -868,7 +812,7 @@ static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsig
- return 0;
- }
-
-- retries = (count_mounts(path, st.st_dev) + 1) * EXPIRE_RETRIES;
-+ retries = (count_mounts(logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
-
- while (retries--) {
- struct timespec tm = {0, 100000000};
-@@ -1018,7 +962,7 @@ void *expire_proc_direct(void *arg)
-
- if (me->ioctlfd != -1 &&
- fstat(ioctlfd, &st) != -1 &&
-- !count_mounts(next->path, st.st_dev)) {
-+ !count_mounts(ap->logopt, next->path, st.st_dev)) {
- close(ioctlfd);
- me->ioctlfd = -1;
- }
-@@ -1049,6 +993,9 @@ void *expire_proc_direct(void *arg)
- }
- pthread_cleanup_pop(1);
-
-+ if (left)
-+ info(ap->logopt, "%d remaining in %s", left, ap->path);
-+
- ec.status = left;
-
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
-@@ -1072,7 +1019,7 @@ static void pending_cond_destroy(void *arg)
- static void expire_send_fail(void *arg)
- {
- struct pending_args *mt = arg;
-- send_fail(mt->ioctlfd, mt->wait_queue_token);
-+ send_fail(mt->ap->logopt, mt->ioctlfd, mt->wait_queue_token);
- }
-
- static void free_pending_args(void *arg)
-@@ -1124,14 +1071,14 @@ static void *do_expire_direct(void *arg)
- status = do_expire(ap, mt->name, len);
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
- if (status)
-- send_fail(mt->ioctlfd, mt->wait_queue_token);
-+ send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
- else {
- struct mapent *me;
- cache_readlock(mt->mc);
- me = cache_lookup_distinct(mt->mc, mt->name);
- me->ioctlfd = -1;
- cache_unlock(mt->mc);
-- send_ready(mt->ioctlfd, mt->wait_queue_token);
-+ send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
- close(mt->ioctlfd);
- }
- pthread_setcancelstate(state, NULL);
-@@ -1194,7 +1141,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
- if (!mt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(ap->logopt, "malloc: %s", estr);
-- send_fail(me->ioctlfd, pkt->wait_queue_token);
-+ send_fail(ap->logopt, me->ioctlfd, pkt->wait_queue_token);
- cache_unlock(mc);
- pthread_setcancelstate(state, NULL);
- return 1;
-@@ -1223,7 +1170,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
- status = pthread_create(&thid, &thread_attr, do_expire_direct, mt);
- if (status) {
- error(ap->logopt, "expire thread create failed");
-- send_fail(mt->ioctlfd, pkt->wait_queue_token);
-+ send_fail(ap->logopt, mt->ioctlfd, pkt->wait_queue_token);
- cache_unlock(mc);
- expire_mutex_unlock(NULL);
- pending_cond_destroy(mt);
-@@ -1252,7 +1199,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
- static void mount_send_fail(void *arg)
- {
- struct pending_args *mt = arg;
-- send_fail(mt->ioctlfd, mt->wait_queue_token);
-+ send_fail(mt->ap->logopt, mt->ioctlfd, mt->wait_queue_token);
- close(mt->ioctlfd);
- }
-
-@@ -1319,7 +1266,7 @@ static void *do_mount_direct(void *arg)
-
- pthread_setcancelstate(state, NULL);
-
-- msg("attempting to mount entry %s", mt->name);
-+ info(ap->logopt, "attempting to mount entry %s", mt->name);
-
- /*
- * Setup thread specific data values for macro
-@@ -1445,16 +1392,16 @@ cont:
- cache_unlock(mt->mc);
- if (set_fd) {
- me->ioctlfd = mt->ioctlfd;
-- send_ready(mt->ioctlfd, mt->wait_queue_token);
-+ send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
- } else {
-- send_ready(mt->ioctlfd, mt->wait_queue_token);
-+ send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
- close(mt->ioctlfd);
- }
-- msg("mounted %s", mt->name);
-+ info(ap->logopt, "mounted %s", mt->name);
- } else {
-- send_fail(mt->ioctlfd, mt->wait_queue_token);
-+ send_fail(mt->ap->logopt, mt->ioctlfd, mt->wait_queue_token);
- close(mt->ioctlfd);
-- msg("failed to mount %s", mt->name);
-+ info(ap->logopt, "failed to mount %s", mt->name);
- }
- pthread_setcancelstate(state, NULL);
-
-@@ -1505,7 +1452,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
- * Shouldn't happen as the kernel is telling us
- * someone has walked on our mount point.
- */
-- crit(ap->logopt, "can't find map entry for (%lu,%lu)",
-+ logerr("can't find map entry for (%lu,%lu)",
- (unsigned long) pkt->dev, (unsigned long) pkt->ino);
- pthread_setcancelstate(state, NULL);
- return 1;
-@@ -1538,7 +1485,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
- if (ap->state == ST_SHUTDOWN_PENDING ||
- ap->state == ST_SHUTDOWN_FORCE ||
- ap->state == ST_SHUTDOWN) {
-- send_fail(ioctlfd, pkt->wait_queue_token);
-+ send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
- close(ioctlfd);
- cache_unlock(mc);
- pthread_setcancelstate(state, NULL);
-@@ -1549,7 +1496,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
- if (!mt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(ap->logopt, "malloc: %s", estr);
-- send_fail(ioctlfd, pkt->wait_queue_token);
-+ send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
- close(ioctlfd);
- cache_unlock(mc);
- pthread_setcancelstate(state, NULL);
-@@ -1578,7 +1525,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
- status = pthread_create(&thid, &thread_attr, do_mount_direct, mt);
- if (status) {
- error(ap->logopt, "missing mount thread create failed");
-- send_fail(ioctlfd, pkt->wait_queue_token);
-+ send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
- close(ioctlfd);
- cache_unlock(mc);
- mount_mutex_unlock(NULL);
-diff --git a/daemon/indirect.c b/daemon/indirect.c
-index 02e7045..5c422c8 100644
---- a/daemon/indirect.c
-+++ b/daemon/indirect.c
-@@ -43,63 +43,6 @@ extern pthread_attr_t thread_attr;
- static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
-
--static int autofs_init_indirect(struct autofs_point *ap)
--{
-- int pipefd[2], cl_flags;
--
-- if ((ap->state != ST_INIT)) {
-- /* This can happen if an autofs process is already running*/
-- error(ap->logopt, "bad state %d", ap->state);
-- return -1;
-- }
--
-- ap->pipefd = ap->kpipefd = ap->ioctlfd = -1;
--
-- /* Pipe for kernel communications */
-- if (pipe(pipefd) < 0) {
-- crit(ap->logopt,
-- "failed to create commumication pipe for autofs path %s",
-- ap->path);
-- free(ap->path);
-- return -1;
-- }
--
-- ap->pipefd = pipefd[0];
-- ap->kpipefd = pipefd[1];
--
-- if ((cl_flags = fcntl(ap->pipefd, F_GETFD, 0)) != -1) {
-- cl_flags |= FD_CLOEXEC;
-- fcntl(ap->pipefd, F_SETFD, cl_flags);
-- }
--
-- if ((cl_flags = fcntl(ap->kpipefd, F_GETFD, 0)) != -1) {
-- cl_flags |= FD_CLOEXEC;
-- fcntl(ap->kpipefd, F_SETFD, cl_flags);
-- }
--
-- /* Pipe state changes from signal handler to main loop */
-- if (pipe(ap->state_pipe) < 0) {
-- crit(ap->logopt,
-- "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;
-- }
--
-- if ((cl_flags = fcntl(ap->state_pipe[0], F_GETFD, 0)) != -1) {
-- cl_flags |= FD_CLOEXEC;
-- fcntl(ap->state_pipe[0], F_SETFD, cl_flags);
-- }
--
-- if ((cl_flags = fcntl(ap->state_pipe[1], F_GETFD, 0)) != -1) {
-- cl_flags |= FD_CLOEXEC;
-- fcntl(ap->state_pipe[1], F_SETFD, cl_flags);
-- }
--
-- return 0;
--}
--
- static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
- {
- struct mnt_list *this;
-@@ -118,7 +61,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
- }
-
- if (strcmp(this->fs_type, "autofs"))
-- rv = spawn_umount(log_debug, "-l", this->path, NULL);
-+ rv = spawn_umount(ap->logopt, "-l", this->path, NULL);
- else
- rv = umount2(this->path, MNT_DETACH);
- if (rv == -1) {
-@@ -222,12 +165,14 @@ static int do_mount_autofs_indirect(struct autofs_point *ap)
- ioctl(ap->ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
-
- if (ap->exp_timeout)
-- msg("mounted indirect mount on %s "
-+ info(ap->logopt,
-+ "mounted indirect mount on %s "
- "with timeout %u, freq %u seconds", ap->path,
-- (unsigned int) ap->exp_timeout,
-- (unsigned int) ap->exp_runfreq);
-+ (unsigned int) ap->exp_timeout,
-+ (unsigned int) ap->exp_runfreq);
- else
-- msg("mounted indirect mount on %s with timeouts disabled",
-+ info(ap->logopt,
-+ "mounted indirect mount on %s with timeouts disabled",
- ap->path);
-
- fstat(ap->ioctlfd, &st);
-@@ -257,9 +202,6 @@ int mount_autofs_indirect(struct autofs_point *ap)
- int status;
- int map;
-
-- if (autofs_init_indirect(ap))
-- return -1;
--
- /* TODO: read map, determine map type is OK */
- if (lookup_nss_read_map(ap, NULL, now))
- lookup_prune_cache(ap, now);
-@@ -309,7 +251,7 @@ int umount_autofs_indirect(struct autofs_point *ap)
- rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret);
- if (rv == -1) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, "ioctl failed: %s", estr);
-+ logerr("ioctl failed: %s", estr);
- return 1;
- } else if (!ret) {
- error(ap->logopt, "ask umount returned busy %s", ap->path);
-@@ -370,9 +312,9 @@ force_umount:
- "forcing umount of indirect mount %s", ap->path);
- rv = umount2(ap->path, MNT_DETACH);
- } else {
-- msg("umounted indirect mount %s", ap->path);
-+ info(ap->logopt, "umounted indirect mount %s", ap->path);
- if (ap->submount)
-- rm_unwanted(ap->path, 1, ap->dev);
-+ rm_unwanted(ap->logopt, ap->path, 1, ap->dev);
- }
-
- return rv;
-@@ -390,7 +332,7 @@ static int expire_indirect(struct autofs_point *ap, int ioctlfd, const char *pat
- return 0;
- }
-
-- retries = (count_mounts(path, st.st_dev) + 1) * EXPIRE_RETRIES;
-+ retries = (count_mounts(ap->logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
-
- while (retries--) {
- struct timespec tm = {0, 100000000};
-@@ -559,13 +501,7 @@ void *expire_proc_indirect(void *arg)
- * words) the umounts are done by the time we reach here
- */
- if (count)
-- debug(ap->logopt, "%d remaining in %s", count, ap->path);
--
-- /* If we are trying to shutdown make sure we can umount */
-- if (!ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret)) {
-- if (!ret)
-- msg("mount still busy %s", ap->path);
-- }
-+ info(ap->logopt, "%d remaining in %s", count, ap->path);
-
- ec.status = left;
-
-@@ -590,7 +526,7 @@ static void pending_cond_destroy(void *arg)
- static void expire_send_fail(void *arg)
- {
- struct pending_args *mt = arg;
-- send_fail(mt->ap->ioctlfd, mt->wait_queue_token);
-+ send_fail(mt->ap->logopt, mt->ap->ioctlfd, mt->wait_queue_token);
- }
-
- static void free_pending_args(void *arg)
-@@ -634,9 +570,9 @@ static void *do_expire_indirect(void *arg)
- status = do_expire(mt->ap, mt->name, mt->len);
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
- if (status)
-- send_fail(ap->ioctlfd, mt->wait_queue_token);
-+ send_fail(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
- else
-- send_ready(ap->ioctlfd, mt->wait_queue_token);
-+ send_ready(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
- pthread_setcancelstate(state, NULL);
-
- pthread_cleanup_pop(0);
-@@ -661,8 +597,8 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
- mt = malloc(sizeof(struct pending_args));
- if (!mt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, "malloc: %s", estr);
-- send_fail(ap->ioctlfd, pkt->wait_queue_token);
-+ logerr("malloc: %s", estr);
-+ send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
- pthread_setcancelstate(state, NULL);
- return 1;
- }
-@@ -684,7 +620,7 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
- status = pthread_create(&thid, &thread_attr, do_expire_indirect, mt);
- if (status) {
- error(ap->logopt, "expire thread create failed");
-- send_fail(ap->ioctlfd, pkt->wait_queue_token);
-+ send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
- expire_mutex_unlock(NULL);
- pending_cond_destroy(mt);
- free_pending_args(mt);
-@@ -710,7 +646,7 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
- static void mount_send_fail(void *arg)
- {
- struct pending_args *mt = arg;
-- send_fail(mt->ap->ioctlfd, mt->wait_queue_token);
-+ send_fail(mt->ap->logopt, mt->ap->ioctlfd, mt->wait_queue_token);
- }
-
- static void mount_mutex_unlock(void *arg)
-@@ -775,7 +711,7 @@ static void *do_mount_indirect(void *arg)
-
- pthread_setcancelstate(state, NULL);
-
-- msg("attempting to mount entry %s", buf);
-+ info(ap->logopt, "attempting to mount entry %s", buf);
-
- /*
- * Setup thread specific data values for macro
-@@ -887,11 +823,11 @@ cont:
- status = lookup_nss_mount(ap, NULL, mt->name, mt->len);
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
- if (status) {
-- send_ready(ap->ioctlfd, mt->wait_queue_token);
-- msg("mounted %s", buf);
-+ send_ready(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
-+ info(ap->logopt, "mounted %s", buf);
- } else {
-- send_fail(ap->ioctlfd, mt->wait_queue_token);
-- msg("failed to mount %s", buf);
-+ send_fail(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
-+ info(ap->logopt, "failed to mount %s", buf);
- }
- pthread_setcancelstate(state, NULL);
-
-@@ -918,7 +854,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
- if (ap->state == ST_SHUTDOWN_PENDING ||
- ap->state == ST_SHUTDOWN_FORCE ||
- ap->state == ST_SHUTDOWN) {
-- send_fail(ap->ioctlfd, pkt->wait_queue_token);
-+ send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
- pthread_setcancelstate(state, NULL);
- return 0;
- }
-@@ -926,8 +862,8 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
- mt = malloc(sizeof(struct pending_args));
- if (!mt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, "malloc: %s", estr);
-- send_fail(ap->ioctlfd, pkt->wait_queue_token);
-+ logerr("malloc: %s", estr);
-+ send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
- pthread_setcancelstate(state, NULL);
- return 1;
- }
-@@ -953,7 +889,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
- status = pthread_create(&thid, &thread_attr, do_mount_indirect, mt);
- if (status) {
- error(ap->logopt, "expire thread create failed");
-- send_fail(ap->ioctlfd, pkt->wait_queue_token);
-+ send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
- mount_mutex_unlock(NULL);
- pending_cond_destroy(mt);
- free_pending_args(mt);
-diff --git a/daemon/lookup.c b/daemon/lookup.c
-index 4f2b318..fd99cf2 100644
---- a/daemon/lookup.c
-+++ b/daemon/lookup.c
-@@ -103,6 +103,7 @@ static int do_read_master(struct master *master, char *type, time_t age)
-
- static int read_master_map(struct master *master, char *type, time_t age)
- {
-+ unsigned int logopt = master->logopt;
- char *path, *save_name;
- int result;
-
-@@ -117,7 +118,7 @@ static int read_master_map(struct master *master, char *type, time_t age)
- */
-
- if (strchr(master->name, '/')) {
-- error(LOGOPT_ANY, "relative path invalid in files map name");
-+ error(logopt, "relative path invalid in files map name");
- return NSS_STATUS_NOTFOUND;
- }
-
-@@ -142,6 +143,7 @@ static int read_master_map(struct master *master, char *type, time_t age)
-
- int lookup_nss_read_master(struct master *master, time_t age)
- {
-+ unsigned int logopt = master->logopt;
- struct list_head nsslist;
- struct list_head *head, *p;
- int result = NSS_STATUS_UNKNOWN;
-@@ -149,12 +151,10 @@ int lookup_nss_read_master(struct master *master, time_t age)
- /* If it starts with a '/' it has to be a file or LDAP map */
- if (*master->name == '/') {
- if (*(master->name + 1) == '/') {
-- debug(LOGOPT_NONE,
-- "reading master ldap %s", master->name);
-+ debug(logopt, "reading master ldap %s", master->name);
- result = do_read_master(master, "ldap", age);
- } else {
-- debug(LOGOPT_NONE,
-- "reading master file %s", master->name);
-+ debug(logopt, "reading master file %s", master->name);
- result = do_read_master(master, "file", age);
- }
-
-@@ -184,13 +184,11 @@ int lookup_nss_read_master(struct master *master, time_t age)
- */
- if (strncmp(name, "ldap", 4)) {
- master->name = tmp + 1;
-- debug(LOGOPT_NONE,
-- "reading master %s %s",
-+ debug(logopt, "reading master %s %s",
- source, master->name);
- } else {
- master->name = name;
-- debug(LOGOPT_NONE,
-- "reading master %s %s",
-+ debug(logopt, "reading master %s %s",
- source, tmp + 1);
- }
-
-@@ -208,7 +206,7 @@ int lookup_nss_read_master(struct master *master, time_t age)
- if (result) {
- if (!list_empty(&nsslist))
- free_sources(&nsslist);
-- error(LOGOPT_ANY, "can't to read name service switch config.");
-+ error(logopt, "can't to read name service switch config.");
- return 0;
- }
-
-@@ -220,13 +218,12 @@ int lookup_nss_read_master(struct master *master, time_t age)
-
- this = list_entry(p, struct nss_source, list);
-
-- debug(LOGOPT_NONE,
-+ debug(logopt,
- "reading master %s %s", this->source, master->name);
-
- result = read_master_map(master, this->source, age);
- if (result == NSS_STATUS_UNKNOWN) {
-- debug(LOGOPT_NONE,
-- "no map - continuing to next source");
-+ debug(logopt, "no map - continuing to next source");
- continue;
- }
-
-@@ -1008,9 +1005,10 @@ int lookup_prune_cache(struct autofs_point *ap, time_t age)
- if (this->ioctlfd == -1)
- status = cache_delete(mc, key);
- if (status != CHE_FAIL) {
-- if (ap->type == LKP_INDIRECT)
-- rmdir_path(ap, path, ap->dev);
-- else
-+ if (ap->type == LKP_INDIRECT) {
-+ if (ap->ghost)
-+ rmdir_path(ap, path, ap->dev);
-+ } else
- rmdir_path(ap, path, this->dev);
- }
- }
-diff --git a/daemon/module.c b/daemon/module.c
-index e83c929..36eca00 100644
---- a/daemon/module.c
-+++ b/daemon/module.c
-@@ -33,7 +33,7 @@ int load_autofs4_module(void)
- */
- fp = fopen("/proc/filesystems", "r");
- if (!fp) {
-- error(LOGOPT_ANY, "cannot open /proc/filesystems\n");
-+ logerr("cannot open /proc/filesystems\n");
- return 0;
- }
-
-@@ -45,7 +45,7 @@ int load_autofs4_module(void)
- }
- fclose(fp);
-
-- ret = spawnl(log_debug, PATH_MODPROBE, PATH_MODPROBE,
-+ ret = spawnl(LOGOPT_NONE, PATH_MODPROBE, PATH_MODPROBE,
- "-q", FS_MODULE_NAME, NULL);
- if (ret)
- return 0;
-@@ -72,7 +72,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
- if (!mod) {
- if (err_prefix) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, "%s%s", err_prefix, estr);
-+ logerr("%s%s", err_prefix, estr);
- }
- return NULL;
- }
-@@ -83,7 +83,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
- free(mod);
- if (err_prefix) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, "%s%s", err_prefix, estr);
-+ logerr("%s%s", err_prefix, estr);
- }
- return NULL;
- }
-@@ -91,7 +91,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
-
- if (!(dh = dlopen(fnbuf, RTLD_NOW))) {
- if (err_prefix)
-- crit(LOGOPT_ANY, "%scannot open lookup module %s (%s)",
-+ logerr("%scannot open lookup module %s (%s)",
- err_prefix, name, dlerror());
- free(mod);
- return NULL;
-@@ -100,8 +100,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
- if (!(ver = (int *) dlsym(dh, "lookup_version"))
- || *ver != AUTOFS_LOOKUP_VERSION) {
- if (err_prefix)
-- crit(LOGOPT_ANY,
-- "%slookup module %s version mismatch",
-+ logerr("%slookup module %s version mismatch",
- err_prefix, name);
- dlclose(dh);
- free(mod);
-@@ -114,7 +113,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
- !(mod->lookup_mount = (lookup_mount_t) dlsym(dh, "lookup_mount")) ||
- !(mod->lookup_done = (lookup_done_t) dlsym(dh, "lookup_done"))) {
- if (err_prefix)
-- crit(LOGOPT_ANY, "%slookup module %s corrupt", err_prefix, name);
-+ logerr("%slookup module %s corrupt", err_prefix, name);
- dlclose(dh);
- free(mod);
- return NULL;
-@@ -156,7 +155,7 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix,
- if (!mod) {
- if (err_prefix) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, "%s%s", err_prefix, estr);
-+ logerr("%s%s", err_prefix, estr);
- }
- return NULL;
- }
-@@ -167,7 +166,7 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix,
- free(mod);
- if (err_prefix) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, "%s%s", err_prefix, estr);
-+ logerr("%s%s", err_prefix, estr);
- }
- return NULL;
- }
-@@ -175,8 +174,7 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix,
-
- if (!(dh = dlopen(fnbuf, RTLD_NOW))) {
- if (err_prefix)
-- crit(LOGOPT_ANY,
-- "%scannot open parse module %s (%s)",
-+ logerr("%scannot open parse module %s (%s)",
- err_prefix, name, dlerror());
- free(mod);
- return NULL;
-@@ -185,8 +183,7 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix,
- if (!(ver = (int *) dlsym(dh, "parse_version"))
- || *ver != AUTOFS_PARSE_VERSION) {
- if (err_prefix)
-- crit(LOGOPT_ANY,
-- "%sparse module %s version mismatch",
-+ logerr("%sparse module %s version mismatch",
- err_prefix, name);
- dlclose(dh);
- free(mod);
-@@ -197,8 +194,7 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix,
- !(mod->parse_mount = (parse_mount_t) dlsym(dh, "parse_mount")) ||
- !(mod->parse_done = (parse_done_t) dlsym(dh, "parse_done"))) {
- if (err_prefix)
-- crit(LOGOPT_ANY,
-- "%sparse module %s corrupt",
-+ logerr("%sparse module %s corrupt",
- err_prefix, name);
- dlclose(dh);
- free(mod);
-@@ -240,7 +236,7 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix)
- if (!mod) {
- if (err_prefix) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, "%s%s", err_prefix, estr);
-+ logerr("%s%s", err_prefix, estr);
- }
- return NULL;
- }
-@@ -251,7 +247,7 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix)
- free(mod);
- if (err_prefix) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, "%s%s", err_prefix, estr);
-+ logerr("%s%s", err_prefix, estr);
- }
- return NULL;
- }
-@@ -259,8 +255,7 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix)
-
- if (!(dh = dlopen(fnbuf, RTLD_NOW))) {
- if (err_prefix)
-- crit(LOGOPT_ANY,
-- "%scannot open mount module %s (%s)",
-+ logerr("%scannot open mount module %s (%s)",
- err_prefix, name, dlerror());
- free(mod);
- return NULL;
-@@ -269,8 +264,7 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix)
- if (!(ver = (int *) dlsym(dh, "mount_version"))
- || *ver != AUTOFS_MOUNT_VERSION) {
- if (err_prefix)
-- crit(LOGOPT_ANY,
-- "%smount module %s version mismatch",
-+ logerr("%smount module %s version mismatch",
- err_prefix, name);
- dlclose(dh);
- free(mod);
-@@ -281,8 +275,7 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix)
- !(mod->mount_mount = (mount_mount_t) dlsym(dh, "mount_mount")) ||
- !(mod->mount_done = (mount_done_t) dlsym(dh, "mount_done"))) {
- if (err_prefix)
-- crit(LOGOPT_ANY,
-- "%smount module %s corrupt",
-+ logerr("%smount module %s corrupt",
- err_prefix, name);
- dlclose(dh);
- free(mod);
-diff --git a/daemon/spawn.c b/daemon/spawn.c
-index 271d37e..3d5ea56 100644
---- a/daemon/spawn.c
-+++ b/daemon/spawn.c
-@@ -88,7 +88,7 @@ void reset_signals(void)
-
- #define ERRBUFSIZ 2047 /* Max length of error string excl \0 */
-
--static int do_spawn(logger *log, unsigned int options, const char *prog, const char *const *argv)
-+static int do_spawn(unsigned logopt, unsigned int options, const char *prog, const char *const *argv)
- {
- pid_t f;
- int ret, status, pipefd[2];
-@@ -195,7 +195,7 @@ static int do_spawn(logger *log, unsigned int options, const char *prog, const c
- while (errp && (p = memchr(sp, '\n', errp))) {
- *p++ = '\0';
- if (sp[0]) /* Don't output empty lines */
-- log(LOGOPT_ANY, ">> %s", sp);
-+ warn(logopt, ">> %s", sp);
- errp -= (p - sp);
- sp = p;
- }
-@@ -206,7 +206,7 @@ static int do_spawn(logger *log, unsigned int options, const char *prog, const c
- if (errp >= ERRBUFSIZ) {
- /* Line too long, split */
- errbuf[errp] = '\0';
-- log(LOGOPT_ANY, ">> %s", errbuf);
-+ warn(logopt, ">> %s", errbuf);
- errp = 0;
- }
- }
-@@ -217,7 +217,7 @@ static int do_spawn(logger *log, unsigned int options, const char *prog, const c
- if (errp > 0) {
- /* End of file without \n */
- errbuf[errp] = '\0';
-- log(LOGOPT_ANY, ">> %s", errbuf);
-+ warn(logopt, ">> %s", errbuf);
- }
-
- if (waitpid(f, &ret, 0) != f)
-@@ -235,12 +235,12 @@ static int do_spawn(logger *log, unsigned int options, const char *prog, const c
- }
- }
-
--int spawnv(logger *log, const char *prog, const char *const *argv)
-+int spawnv(unsigned logopt, const char *prog, const char *const *argv)
- {
-- return do_spawn(log, SPAWN_OPT_NONE, prog, argv);
-+ return do_spawn(logopt, SPAWN_OPT_NONE, prog, argv);
- }
-
--int spawnl(logger *log, const char *prog, ...)
-+int spawnl(unsigned logopt, const char *prog, ...)
- {
- va_list arg;
- int argc;
-@@ -258,10 +258,10 @@ int spawnl(logger *log, const char *prog, ...)
- while ((*p++ = va_arg(arg, char *)));
- va_end(arg);
-
-- return do_spawn(log, SPAWN_OPT_NONE, prog, (const char **) argv);
-+ return do_spawn(logopt, SPAWN_OPT_NONE, prog, (const char **) argv);
- }
-
--int spawn_mount(logger *log, ...)
-+int spawn_mount(unsigned logopt, ...)
- {
- va_list arg;
- int argc;
-@@ -279,7 +279,7 @@ int spawn_mount(logger *log, ...)
- options = SPAWN_OPT_NONE;
- #endif
-
-- va_start(arg, log);
-+ va_start(arg, logopt);
- for (argc = 1; va_arg(arg, char *); argc++);
- va_end(arg);
-
-@@ -288,13 +288,13 @@ int spawn_mount(logger *log, ...)
-
- argv[0] = arg0;
-
-- va_start(arg, log);
-+ va_start(arg, logopt);
- p = argv + 1;
- while ((*p++ = va_arg(arg, char *)));
- va_end(arg);
-
- while (retries--) {
-- ret = do_spawn(log, options, prog, (const char **) argv);
-+ ret = do_spawn(logopt, options, prog, (const char **) argv);
- if (ret & MTAB_NOTUPDATED)
- continue;
- break;
-@@ -311,7 +311,7 @@ int spawn_mount(logger *log, ...)
- * NOTE: If mount locking is enabled this type of recursive mount cannot
- * work.
- */
--int spawn_bind_mount(logger *log, ...)
-+int spawn_bind_mount(unsigned logopt, ...)
- {
- va_list arg;
- int argc;
-@@ -330,7 +330,7 @@ int spawn_bind_mount(logger *log, ...)
- options = SPAWN_OPT_ACCESS;
- #endif
-
-- va_start(arg, log);
-+ va_start(arg, logopt);
- for (argc = 1; va_arg(arg, char *); argc++);
- va_end(arg);
-
-@@ -340,13 +340,13 @@ int spawn_bind_mount(logger *log, ...)
- argv[0] = arg0;
- argv[1] = bind;
-
-- va_start(arg, log);
-+ va_start(arg, logopt);
- p = argv + 2;
- while ((*p++ = va_arg(arg, char *)));
- va_end(arg);
-
- while (retries--) {
-- ret = do_spawn(log, options, prog, (const char **) argv);
-+ ret = do_spawn(logopt, options, prog, (const char **) argv);
- if (ret & MTAB_NOTUPDATED)
- continue;
- break;
-@@ -355,7 +355,7 @@ int spawn_bind_mount(logger *log, ...)
- return ret;
- }
-
--int spawn_umount(logger *log, ...)
-+int spawn_umount(unsigned logopt, ...)
- {
- va_list arg;
- int argc;
-@@ -372,7 +372,7 @@ int spawn_umount(logger *log, ...)
- options = SPAWN_OPT_NONE;
- #endif
-
-- va_start(arg, log);
-+ va_start(arg, logopt);
- for (argc = 1; va_arg(arg, char *); argc++);
- va_end(arg);
-
-@@ -381,13 +381,13 @@ int spawn_umount(logger *log, ...)
-
- argv[0] = arg0;
-
-- va_start(arg, log);
-+ va_start(arg, logopt);
- p = argv + 1;
- while ((*p++ = va_arg(arg, char *)));
- va_end(arg);
-
- while (retries--) {
-- ret = do_spawn(log, options, prog, (const char **) argv);
-+ ret = do_spawn(logopt, options, prog, (const char **) argv);
- if (ret & MTAB_NOTUPDATED)
- continue;
- break;
-diff --git a/daemon/state.c b/daemon/state.c
-index 39f4497..a2da762 100644
---- a/daemon/state.c
-+++ b/daemon/state.c
-@@ -58,22 +58,20 @@ void dump_state_queue(void)
- struct list_head *head = &state_queue;
- struct list_head *p, *q;
-
-- debug(LOGOPT_ANY, "dumping queue");
-+ logmsg("dumping queue");
-
- list_for_each(p, head) {
- struct state_queue *entry;
-
- entry = list_entry(p, struct state_queue, list);
-- debug(LOGOPT_ANY,
-- "queue list head path %s state %d busy %d",
-+ logmsg("queue list head path %s state %d busy %d",
- entry->ap->path, entry->state, entry->busy);
-
- list_for_each(q, &entry->pending) {
- struct state_queue *this;
-
- this = list_entry(q, struct state_queue, pending);
-- debug(LOGOPT_ANY,
-- "queue list entry path %s state %d busy %d",
-+ logmsg("queue list entry path %s state %d busy %d",
- this->ap->path, this->state, this->busy);
- }
- }
-@@ -85,7 +83,7 @@ void nextstate(int statefd, enum states next)
-
- if (write(statefd, &next, sizeof(next)) != sizeof(next)) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(LOGOPT_ANY, "write failed %s", estr);
-+ logerr("write failed %s", estr);
- }
- }
-
-diff --git a/include/automount.h b/include/automount.h
-index d55ba5c..37a3c0a 100644
---- a/include/automount.h
-+++ b/include/automount.h
-@@ -131,6 +131,7 @@ struct mapent_cache {
- unsigned int size;
- pthread_mutex_t ino_index_mutex;
- struct list_head *ino_index;
-+ struct autofs_point *ap;
- struct map_source *map;
- struct mapent **hash;
- };
-@@ -164,7 +165,7 @@ void cache_readlock(struct mapent_cache *mc);
- void cache_writelock(struct mapent_cache *mc);
- int cache_try_writelock(struct mapent_cache *mc);
- void cache_unlock(struct mapent_cache *mc);
--struct mapent_cache *cache_init(struct map_source *map);
-+struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map);
- struct mapent_cache *cache_init_null_cache(struct master *master);
- int cache_set_ino_index(struct mapent_cache *mc, const char *key, dev_t dev, ino_t ino);
- /* void cache_set_ino(struct mapent *me, dev_t dev, ino_t ino); */
-@@ -200,11 +201,11 @@ int free_argv(int argc, const char **argv);
- inline void dump_core(void);
- int aquire_lock(void);
- void release_lock(void);
--int spawnl(logger *log, const char *prog, ...);
--int spawnv(logger *log, const char *prog, const char *const *argv);
--int spawn_mount(logger *log, ...);
--int spawn_bind_mount(logger *log, ...);
--int spawn_umount(logger *log, ...);
-+int spawnl(unsigned logopt, const char *prog, ...);
-+int spawnv(unsigned logopt, const char *prog, const char *const *argv);
-+int spawn_mount(unsigned logopt, ...);
-+int spawn_bind_mount(unsigned logopt, ...);
-+int spawn_umount(unsigned logopt, ...);
- void reset_signals(void);
- int do_mount(struct autofs_point *ap, const char *root, const char *name,
- int name_len, const char *what, const char *fstype,
-@@ -222,6 +223,8 @@ 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,
-@@ -435,6 +438,7 @@ struct autofs_point {
- int pipefd; /* File descriptor for pipe */
- int kpipefd; /* Kernel end descriptor for pipe */
- int ioctlfd; /* File descriptor for ioctls */
-+ int logpri_fifo; /* FIFO used for changing log levels */
- dev_t dev; /* "Device" number assigned by kernel */
- struct master_mapent *entry; /* Master map entry for this mount */
- unsigned int type; /* Type of map direct or indirect */
-@@ -464,8 +468,8 @@ struct autofs_point {
-
- void *handle_mounts(void *arg);
- int umount_multi(struct autofs_point *ap, const char *path, int incl);
--int send_ready(int ioctlfd, unsigned int wait_queue_token);
--int send_fail(int ioctlfd, unsigned int wait_queue_token);
-+int send_ready(unsigned logopt, int ioctlfd, unsigned int wait_queue_token);
-+int send_fail(unsigned logopt, int ioctlfd, unsigned int wait_queue_token);
- int do_expire(struct autofs_point *ap, const char *name, int namelen);
- void *expire_proc_indirect(void *);
- void *expire_proc_direct(void *);
-@@ -483,8 +487,8 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
- int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_direct_t *pkt);
- int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missing_indirect_t *pkt);
- int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_direct_t *pkt);
--void rm_unwanted(const char *path, int incl, dev_t dev);
--int count_mounts(const char *path, dev_t dev);
-+void rm_unwanted(unsigned logopt, const char *path, int incl, dev_t dev);
-+int count_mounts(unsigned logopt, const char *path, dev_t dev);
-
- #define state_mutex_lock(ap) \
- do { \
-diff --git a/include/log.h b/include/log.h
-index 3276cca..6a4a942 100644
---- a/include/log.h
-+++ b/include/log.h
-@@ -20,6 +20,7 @@
- /* Define logging functions */
-
- #define LOGOPT_NONE 0x0000
-+#define LOGOPT_ERROR 0x0000
- #define LOGOPT_DEBUG 0x0001
- #define LOGOPT_VERBOSE 0x0002
- #define LOGOPT_ANY (LOGOPT_DEBUG | LOGOPT_VERBOSE)
-@@ -29,34 +30,33 @@ struct autofs_point;
- extern void set_log_norm(void);
- extern void set_log_verbose(void);
- extern void set_log_debug(void);
--extern void set_mnt_logging(struct autofs_point *);
-+extern void set_log_norm_ap(struct autofs_point *ap);
-+extern void set_log_verbose_ap(struct autofs_point *ap);
-+extern void set_log_debug_ap(struct autofs_point *ap);
-+extern void set_mnt_logging(unsigned global_logopt);
-
- extern void log_to_syslog(void);
- extern void log_to_stderr(void);
-
--typedef void logger(unsigned int logopt, const char* msg, ...);
--
--extern void (*log_info)(unsigned int, const char* msg, ...);
--extern void (*log_notice)(unsigned int, const char* msg, ...);
--extern void (*log_warn)(unsigned int, const char* msg, ...);
--extern void (*log_error)(unsigned int, const char* msg, ...);
--extern void (*log_crit)(unsigned int, const char* msg, ...);
--extern void (*log_debug)(unsigned int, const char* msg, ...);
--
--#define msg(msg, args...) \
-- do { log_info(LOGOPT_NONE, msg, ##args); } while (0)
-+extern void log_info(unsigned int, const char* msg, ...);
-+extern void log_notice(unsigned int, const char* msg, ...);
-+extern void log_warn(unsigned int, const char* msg, ...);
-+extern void log_error(unsigned, const char* msg, ...);
-+extern void log_crit(unsigned, const char* msg, ...);
-+extern void log_debug(unsigned int, const char* msg, ...);
-+extern void logmsg(const char* msg, ...);
-
- #define debug(opt, msg, args...) \
- do { log_debug(opt, "%s: " msg, __FUNCTION__, ##args); } while (0)
-
--#define info(opt, msg, args...) \
-- do { log_info(opt, "%s: " msg, __FUNCTION__, ##args); } while (0)
-+#define info(opt, msg, args...) \
-+ do { log_info(opt, msg, ##args); } while (0)
-
- #define notice(opt, msg, args...) \
-- do { log_notice(opt, "%s: " msg, __FUNCTION__, ##args); } while (0)
-+ do { log_notice(opt, msg, ##args); } while (0)
-
--#define warn(opt, msg, args...) \
-- do { log_warn(opt, "%s: " msg, __FUNCTION__, ##args); } while (0)
-+#define warn(opt, msg, args...) \
-+ do { log_warn(opt, msg, ##args); } while (0)
-
- #define error(opt, msg, args...) \
- do { log_error(opt, "%s: " msg, __FUNCTION__, ##args); } while (0)
-@@ -64,17 +64,18 @@ extern void (*log_debug)(unsigned int, const char* msg, ...);
- #define crit(opt, msg, args...) \
- do { log_crit(opt, "%s: " msg, __FUNCTION__, ##args); } while (0)
-
-+#define logerr(msg, args...) \
-+ do { logmsg("%s:%d: " msg, __FUNCTION__, __LINE__, ##args); } while (0)
-+
- #define fatal(status) \
- do { \
- if (status == EDEADLK) { \
-- log_crit(LOGOPT_ANY, \
-- "%s: deadlock detected " \
-+ logmsg("deadlock detected " \
- "at line %d in %s, dumping core.", \
-- __FUNCTION__, __LINE__, __FILE__); \
-+ __LINE__, __FILE__); \
- dump_core(); \
- } \
-- log_crit(LOGOPT_ANY, \
-- "unexpected pthreads error: %d at %d " \
-+ logmsg("unexpected pthreads error: %d at %d " \
- "in %s", status, __LINE__, __FILE__); \
- abort(); \
- } while(0)
-@@ -83,7 +84,7 @@ extern void (*log_debug)(unsigned int, const char* msg, ...);
- #define assert(x) \
- do { \
- if (!(x)) { \
-- log_crit(LOGOPT_ANY, __FILE__ \
-+ logmsg(__FILE__ \
- ":%d: assertion failed: " #x, __LINE__); \
- } \
- } while(0)
-diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
-index ca8d658..5b5c475 100644
---- a/include/lookup_ldap.h
-+++ b/include/lookup_ldap.h
-@@ -94,13 +94,13 @@ struct lookup_context {
- #define LDAP_AUTH_AUTODETECT 0x0004
-
- /* lookup_ldap.c */
--LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt);
--int unbind_ldap_connection(LDAP *ldap, struct lookup_context *ctxt);
-+LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt);
-+int unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
- int authtype_requires_creds(const char *authtype);
-
- /* cyrus-sasl.c */
--int autofs_sasl_init(LDAP *ldap, struct lookup_context *ctxt);
--int autofs_sasl_bind(LDAP *ldap, struct lookup_context *ctxt);
-+int autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
-+int autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
- void autofs_sasl_unbind(struct lookup_context *ctxt);
- void autofs_sasl_done(struct lookup_context *ctxt);
- #endif
-diff --git a/include/master.h b/include/master.h
-index 8470bb1..5f10d1f 100644
---- a/include/master.h
-+++ b/include/master.h
-@@ -62,6 +62,7 @@ struct master {
- unsigned int default_ghost;
- unsigned int default_logging;
- unsigned int default_timeout;
-+ unsigned int logopt;
- struct mapent_cache *nc;
- struct list_head mounts;
- };
-@@ -106,6 +107,7 @@ int master_notify_submount(struct autofs_point *, const char *path, enum states)
- void master_signal_submount(struct autofs_point *, unsigned int);
- void master_notify_state_change(struct master *, int);
- int master_mount_mounts(struct master *, time_t, int);
-+extern inline unsigned int master_get_logopt(void);
- int master_list_empty(struct master *);
- int master_kill(struct master *);
-
-diff --git a/include/replicated.h b/include/replicated.h
-index 3afe9f7..672f853 100644
---- a/include/replicated.h
-+++ b/include/replicated.h
-@@ -62,8 +62,8 @@ 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 *, unsigned int);
-+int parse_location(unsigned, struct host **, const char *);
-+int prune_host_list(unsigned, struct host **, unsigned int, const char *, unsigned int);
- void dump_host_list(struct host *);
-
- #endif
-diff --git a/lib/alarm.c b/lib/alarm.c
-index 90bf7aa..6a70ed1 100755
---- a/lib/alarm.c
-+++ b/lib/alarm.c
-@@ -51,7 +51,7 @@ void dump_alarms(void)
- struct alarm *this;
-
- this = list_entry(p, struct alarm, list);
-- msg("alarm time = %d", this->time);
-+ logmsg("alarm time = %d", this->time);
- }
- pthread_mutex_unlock(&mutex);
- }
-diff --git a/lib/args.c b/lib/args.c
-index fbfb004..9616598 100644
---- a/lib/args.c
-+++ b/lib/args.c
-@@ -37,7 +37,7 @@ char **add_argv(int argc, char **argv, char *str)
- if (argv[i]) {
- vector[i] = strdup(argv[i]);
- if (!vector[i]) {
-- error(LOGOPT_ANY, "failed to strdup arg");
-+ logerr("failed to strdup arg");
- break;
- }
- } else
-@@ -81,7 +81,7 @@ char **append_argv(int argc1, char **argv1, int argc2, char **argv2)
- if (argv2[j]) {
- vector[i] = strdup(argv2[j]);
- if (!vector[i]) {
-- error(LOGOPT_ANY, "failed to strdup arg");
-+ logerr("failed to strdup arg");
- break;
- }
- } else
-@@ -116,7 +116,7 @@ const char **copy_argv(int argc, const char **argv)
- if (argv[i]) {
- vector[i] = strdup(argv[i]);
- if (!vector[i]) {
-- error(LOGOPT_ANY, "failed to strdup arg");
-+ logerr("failed to strdup arg");
- break;
- }
- } else
-diff --git a/lib/cache.c b/lib/cache.c
-index 06bb461..55586a3 100644
---- a/lib/cache.c
-+++ b/lib/cache.c
-@@ -34,7 +34,7 @@ void cache_dump_multi(struct list_head *list)
-
- list_for_each(p, list) {
- me = list_entry(p, struct mapent, multi_list);
-- msg("key=%s", me->key);
-+ logmsg("key=%s", me->key);
- }
- }
-
-@@ -48,7 +48,7 @@ void cache_dump_cache(struct mapent_cache *mc)
- if (me == NULL)
- continue;
- while (me) {
-- msg("me->key=%s me->multi=%p dev=%ld ino=%ld",
-+ logmsg("me->key=%s me->multi=%p dev=%ld ino=%ld",
- me->key, me->multi, me->dev, me->ino);
- me = me->next;
- }
-@@ -61,7 +61,7 @@ void cache_readlock(struct mapent_cache *mc)
-
- status = pthread_rwlock_rdlock(&mc->rwlock);
- if (status) {
-- error(LOGOPT_ANY, "mapent cache rwlock lock failed");
-+ logmsg("mapent cache rwlock lock failed");
- fatal(status);
- }
- return;
-@@ -73,7 +73,7 @@ void cache_writelock(struct mapent_cache *mc)
-
- status = pthread_rwlock_wrlock(&mc->rwlock);
- if (status) {
-- error(LOGOPT_ANY, "mapent cache rwlock lock failed");
-+ logmsg("mapent cache rwlock lock failed");
- fatal(status);
- }
- return;
-@@ -85,7 +85,7 @@ int cache_try_writelock(struct mapent_cache *mc)
-
- status = pthread_rwlock_trywrlock(&mc->rwlock);
- if (status) {
-- debug(LOGOPT_ANY, "mapent cache rwlock busy");
-+ logmsg("mapent cache rwlock busy");
- return 0;
- }
- return 1;
-@@ -97,7 +97,7 @@ void cache_unlock(struct mapent_cache *mc)
-
- status = pthread_rwlock_unlock(&mc->rwlock);
- if (status) {
-- error(LOGOPT_ANY, "mapent cache rwlock unlock failed");
-+ logmsg("mapent cache rwlock unlock failed");
- fatal(status);
- }
- return;
-@@ -120,7 +120,7 @@ void cache_multi_lock(struct mapent *me)
-
- status = pthread_mutex_lock(&me->multi_mutex);
- if (status) {
-- error(LOGOPT_ANY, "mapent cache multi mutex lock failed");
-+ logmsg("mapent cache multi mutex lock failed");
- fatal(status);
- }
- return;
-@@ -135,7 +135,7 @@ void cache_multi_unlock(struct mapent *me)
-
- status = pthread_mutex_unlock(&me->multi_mutex);
- if (status) {
-- error(LOGOPT_ANY, "mapent cache multi mutex unlock failed");
-+ logmsg("mapent cache multi mutex unlock failed");
- fatal(status);
- }
- return;
-@@ -164,7 +164,7 @@ static inline void ino_index_unlock(struct mapent_cache *mc)
- return;
- }
-
--struct mapent_cache *cache_init(struct map_source *map)
-+struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map)
- {
- struct mapent_cache *mc;
- unsigned int i;
-@@ -207,6 +207,7 @@ struct mapent_cache *cache_init(struct map_source *map)
- INIT_LIST_HEAD(&mc->ino_index[i]);
- }
-
-+ mc->ap = ap;
- mc->map = map;
-
- cache_unlock(mc);
-@@ -257,6 +258,9 @@ struct mapent_cache *cache_init_null_cache(struct master *master)
- INIT_LIST_HEAD(&mc->ino_index[i]);
- }
-
-+ mc->ap = NULL;
-+ mc->map = NULL;
-+
- cache_unlock(mc);
-
- return mc;
-@@ -608,6 +612,7 @@ static void cache_add_ordered_offset(struct mapent *me, struct list_head *head)
- /* cache must be write locked by caller */
- int cache_add_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age)
- {
-+ unsigned logopt = mc->ap ? mc->ap->logopt : master_get_logopt();
- struct mapent *me, *owner;
- int ret = CHE_OK;
-
-@@ -621,7 +626,7 @@ int cache_add_offset(struct mapent_cache *mc, const char *mkey, const char *key,
-
- ret = cache_add(mc, owner->source, key, mapent, age);
- if (ret == CHE_FAIL) {
-- warn(LOGOPT_ANY, "failed to add key %s to cache", key);
-+ warn(logopt, "failed to add key %s to cache", key);
- return CHE_FAIL;
- }
-
-@@ -689,6 +694,7 @@ int cache_set_parents(struct mapent *mm)
- /* cache must be write locked by caller */
- int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age)
- {
-+ unsigned logopt = mc->ap ? mc->ap->logopt : master_get_logopt();
- struct mapent *me = NULL;
- char *pent;
- int ret = CHE_OK;
-@@ -697,7 +703,7 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key
- if (!me || (*me->key == '*' && *key != '*')) {
- ret = cache_add(mc, ms, key, mapent, age);
- if (!ret) {
-- debug(LOGOPT_NONE, "failed for %s", key);
-+ debug(logopt, "failed for %s", key);
- return CHE_FAIL;
- }
- ret = CHE_UPDATED;
-@@ -796,6 +802,7 @@ done:
- /* cache must be write locked by caller */
- int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
- {
-+ unsigned logopt = mc->ap ? mc->ap->logopt : master_get_logopt();
- struct mapent *me;
- struct mapent *this;
- struct list_head *head, *next;
-@@ -816,7 +823,7 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
- this = list_entry(next, struct mapent, multi_list);
- next = next->next;
- if (this->ioctlfd != -1) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- "active offset mount key %s", this->key);
- return CHE_FAIL;
- }
-@@ -829,10 +836,10 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
- next = next->next;
- list_del_init(&this->multi_list);
- this->multi = NULL;
-- debug(LOGOPT_NONE, "deleting offset key %s", this->key);
-+ debug(logopt, "deleting offset key %s", this->key);
- status = cache_delete(mc, this->key);
- if (status == CHE_FAIL) {
-- warn(LOGOPT_ANY,
-+ warn(logopt,
- "failed to delete offset %s", this->key);
- this->multi = me;
- /* TODO: add list back in */
-diff --git a/lib/defaults.c b/lib/defaults.c
-index 2cccf20..94885e8 100644
---- a/lib/defaults.c
-+++ b/lib/defaults.c
-@@ -105,17 +105,22 @@ static int get_env_yesno(const char *name)
- * We've changed the key names so we need to check for the
- * config key and it's old name for backward conpatibility.
- */
--static int check_set_config_value(const char *res, const char *name, const char *value)
-+static int check_set_config_value(const char *res, const char *name, const char *value, unsigned to_syslog)
- {
- char *old_name;
- int ret;
-
- if (!strcasecmp(res, name)) {
- ret = setenv(name, value, 0);
-- if (ret)
-- fprintf(stderr,
-- "can't set config value for %s, "
-- "error %d", name, ret);
-+ if (ret) {
-+ if (!to_syslog)
-+ fprintf(stderr,
-+ "can't set config value for %s, "
-+ "error %d\n", name, ret);
-+ else
-+ logmsg("can't set config value for %s, "
-+ "error %d", name, ret);
-+ }
- return 1;
- }
-
-@@ -125,10 +130,15 @@ static int check_set_config_value(const char *res, const char *name, const char
-
- if (!strcasecmp(res, old_name)) {
- ret = setenv(name, value, 0);
-- if (ret)
-- fprintf(stderr,
-- "can't set config value for %s, "
-- "error %d", name, ret);
-+ if (ret) {
-+ if (!to_syslog)
-+ fprintf(stderr,
-+ "can't set config value for %s, "
-+ "error %d\n", name, ret);
-+ else
-+ logmsg("can't set config value for %s, "
-+ "error %d\n", name, ret);
-+ }
- return 1;
- }
- return 0;
-@@ -296,19 +306,19 @@ unsigned int defaults_read_config(unsigned int to_syslog)
- if (!parse_line(res, &key, &value))
- continue;
-
-- 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_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) ||
-- 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))
-+ 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_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) ||
-+ check_set_config_value(key, ENV_LDAP_NETWORK_TIMEOUT, value, to_syslog) ||
-+ check_set_config_value(key, ENV_NAME_MAP_OBJ_CLASS, value, to_syslog) ||
-+ check_set_config_value(key, ENV_NAME_ENTRY_OBJ_CLASS, value, to_syslog) ||
-+ check_set_config_value(key, ENV_NAME_MAP_ATTR, value, to_syslog) ||
-+ check_set_config_value(key, ENV_NAME_ENTRY_ATTR, value, to_syslog) ||
-+ check_set_config_value(key, ENV_NAME_VALUE_ATTR, value, to_syslog) ||
-+ check_set_config_value(key, ENV_APPEND_OPTIONS, value, to_syslog) ||
-+ check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog))
- ;
- }
-
-@@ -318,8 +328,7 @@ unsigned int defaults_read_config(unsigned int to_syslog)
- "fgets returned error %d while reading %s\n",
- ferror(f), DEFAULTS_CONFIG_FILE);
- } else {
-- error(LOGOPT_ANY,
-- "fgets returned error %d while reading %s",
-+ logmsg("fgets returned error %d while reading %s",
- ferror(f), DEFAULTS_CONFIG_FILE);
- }
- fclose(f);
-diff --git a/lib/log.c b/lib/log.c
-index b747e12..65e8ad2 100644
---- a/lib/log.c
-+++ b/lib/log.c
-@@ -27,11 +27,6 @@
-
- #include "automount.h"
-
--/*
--struct syslog_data syslog_context = AUTOFS_SYSLOG_CONTEXT;
--struct syslog_data *slc = &syslog_context;
--*/
--
- static unsigned int syslog_open = 0;
- static unsigned int logging_to_syslog = 0;
-
-@@ -39,32 +34,44 @@ static unsigned int logging_to_syslog = 0;
- static unsigned int do_verbose = 0; /* Verbose feedback option */
- static unsigned int do_debug = 0; /* Full debug output */
-
--static void null(unsigned int logopt, const char *msg, ...) { }
--
--void (*log_info)(unsigned int logopt, const char* msg, ...) = null;
--void (*log_notice)(unsigned int logopt, const char* msg, ...) = null;
--void (*log_warn)(unsigned int logopt, const char* msg, ...) = null;
--void (*log_error)(unsigned int logopt, const char* msg, ...) = null;
--void (*log_crit)(unsigned int logopt, const char* msg, ...) = null;
--void (*log_debug)(unsigned int logopt, const char* msg, ...) = null;
--
- void set_log_norm(void)
- {
- do_verbose = 0;
- do_debug = 0;
-+ return;
- }
-
- void set_log_verbose(void)
- {
- do_verbose = 1;
-+ return;
- }
-
- void set_log_debug(void)
- {
- do_debug = 1;
-+ return;
-+}
-+
-+void set_log_norm_ap(struct autofs_point *ap)
-+{
-+ ap->logopt = LOGOPT_ERROR;
-+ return;
-+}
-+
-+void set_log_verbose_ap(struct autofs_point *ap)
-+{
-+ ap->logopt = LOGOPT_VERBOSE;
-+ return;
-+}
-+
-+void set_log_debug_ap(struct autofs_point *ap)
-+{
-+ ap->logopt = LOGOPT_DEBUG;
-+ return;
- }
-
--static void syslog_info(unsigned int logopt, const char *msg, ...)
-+void log_info(unsigned int logopt, const char *msg, ...)
- {
- unsigned int opt_log = logopt & (LOGOPT_DEBUG | LOGOPT_VERBOSE);
- va_list ap;
-@@ -73,11 +80,18 @@ static void syslog_info(unsigned int logopt, const char *msg, ...)
- return;
-
- va_start(ap, msg);
-- vsyslog(LOG_INFO, msg, ap);
-+ if (logging_to_syslog)
-+ vsyslog(LOG_INFO, msg, ap);
-+ else {
-+ vfprintf(stderr, msg, ap);
-+ fputc('\n', stderr);
-+ }
- va_end(ap);
-+
-+ return;
- }
-
--static void syslog_notice(unsigned int logopt, const char *msg, ...)
-+void log_notice(unsigned int logopt, const char *msg, ...)
- {
- unsigned int opt_log = logopt & (LOGOPT_DEBUG | LOGOPT_VERBOSE);
- va_list ap;
-@@ -86,11 +100,18 @@ static void syslog_notice(unsigned int logopt, const char *msg, ...)
- return;
-
- va_start(ap, msg);
-- vsyslog(LOG_NOTICE, msg, ap);
-+ if (logging_to_syslog)
-+ vsyslog(LOG_NOTICE, msg, ap);
-+ else {
-+ vfprintf(stderr, msg, ap);
-+ fputc('\n', stderr);
-+ }
- va_end(ap);
-+
-+ return;
- }
-
--static void syslog_warn(unsigned int logopt, const char *msg, ...)
-+void log_warn(unsigned int logopt, const char *msg, ...)
- {
- unsigned int opt_log = logopt & (LOGOPT_DEBUG | LOGOPT_VERBOSE);
- va_list ap;
-@@ -99,70 +120,79 @@ static void syslog_warn(unsigned int logopt, const char *msg, ...)
- return;
-
- va_start(ap, msg);
-- vsyslog(LOG_WARNING, msg, ap);
-+ if (logging_to_syslog)
-+ vsyslog(LOG_WARNING, msg, ap);
-+ else {
-+ vfprintf(stderr, msg, ap);
-+ fputc('\n', stderr);
-+ }
- va_end(ap);
-+
-+ return;
- }
-
--static void syslog_err(unsigned int logopt, const char *msg, ...)
-+void log_error(unsigned logopt, const char *msg, ...)
- {
- va_list ap;
-+
- va_start(ap, msg);
-- vsyslog(LOG_ERR, msg, ap);
-+ if (logging_to_syslog)
-+ vsyslog(LOG_ERR, msg, ap);
-+ else {
-+ vfprintf(stderr, msg, ap);
-+ fputc('\n', stderr);
-+ }
- va_end(ap);
-+ return;
- }
-
--static void syslog_crit(unsigned int logopt, const char *msg, ...)
-+void log_crit(unsigned logopt, const char *msg, ...)
- {
- va_list ap;
-+
- va_start(ap, msg);
-- vsyslog(LOG_CRIT, msg, ap);
-+ if (logging_to_syslog)
-+ vsyslog(LOG_CRIT, msg, ap);
-+ else {
-+ vfprintf(stderr, msg, ap);
-+ fputc('\n', stderr);
-+ }
- va_end(ap);
-+ return;
- }
-
--static void syslog_debug(unsigned int logopt, const char *msg, ...)
-+void log_debug(unsigned int logopt, const char *msg, ...)
- {
-+ unsigned int opt_log = logopt & LOGOPT_DEBUG;
- va_list ap;
-
-- if (!do_debug && !(logopt & LOGOPT_DEBUG))
-+ if (!do_debug && !opt_log)
- return;
-
- va_start(ap, msg);
-- vsyslog(LOG_DEBUG, msg, ap);
-+ if (logging_to_syslog)
-+ vsyslog(LOG_WARNING, msg, ap);
-+ else {
-+ vfprintf(stderr, msg, ap);
-+ fputc('\n', stderr);
-+ }
- va_end(ap);
-+
-+ return;
- }
-
--static void to_stderr(unsigned int logopt, const char *msg, ...)
-+void logmsg(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) {
-- if (logging_to_syslog)
-- log_debug = syslog_debug;
-- else
-- log_debug = to_stderr;
-- }
--
-- if (opt_verbose || opt_debug) {
-- 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;
-- }
-+ if (logging_to_syslog)
-+ vsyslog(LOG_CRIT, msg, ap);
-+ else {
-+ vfprintf(stderr, msg, ap);
-+ fputc('\n', stderr);
- }
-+ va_end(ap);
-+ return;
- }
-
- void log_to_syslog(void)
-@@ -175,31 +205,13 @@ void log_to_syslog(void)
- openlog("automount", LOG_PID, LOG_DAEMON);
- }
-
-- if (do_debug)
-- log_debug = syslog_debug;
-- else
-- log_debug = null;
--
-- if (do_verbose || do_debug) {
-- log_info = syslog_info;
-- log_notice = syslog_notice;
-- log_warn = syslog_warn;
-- } else {
-- log_info = null;
-- log_notice = null;
-- log_warn = null;
-- }
--
-- log_error = syslog_err;
-- log_crit = syslog_crit;
--
- logging_to_syslog = 1;
-
- /* Redirect all our file descriptors to /dev/null */
- nullfd = open("/dev/null", O_RDWR);
- if (nullfd < 0) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- syslog_crit(LOGOPT_ANY, "cannot open /dev/null: %s", estr);
-+ fprintf(stderr, "cannot open /dev/null: %s", estr);
- exit(1);
- }
-
-@@ -207,13 +219,15 @@ void log_to_syslog(void)
- dup2(nullfd, STDOUT_FILENO) < 0 ||
- dup2(nullfd, STDERR_FILENO) < 0) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- syslog_crit(LOGOPT_ANY,
-- "redirecting file descriptors failed: %s", estr);
-+ fprintf(stderr,
-+ "redirecting file descriptors failed: %s", estr);
- exit(1);
- }
-
- if (nullfd > 2)
- close(nullfd);
-+
-+ return;
- }
-
- void log_to_stderr(void)
-@@ -223,23 +237,7 @@ void log_to_stderr(void)
- closelog();
- }
-
-- if (do_debug)
-- log_debug = to_stderr;
-- else
-- log_debug = null;
--
-- if (do_verbose || do_debug) {
-- log_info = to_stderr;
-- log_notice = to_stderr;
-- log_warn = to_stderr;
-- } else {
-- log_info = null;
-- log_notice = null;
-- log_warn = null;
-- }
--
-- log_error = to_stderr;
-- log_crit = to_stderr;
--
- logging_to_syslog = 0;
-+
-+ return;
- }
-diff --git a/lib/macros.c b/lib/macros.c
-index 936ae06..fa6db8e 100644
---- a/lib/macros.c
-+++ b/lib/macros.c
-@@ -50,8 +50,7 @@ void dump_table(struct substvar *table)
- fatal(status);
-
- while (lv) {
-- debug(LOGOPT_NONE,
-- "lv->def %s lv->val %s lv->next %p",
-+ logmsg("lv->def %s lv->val %s lv->next %p",
- lv->def, lv->val, lv->next);
- lv = lv->next;
- }
-diff --git a/lib/master.c b/lib/master.c
-index abc3bc2..2e24ad0 100644
---- a/lib/master.c
-+++ b/lib/master.c
-@@ -524,8 +524,7 @@ void master_source_writelock(struct master_mapent *entry)
-
- status = pthread_rwlock_wrlock(&entry->source_lock);
- if (status) {
-- error(LOGOPT_ANY,
-- "master_mapent source write lock failed");
-+ logmsg("master_mapent source write lock failed");
- fatal(status);
- }
- return;
-@@ -537,8 +536,7 @@ void master_source_readlock(struct master_mapent *entry)
-
- status = pthread_rwlock_rdlock(&entry->source_lock);
- if (status) {
-- error(LOGOPT_ANY,
-- "master_mapent source read lock failed");
-+ logmsg("master_mapent source read lock failed");
- fatal(status);
- }
- return;
-@@ -550,8 +548,7 @@ void master_source_unlock(struct master_mapent *entry)
-
- status = pthread_rwlock_unlock(&entry->source_lock);
- if (status) {
-- error(LOGOPT_ANY,
-- "master_mapent source unlock failed");
-+ logmsg("master_mapent source unlock failed");
- fatal(status);
- }
- return;
-@@ -572,7 +569,7 @@ void master_source_current_wait(struct master_mapent *entry)
-
- status = pthread_mutex_lock(&entry->current_mutex);
- if (status) {
-- error(LOGOPT_ANY, "entry current source lock failed");
-+ logmsg("entry current source lock failed");
- fatal(status);
- }
-
-@@ -580,8 +577,7 @@ void master_source_current_wait(struct master_mapent *entry)
- status = pthread_cond_wait(
- &entry->current_cond, &entry->current_mutex);
- if (status) {
-- error(LOGOPT_ANY,
-- "entry current source condition wait failed");
-+ logmsg("entry current source condition wait failed");
- fatal(status);
- }
- }
-@@ -595,14 +591,13 @@ void master_source_current_signal(struct master_mapent *entry)
-
- status = pthread_cond_signal(&entry->current_cond);
- if (status) {
-- error(LOGOPT_ANY,
-- "entry current source condition signal failed");
-+ logmsg("entry current source condition signal failed");
- fatal(status);
- }
-
- status = pthread_mutex_unlock(&entry->current_mutex);
- if (status) {
-- error(LOGOPT_ANY, "entry current source unlock failed");
-+ logmsg("entry current source unlock failed");
- fatal(status);
- }
-
-@@ -770,6 +765,7 @@ struct master *master_new(const char *name, unsigned int timeout, unsigned int g
- master->default_ghost = ghost;
- master->default_timeout = timeout;
- master->default_logging = defaults_get_logging();
-+ master->logopt = master->default_logging;
-
- INIT_LIST_HEAD(&master->mounts);
-
-@@ -778,11 +774,12 @@ struct master *master_new(const char *name, unsigned int timeout, unsigned int g
-
- int master_read_master(struct master *master, time_t age, int readall)
- {
-+ unsigned int logopt = master->logopt;
- struct mapent_cache *nc;
-
- nc = cache_init_null_cache(master);
- if (!nc) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- "failed to init null map cache for %s", master->name);
- return 0;
- }
-@@ -791,7 +788,7 @@ int master_read_master(struct master *master, time_t age, int readall)
- master_init_scan();
-
- if (!lookup_nss_read_master(master, age)) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- "can't read master map %s", master->name);
- return 0;
- }
-@@ -802,7 +799,7 @@ int master_read_master(struct master *master, time_t age, int readall)
-
- if (list_empty(&master->mounts)) {
- master_mutex_unlock();
-- warn(LOGOPT_ANY, "no mounts in table");
-+ warn(logopt, "no mounts in table");
- return 1;
- }
-
-@@ -934,6 +931,7 @@ void master_notify_state_change(struct master *master, int sig)
- struct autofs_point *ap;
- struct list_head *p;
- int state_pipe, cur_state;
-+ unsigned int logopt;
-
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- master_mutex_lock();
-@@ -944,6 +942,7 @@ void master_notify_state_change(struct master *master, int sig)
- entry = list_entry(p, struct master_mapent, list);
-
- ap = entry->ap;
-+ logopt = ap->logopt;
-
- state_mutex_lock(ap);
-
-@@ -978,7 +977,7 @@ void master_notify_state_change(struct master *master, int sig)
- }
- next:
- if (next != ST_INVAL)
-- debug(ap->logopt,
-+ debug(logopt,
- "sig %d switching %s from %d to %d",
- sig, ap->path, ap->state, next);
-
-@@ -1230,6 +1229,11 @@ int master_list_empty(struct master *master)
- return res;
- }
-
-+inline unsigned int master_get_logopt(void)
-+{
-+ return master_list ? master_list->logopt : LOGOPT_NONE;
-+}
-+
- int master_kill(struct master *master)
- {
- if (!list_empty(&master->mounts))
-@@ -1251,6 +1255,6 @@ void dump_master(struct master *master)
- head = &master->mounts;
- list_for_each(p, head) {
- struct master_mapent *this = list_entry(p, struct master_mapent, list);
-- debug(LOGOPT_ANY, "path %s", this->path);
-+ logmsg("path %s", this->path);
- }
- }
-diff --git a/lib/master_parse.y b/lib/master_parse.y
-index 70b48be..a767f9e 100644
---- a/lib/master_parse.y
-+++ b/lib/master_parse.y
-@@ -585,13 +585,13 @@ static char *master_strdup(char *str)
-
- static int master_error(const char *s)
- {
-- error(LOGOPT_ANY, "%s while parsing map.", s);
-+ logmsg("%s while parsing map.", s);
- return 0;
- }
-
- static int master_notify(const char *s)
- {
-- warn(LOGOPT_ANY, "syntax error in map near [ %s ]", s);
-+ logmsg("syntax error in map near [ %s ]", s);
- return(0);
- }
-
-@@ -704,6 +704,7 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne
- struct master_mapent *entry, *new;
- struct map_source *source;
- unsigned int logopt = logging;
-+ unsigned int m_logopt = master->logopt;
- int ret;
-
- local_init_vars();
-@@ -758,8 +759,8 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne
- } else {
- if (entry->age && entry->age == age) {
- if (strcmp(path, "/-")) {
-- warn(LOGOPT_VERBOSE,
-- "ignoring duplicate indirect mount %s",
-+ info(m_logopt,
-+ "ignoring duplicate indirect mount %s",
- path);
- local_free_vars();
- return 0;
-@@ -770,13 +771,12 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne
- if (!entry->ap) {
- ret = master_add_autofs_point(entry, timeout, logopt, ghost, 0);
- if (!ret) {
-- error(LOGOPT_ANY, "failed to add autofs_point");
-+ error(m_logopt, "failed to add autofs_point");
- if (new)
- master_free_mapent(new);
- local_free_vars();
- return 0;
- }
-- set_mnt_logging(entry->ap);
- } else {
- struct autofs_point *ap = entry->ap;
- time_t tout = timeout;
-@@ -786,14 +786,11 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne
- * use the ghost, log and timeout of the first
- */
- if (entry->age < age) {
-- ap->ghost = ghost;
-- ap->logopt = logopt;
- ap->exp_timeout = timeout;
- ap->exp_runfreq = (ap->exp_timeout + CHECK_RATIO - 1) / CHECK_RATIO;
- if (ap->ioctlfd != -1 && ap->type == LKP_INDIRECT)
- ioctl(ap->ioctlfd, AUTOFS_IOC_SETTIMEOUT, &tout);
- }
-- set_mnt_logging(ap);
- }
- entry->ap->random_selection = random_selection;
-
-@@ -809,7 +806,7 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne
- source = master_add_map_source(entry, type, format, age,
- local_argc, (const char **) local_argv);
- if (!source) {
-- error(LOGOPT_ANY, "failed to add source");
-+ error(m_logopt, "failed to add source");
- if (new)
- master_free_mapent(new);
- local_free_vars();
-@@ -817,9 +814,9 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne
- }
-
- if (!source->mc) {
-- source->mc = cache_init(source);
-+ source->mc = cache_init(entry->ap, source);
- if (!source->mc) {
-- error(LOGOPT_ANY, "failed to init source cache");
-+ error(m_logopt, "failed to init source cache");
- if (new)
- master_free_mapent(new);
- local_free_vars();
-diff --git a/lib/master_tok.l b/lib/master_tok.l
-index 2735223..00cd223 100644
---- a/lib/master_tok.l
-+++ b/lib/master_tok.l
-@@ -368,7 +368,7 @@ int master_wrap(void)
-
- static void master_echo(void)
- {
-- debug(LOGOPT_NONE, "%s", master_text);
-+ logmsg("%s", master_text);
- return;
- }
-
-diff --git a/lib/mounts.c b/lib/mounts.c
-index 0e428e8..425a65a 100644
---- a/lib/mounts.c
-+++ b/lib/mounts.c
-@@ -126,7 +126,7 @@ char *make_options_string(char *path, int pipefd, char *extra)
-
- options = malloc(MAX_OPTIONS_LEN + 1);
- if (!options) {
-- crit(LOGOPT_ANY, "can't malloc options string");
-+ logerr("can't malloc options string");
- return NULL;
- }
-
-@@ -141,13 +141,12 @@ char *make_options_string(char *path, int pipefd, char *extra)
- AUTOFS_MAX_PROTO_VERSION);
-
- if (len >= MAX_OPTIONS_LEN) {
-- crit(LOGOPT_ANY, "buffer to small for options - truncated");
-+ logerr("buffer to small for options - truncated");
- len = MAX_OPTIONS_LEN - 1;
- }
-
- if (len < 0) {
-- crit(LOGOPT_ANY,
-- "failed to malloc autofs mount options for %s", path);
-+ logerr("failed to malloc autofs mount options for %s", path);
- free(options);
- return NULL;
- }
-@@ -163,7 +162,7 @@ char *make_mnt_name_string(char *path)
-
- mnt_name = malloc(MAX_MNT_NAME_LEN + 1);
- if (!mnt_name) {
-- crit(LOGOPT_ANY, "can't malloc mnt_name string");
-+ logerr("can't malloc mnt_name string");
- return NULL;
- }
-
-@@ -171,13 +170,12 @@ char *make_mnt_name_string(char *path)
- mnt_name_template, (unsigned) getpid());
-
- if (len >= MAX_MNT_NAME_LEN) {
-- crit(LOGOPT_ANY, "buffer to small for mnt_name - truncated");
-+ logerr("buffer to small for mnt_name - truncated");
- len = MAX_MNT_NAME_LEN - 1;
- }
-
- if (len < 0) {
-- crit(LOGOPT_ANY,
-- "failed setting up mnt_name for autofs path %s", path);
-+ logerr("failed setting up mnt_name for autofs path %s", path);
- free(mnt_name);
- return NULL;
- }
-@@ -207,7 +205,7 @@ struct mnt_list *get_mnt_list(const char *table, const char *path, int include)
- tab = setmntent(table, "r");
- if (!tab) {
- char *estr = strerror_r(errno, buf, PATH_MAX - 1);
-- error(LOGOPT_ANY, "setmntent: %s", estr);
-+ logerr("setmntent: %s", estr);
- return NULL;
- }
-
-@@ -398,7 +396,7 @@ int is_mounted(const char *table, const char *path, unsigned int type)
- tab = setmntent(table, "r");
- if (!tab) {
- char *estr = strerror_r(errno, buf, PATH_MAX - 1);
-- error(LOGOPT_ANY, "setmntent: %s", estr);
-+ logerr("setmntent: %s", estr);
- return 0;
- }
-
-@@ -443,7 +441,7 @@ int has_fstab_option(const char *opt)
- tab = setmntent(_PATH_MNTTAB, "r");
- if (!tab) {
- char *estr = strerror_r(errno, buf, PATH_MAX - 1);
-- error(LOGOPT_ANY, "setmntent: %s", estr);
-+ logerr("setmntent: %s", estr);
- return 0;
- }
-
-@@ -471,7 +469,7 @@ char *find_mnt_ino(const char *table, dev_t dev, ino_t ino)
- tab = setmntent(table, "r");
- if (!tab) {
- char *estr = strerror_r(errno, buf, (size_t) PATH_MAX - 1);
-- error(LOGOPT_ANY, "setmntent: %s", estr);
-+ logerr("setmntent: %s", estr);
- return 0;
- }
-
-@@ -667,7 +665,7 @@ struct mnt_list *tree_make_mnt_tree(const char *table, const char *path)
- tab = setmntent(table, "r");
- if (!tab) {
- char *estr = strerror_r(errno, buf, PATH_MAX - 1);
-- error(LOGOPT_ANY, "setmntent: %s", estr);
-+ logerr("setmntent: %s", estr);
- return NULL;
- }
-
-diff --git a/lib/nss_parse.y b/lib/nss_parse.y
-index e559696..90b7d25 100644
---- a/lib/nss_parse.y
-+++ b/lib/nss_parse.y
-@@ -127,13 +127,13 @@ status_exp: STATUS EQUAL ACTION
-
- static int nss_ignore(const char *s)
- {
-- msg("ignored invalid nsswitch config near [ %s ]", s);
-+ logmsg("ignored invalid nsswitch config near [ %s ]", s);
- return(0);
- }
-
- static int nss_error(const char *s)
- {
-- msg("syntax error in nsswitch config near [ %s ]\n", s);
-+ logmsg("syntax error in nsswitch config near [ %s ]\n", s);
- return(0);
- }
-
-@@ -167,7 +167,7 @@ int nsswitch_parse(struct list_head *list)
-
- nsswitch = fopen(NSSWITCH_FILE, "r");
- if (!nsswitch) {
-- error(LOGOPT_ANY, "couldn't open %s\n", NSSWITCH_FILE);
-+ logerr("couldn't open %s\n", NSSWITCH_FILE);
- return 1;
- }
-
-diff --git a/lib/nss_tok.l b/lib/nss_tok.l
-index f96b47f..c435b63 100644
---- a/lib/nss_tok.l
-+++ b/lib/nss_tok.l
-@@ -135,6 +135,6 @@ int nss_wrap(void)
-
- static void nss_echo(void)
- {
-- msg("%s", nss_text);
-+ logmsg("%s", nss_text);
- return;
- }
-diff --git a/lib/parse_subs.c b/lib/parse_subs.c
-index 3627f44..5422fef 100644
---- a/lib/parse_subs.c
-+++ b/lib/parse_subs.c
-@@ -337,9 +337,9 @@ int umount_ent(struct autofs_point *ap, const char *path)
- * and EBADSLT relates to CD changer not responding.
- */
- if (!status && (S_ISDIR(st.st_mode) && st.st_dev != ap->dev)) {
-- rv = spawn_umount(log_debug, path, NULL);
-+ rv = spawn_umount(ap->logopt, path, NULL);
- } else if (is_smbfs && (sav_errno == EIO || sav_errno == EBADSLT)) {
-- rv = spawn_umount(log_debug, path, NULL);
-+ rv = spawn_umount(ap->logopt, path, NULL);
- }
-
- /* We are doing a forced shutcwdown down so unlink busy mounts */
-@@ -356,8 +356,8 @@ int umount_ent(struct autofs_point *ap, const char *path)
- }
-
- if (ap->state == ST_SHUTDOWN_FORCE) {
-- msg("forcing umount of %s", path);
-- rv = spawn_umount(log_debug, "-l", path, NULL);
-+ info(ap->logopt, "forcing umount of %s", path);
-+ rv = spawn_umount(ap->logopt, "-l", path, NULL);
- }
-
- /*
-@@ -503,7 +503,7 @@ int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me
- * the offset triggers back.
- */
- if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) {
-- msg("unmounting dir = %s", root);
-+ info(ap->logopt, "unmounting dir = %s", root);
- if (umount_ent(ap, root)) {
- if (!mount_multi_triggers(ap, root, me, "/"))
- warn(ap->logopt,
-diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
-index d79a94f..5797639 100644
---- a/lib/rpc_subs.c
-+++ b/lib/rpc_subs.c
-@@ -96,7 +96,7 @@ static CLIENT *create_udp_client(struct conn_info *info)
- if (ret || !result) {
- int err = ghn_errno == -1 ? errno : ghn_errno;
- char *estr = strerror_r(err, buf, HOST_ENT_BUF_SIZE);
-- error(LOGOPT_ANY, "hostname lookup failed: %s", estr);
-+ logerr("hostname lookup failed: %s", estr);
- goto out_close;
- }
- memcpy(&raddr.sin_addr.s_addr, php->h_addr, php->h_length);
-@@ -305,7 +305,7 @@ static CLIENT *create_tcp_client(struct conn_info *info)
- if (ret || !result) {
- int err = ghn_errno == -1 ? errno : ghn_errno;
- char *estr = strerror_r(err, buf, HOST_ENT_BUF_SIZE);
-- error(LOGOPT_ANY, "hostname lookup failed: %s", estr);
-+ logerr("hostname lookup failed: %s", estr);
- goto out_close;
- }
- memcpy(&addr.sin_addr.s_addr, php->h_addr, php->h_length);
-diff --git a/man/automount.8 b/man/automount.8
-index e203a3e..5cd63c7 100644
---- a/man/automount.8
-+++ b/man/automount.8
-@@ -62,6 +62,22 @@ setting.
- .TP
- .I "\-V, \-\-version"
- Display the version number, then exit.
-+.TP
-+.I "\-l, \-\-set-log-priority priority path [path,...]"
-+Set the daemon log priority to the specified value. Valid values include
-+the numbers 0-7, or the strings emerg, alert, crit, err, warning, notice,
-+info, or debug. Log level debug will log everything, log levels info, warn
-+(or warning), or notice with enable the daemon verbose logging. Any other
-+level will set basic logging. Note that enabling debug or verbose
-+logging in the autofs global configuration will override dynamic log level
-+changes. For example, if verbose logging is set in the configuration then
-+attempting to set logging to basic logging, by using alert, crit, err
-+or emerg won't stop the verbose logging. However, setting logging to debug
-+will lead to everything (debug logging) being logged witch can then also
-+be disabled, returning the daemon to verbose logging.
-+.P
-+The \fIpath\fP argument corresponds to the automounted
-+path name as specified in the master map.
- .SH ARGUMENTS
- \fBautomount\fP takes one optional argument, the name of the master map to
- use.
-diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
-index 68e5dd7..18733f3 100644
---- a/modules/cyrus-sasl.c
-+++ b/modules/cyrus-sasl.c
-@@ -96,18 +96,18 @@ sasl_log_func(void *context, int level, const char *message)
- switch (level) {
- case SASL_LOG_ERR:
- case SASL_LOG_FAIL:
-- error(LOGOPT_ANY, "%s", message);
-+ logerr("%s", message);
- break;
- case SASL_LOG_WARN:
-- warn(LOGOPT_ANY, "%s", message);
-+ logmsg("%s", message);
- break;
- case SASL_LOG_NOTE:
-- info(LOGOPT_ANY, "%s", message);
-+ logmsg("%s", message);
- break;
- case SASL_LOG_DEBUG:
- case SASL_LOG_TRACE:
- case SASL_LOG_PASS:
-- debug(LOGOPT_NONE, "%s", message);
-+ debug(LOGOPT_DEBUG, "%s", message);
- break;
- default:
- break;
-@@ -129,7 +129,7 @@ getuser_func(void *context, int id, const char **result, unsigned *len)
- *len = strlen(sasl_auth_id);
- break;
- default:
-- error(LOGOPT_ANY, "unknown id in request: %d", id);
-+ error(LOGOPT_VERBOSE, "unknown id in request: %d", id);
- return SASL_FAIL;
- }
-
-@@ -166,7 +166,7 @@ getpass_func(sasl_conn_t *conn, void *context, int id, sasl_secret_t **psecret)
- * the returned data.
- */
- char **
--get_server_SASL_mechanisms(LDAP *ld)
-+get_server_SASL_mechanisms(unsigned logopt, LDAP *ld)
- {
- int ret;
- const char *saslattrlist[] = {"supportedSASLmechanisms", NULL};
-@@ -178,7 +178,7 @@ get_server_SASL_mechanisms(LDAP *ld)
- NULL, NULL,
- NULL, LDAP_NO_LIMIT, &results);
- if (ret != LDAP_SUCCESS) {
-- error(LOGOPT_ANY, "%s", ldap_err2string(ret));
-+ error(logopt, "%s", ldap_err2string(ret));
- return NULL;
- }
-
-@@ -186,7 +186,7 @@ get_server_SASL_mechanisms(LDAP *ld)
- if (entry == NULL) {
- /* No root DSE. (!) */
- ldap_msgfree(results);
-- debug(LOGOPT_NONE,
-+ debug(logopt,
- "a lookup of \"supportedSASLmechanisms\" returned "
- "no results.");
- return NULL;
-@@ -196,7 +196,7 @@ get_server_SASL_mechanisms(LDAP *ld)
- ldap_msgfree(results);
- if (mechanisms == NULL) {
- /* Well, that was a waste of time. */
-- msg("No SASL authentication mechanisms are supported"
-+ info(logopt, "No SASL authentication mechanisms are supported"
- " by the LDAP server.");
- return NULL;
- }
-@@ -208,7 +208,7 @@ get_server_SASL_mechanisms(LDAP *ld)
- * Returns 0 upon successful connect, -1 on failure.
- */
- int
--do_sasl_bind(LDAP *ld, sasl_conn_t *conn, const char **clientout,
-+do_sasl_bind(unsigned logopt, LDAP *ld, sasl_conn_t *conn, const char **clientout,
- unsigned int *clientoutlen, const char *auth_mech, int sasl_result)
- {
- int ret, msgid, bind_result;
-@@ -226,7 +226,7 @@ do_sasl_bind(LDAP *ld, sasl_conn_t *conn, const char **clientout,
- &client_cred : NULL,
- NULL, NULL, &msgid);
- if (ret != LDAP_SUCCESS) {
-- crit(LOGOPT_ANY,
-+ crit(logopt,
- "Error sending sasl_bind request to "
- "the server: %s", ldap_err2string(ret));
- return -1;
-@@ -236,7 +236,7 @@ do_sasl_bind(LDAP *ld, sasl_conn_t *conn, const char **clientout,
- results = NULL;
- ret = ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, &results);
- if (ret != LDAP_RES_BIND) {
-- crit(LOGOPT_ANY,
-+ crit(logopt,
- "Error while waiting for response to "
- "sasl_bind request: %s", ldap_err2string(ret));
- return -1;
-@@ -264,7 +264,7 @@ do_sasl_bind(LDAP *ld, sasl_conn_t *conn, const char **clientout,
- ret = ldap_get_option(ld, LDAP_OPT_RESULT_CODE,
- &bind_result);
- if (ret != LDAP_SUCCESS) {
-- crit(LOGOPT_ANY,
-+ crit(logopt,
- "Error retrieving response to sasl_bind "
- "request: %s", ldap_err2string(ret));
- ret = -1;
-@@ -277,7 +277,7 @@ do_sasl_bind(LDAP *ld, sasl_conn_t *conn, const char **clientout,
- bind_result = ret;
- break;
- default:
-- warn(LOGOPT_ANY,
-+ warn(logopt,
- "Error parsing response to sasl_bind "
- "request: %s.", ldap_err2string(ret));
- break;
-@@ -299,7 +299,7 @@ do_sasl_bind(LDAP *ld, sasl_conn_t *conn, const char **clientout,
- expected_data = sasl_result == SASL_CONTINUE;
-
- if (have_data && !expected_data) {
-- warn(LOGOPT_ANY,
-+ warn(logopt,
- "The LDAP server sent data in response to our "
- "bind request, but indicated that the bind was "
- "complete. LDAP SASL bind with mechansim %s "
-@@ -308,7 +308,7 @@ do_sasl_bind(LDAP *ld, sasl_conn_t *conn, const char **clientout,
- break;
- }
- if (expected_data && !have_data) {
-- warn(LOGOPT_ANY,
-+ warn(logopt,
- "The LDAP server indicated that the LDAP SASL "
- "bind was incomplete, but did not provide the "
- "required data to proceed. LDAP SASL bind with "
-@@ -340,7 +340,7 @@ do_sasl_bind(LDAP *ld, sasl_conn_t *conn, const char **clientout,
- */
- if ((*clientoutlen > 0) &&
- (bind_result != LDAP_SASL_BIND_IN_PROGRESS)) {
-- warn(LOGOPT_ANY,
-+ warn(logopt,
- "We have data for the server, "
- "but it thinks we are done!");
- /* XXX should print out debug data here */
-@@ -372,7 +372,7 @@ do_sasl_bind(LDAP *ld, sasl_conn_t *conn, const char **clientout,
- * Upon failure, -1 is returned.
- */
- int
--sasl_do_kinit(struct lookup_context *ctxt)
-+sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
- {
- krb5_error_code ret;
- krb5_principal tgs_princ, krb5_client_princ = ctxt->krb5_client_princ;
-@@ -384,33 +384,33 @@ sasl_do_kinit(struct lookup_context *ctxt)
- return 0;
- ctxt->kinit_done = 1;
-
-- debug(LOGOPT_NONE,
-+ debug(logopt,
- "initializing kerberos ticket: client principal %s ",
- ctxt->client_princ ? "" : "autofsclient");
-
- ret = krb5_init_context(&ctxt->krb5ctxt);
- if (ret) {
-- error(LOGOPT_ANY, "krb5_init_context failed with %d", ret);
-+ error(logopt, "krb5_init_context failed with %d", ret);
- return -1;
- }
-
- ret = krb5_cc_resolve(ctxt->krb5ctxt, krb5ccval, &ctxt->krb5_ccache);
- if (ret) {
-- error(LOGOPT_ANY, "krb5_cc_resolve failed with error %d",
-+ error(logopt, "krb5_cc_resolve failed with error %d",
- ret);
- krb5_free_context(ctxt->krb5ctxt);
- return -1;
- }
-
- if (ctxt->client_princ) {
-- debug(LOGOPT_NONE,
-+ debug(logopt,
- "calling krb5_parse_name on client principal %s",
- ctxt->client_princ);
-
- ret = krb5_parse_name(ctxt->krb5ctxt, ctxt->client_princ,
- &krb5_client_princ);
- if (ret) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- "krb5_parse_name failed for "
- "specified client principal %s",
- ctxt->client_princ);
-@@ -419,14 +419,14 @@ sasl_do_kinit(struct lookup_context *ctxt)
- } else {
- char *tmp_name = NULL;
-
-- debug(LOGOPT_NONE,
-+ debug(logopt,
- "calling krb5_sname_to_principal using defaults");
-
- ret = krb5_sname_to_principal(ctxt->krb5ctxt, NULL,
- "autofsclient", KRB5_NT_SRV_HST,
- &krb5_client_princ);
- if (ret) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- "krb5_sname_to_principal failed for "
- "%s with error %d",
- ctxt->client_princ ? "" : "autofsclient", ret);
-@@ -437,13 +437,13 @@ sasl_do_kinit(struct lookup_context *ctxt)
- ret = krb5_unparse_name(ctxt->krb5ctxt,
- krb5_client_princ, &tmp_name);
- if (ret) {
-- debug(LOGOPT_NONE,
-+ debug(logopt,
- "krb5_unparse_name failed with error %d",
- ret);
- goto out_cleanup_cc;
- }
-
-- debug(LOGOPT_NONE,
-+ debug(logopt,
- "principal used for authentication: \"%s\"", tmp_name);
-
- krb5_free_unparsed_name(ctxt->krb5ctxt, tmp_name);
-@@ -458,19 +458,19 @@ sasl_do_kinit(struct lookup_context *ctxt)
- krb5_princ_realm(ctxt->krb5ctxt, krb5_client_princ)->data,
- 0);
- if (ret) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- "krb5_build_principal failed with error %d", ret);
- goto out_cleanup_cc;
- }
-
- ret = krb5_unparse_name(ctxt->krb5ctxt, tgs_princ, &tgs_name);
- if (ret) {
-- error(LOGOPT_ANY, "krb5_unparse_name failed with error %d",
-+ error(logopt, "krb5_unparse_name failed with error %d",
- ret);
- goto out_cleanup_cc;
- }
-
-- debug(LOGOPT_NONE, "Using tgs name %s", tgs_name);
-+ debug(logopt, "Using tgs name %s", tgs_name);
-
- memset(&my_creds, 0, sizeof(my_creds));
- ret = krb5_get_init_creds_keytab(ctxt->krb5ctxt, &my_creds,
-@@ -479,7 +479,7 @@ sasl_do_kinit(struct lookup_context *ctxt)
- 0 /* relative start time */,
- tgs_name, NULL);
- if (ret) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- "krb5_get_init_creds_keytab failed with error %d",
- ret);
- goto out_cleanup_unparse;
-@@ -500,7 +500,7 @@ sasl_do_kinit(struct lookup_context *ctxt)
- fatal(status);
-
- if (ret) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- "krb5_cc_initialize failed with error %d", ret);
- goto out_cleanup_unparse;
- }
-@@ -508,7 +508,7 @@ sasl_do_kinit(struct lookup_context *ctxt)
- /* and store credentials for that principal */
- ret = krb5_cc_store_cred(ctxt->krb5ctxt, ctxt->krb5_ccache, &my_creds);
- if (ret) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- "krb5_cc_store_cred failed with error %d", ret);
- goto out_cleanup_unparse;
- }
-@@ -516,12 +516,12 @@ sasl_do_kinit(struct lookup_context *ctxt)
- /* finally, set the environment variable to point to our
- * credentials cache */
- if (setenv(krb5ccenv, krb5ccval, 1) != 0) {
-- error(LOGOPT_ANY, "setenv failed with %d", errno);
-+ error(logopt, "setenv failed with %d", errno);
- goto out_cleanup_unparse;
- }
- ctxt->kinit_successful = 1;
-
-- debug(LOGOPT_NONE, "Kerberos authentication was successful!");
-+ debug(logopt, "Kerberos authentication was successful!");
-
- krb5_free_unparsed_name(ctxt->krb5ctxt, tgs_name);
-
-@@ -540,7 +540,7 @@ out_cleanup_cc:
- else
- ret = krb5_cc_destroy(ctxt->krb5ctxt, ctxt->krb5_ccache);
- if (ret)
-- warn(LOGOPT_ANY,
-+ warn(logopt,
- "krb5_cc_destroy failed with non-fatal error %d", ret);
-
- status = pthread_mutex_unlock(&krb5cc_mutex);
-@@ -559,7 +559,7 @@ out_cleanup_cc:
- * Returns a valid sasl_conn_t pointer upon success, NULL on failure.
- */
- sasl_conn_t *
--sasl_bind_mech(LDAP *ldap, struct lookup_context *ctxt, const char *mech)
-+sasl_bind_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const char *mech)
- {
- sasl_conn_t *conn;
- char *tmp, *host = NULL;
-@@ -569,15 +569,15 @@ sasl_bind_mech(LDAP *ldap, struct lookup_context *ctxt, const char *mech)
- int result;
-
- if (!strncmp(mech, "GSSAPI", 6)) {
-- if (sasl_do_kinit(ctxt) != 0)
-+ if (sasl_do_kinit(logopt, ctxt) != 0)
- return NULL;
- }
-
-- debug(LOGOPT_NONE, "Attempting sasl bind with mechanism %s", mech);
-+ debug(logopt, "Attempting sasl bind with mechanism %s", mech);
-
- result = ldap_get_option(ldap, LDAP_OPT_HOST_NAME, &host);
- if (result != LDAP_SUCCESS || !host) {
-- debug(LOGOPT_NONE, "failed to get hostname for connection");
-+ debug(logopt, "failed to get hostname for connection");
- return NULL;
- }
-
-@@ -587,7 +587,7 @@ sasl_bind_mech(LDAP *ldap, struct lookup_context *ctxt, const char *mech)
- /* Create a new authentication context for the service. */
- result = sasl_client_new("ldap", host, NULL, NULL, NULL, 0, &conn);
- if (result != SASL_OK) {
-- error(LOGOPT_ANY, "sasl_client_new failed with error %d",
-+ error(logopt, "sasl_client_new failed with error %d",
- result);
- ldap_memfree(host);
- return NULL;
-@@ -599,23 +599,23 @@ sasl_bind_mech(LDAP *ldap, struct lookup_context *ctxt, const char *mech)
-
- /* OK and CONTINUE are the only non-fatal return codes here. */
- if ((result != SASL_OK) && (result != SASL_CONTINUE)) {
-- error(LOGOPT_ANY, "sasl_client start failed with error: %s",
-+ error(logopt, "sasl_client start failed with error: %s",
- sasl_errdetail(conn));
- ldap_memfree(host);
- sasl_dispose(&conn);
- return NULL;
- }
-
-- result = do_sasl_bind(ldap, conn,
-+ result = do_sasl_bind(logopt, ldap, conn,
- &clientout, &clientoutlen, chosen_mech, result);
- if (result == 0) {
- ldap_memfree(host);
-- debug(LOGOPT_NONE, "sasl bind with mechanism %s succeeded",
-+ debug(logopt, "sasl bind with mechanism %s succeeded",
- chosen_mech);
- return conn;
- }
-
-- info(LOGOPT_ANY, "sasl bind with mechanism %s failed", mech);
-+ info(logopt, "sasl bind with mechanism %s failed", mech);
-
- /* sasl bind failed */
- ldap_memfree(host);
-@@ -629,14 +629,14 @@ sasl_bind_mech(LDAP *ldap, struct lookup_context *ctxt, const char *mech)
- * -1 on error or if no mechanism is supported by both client and server.
- */
- sasl_conn_t *
--sasl_choose_mech(LDAP *ldap, struct lookup_context *ctxt)
-+sasl_choose_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
- {
- sasl_conn_t *conn;
- int authenticated;
- int i;
- char **mechanisms;
-
-- mechanisms = get_server_SASL_mechanisms(ldap);
-+ mechanisms = get_server_SASL_mechanisms(logopt, ldap);
- if (!mechanisms)
- return NULL;
-
-@@ -652,12 +652,11 @@ sasl_choose_mech(LDAP *ldap, struct lookup_context *ctxt)
- if (authtype_requires_creds(mechanisms[i]))
- continue;
-
-- conn = sasl_bind_mech(ldap, ctxt, mechanisms[i]);
-+ conn = sasl_bind_mech(logopt, ldap, ctxt, mechanisms[i]);
- if (conn) {
- ctxt->sasl_mech = strdup(mechanisms[i]);
- if (!ctxt->sasl_mech) {
-- crit(LOGOPT_ANY,
-- "Successfully authenticated with "
-+ crit(logopt, "Successfully authenticated with "
- "mechanism %s, but failed to allocate "
- "memory to hold the mechanism type.",
- mechanisms[i]);
-@@ -668,11 +667,11 @@ sasl_choose_mech(LDAP *ldap, struct lookup_context *ctxt)
- authenticated = 1;
- break;
- }
-- debug(LOGOPT_NONE, "Failed to authenticate with mech %s",
-+ debug(logopt, "Failed to authenticate with mech %s",
- mechanisms[i]);
- }
-
-- debug(LOGOPT_NONE, "authenticated: %d, sasl_mech: %s",
-+ debug(logopt, "authenticated: %d, sasl_mech: %s",
- authenticated, ctxt->sasl_mech);
-
- ldap_value_free(mechanisms);
-@@ -680,14 +679,14 @@ sasl_choose_mech(LDAP *ldap, struct lookup_context *ctxt)
- }
-
- int
--autofs_sasl_bind(LDAP *ldap, struct lookup_context *ctxt)
-+autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
- {
- sasl_conn_t *conn;
-
- if (!ctxt->sasl_mech)
- return -1;
-
-- conn = sasl_bind_mech(ldap, ctxt, ctxt->sasl_mech);
-+ conn = sasl_bind_mech(logopt, ldap, ctxt, ctxt->sasl_mech);
- if (!conn)
- return -1;
-
-@@ -717,13 +716,13 @@ autofs_sasl_unbind(struct lookup_context *ctxt)
- * -1 - Failure
- */
- int
--autofs_sasl_init(LDAP *ldap, struct lookup_context *ctxt)
-+autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
- {
- sasl_conn_t *conn;
-
- /* Start up Cyrus SASL--only needs to be done once. */
- if (sasl_client_init(callbacks) != SASL_OK) {
-- error(LOGOPT_ANY, "sasl_client_init failed");
-+ error(logopt, "sasl_client_init failed");
- return -1;
- }
-
-@@ -736,9 +735,9 @@ autofs_sasl_init(LDAP *ldap, struct lookup_context *ctxt)
- * select one.
- */
- if (ctxt->sasl_mech)
-- conn = sasl_bind_mech(ldap, ctxt, ctxt->sasl_mech);
-+ conn = sasl_bind_mech(logopt, ldap, ctxt, ctxt->sasl_mech);
- else
-- conn = sasl_choose_mech(ldap, ctxt);
-+ conn = sasl_choose_mech(logopt, ldap, ctxt);
-
- if (conn) {
- sasl_dispose(&conn);
-@@ -772,8 +771,7 @@ autofs_sasl_done(struct lookup_context *ctxt)
- else
- ret = krb5_cc_destroy(ctxt->krb5ctxt, ctxt->krb5_ccache);
- if (ret)
-- warn(LOGOPT_ANY,
-- "krb5_cc_destroy failed with non-fatal error %d",
-+ logmsg("krb5_cc_destroy failed with non-fatal error %d",
- ret);
-
- status = pthread_mutex_unlock(&krb5cc_mutex);
-@@ -782,8 +780,7 @@ autofs_sasl_done(struct lookup_context *ctxt)
-
- krb5_free_context(ctxt->krb5ctxt);
- if (unsetenv(krb5ccenv) != 0)
-- warn(LOGOPT_ANY,
-- "unsetenv failed with error %d", errno);
-+ logerr("unsetenv failed with error %d", errno);
-
- ctxt->krb5ctxt = NULL;
- ctxt->krb5_ccache = NULL;
-diff --git a/modules/lookup_file.c b/modules/lookup_file.c
-index 31ee0fb..921b32b 100644
---- a/modules/lookup_file.c
-+++ b/modules/lookup_file.c
-@@ -63,13 +63,13 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- return 1;
- }
-
- if (argc < 1) {
- free(ctxt);
-- crit(LOGOPT_ANY, MODPREFIX "No map name");
-+ logerr(MODPREFIX "No map name");
- return 1;
- }
-
-@@ -77,21 +77,21 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
-
- if (ctxt->mapname[0] != '/') {
- free(ctxt);
-- msg(MODPREFIX "file map %s is not an absolute pathname",
-- argv[0]);
-+ logmsg(MODPREFIX
-+ "file map %s is not an absolute pathname", argv[0]);
- return 1;
- }
-
- if (access(ctxt->mapname, R_OK)) {
- free(ctxt);
-- msg(MODPREFIX "file map %s missing or not readable",
-- argv[0]);
-+ warn(LOGOPT_NONE, MODPREFIX
-+ "file map %s missing or not readable", argv[0]);
- return 1;
- }
-
- if (stat(ctxt->mapname, &st)) {
- free(ctxt);
-- crit(LOGOPT_ANY, MODPREFIX "file map %s, could not stat",
-+ logmsg(MODPREFIX "file map %s, could not stat",
- argv[0]);
- return 1;
- }
-@@ -104,7 +104,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
- if (!ctxt->parse) {
- free(ctxt);
-- crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
-+ logmsg(MODPREFIX "failed to open parse context");
- return 1;
- }
- *context = ctxt;
-@@ -112,7 +112,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- return 0;
- }
-
--static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsigned int *m_len)
-+static int read_one(unsigned logopt, FILE *f, char *key, unsigned int *k_len, char *mapent, unsigned int *m_len)
- {
- char *kptr, *p;
- int mapent_len, key_len;
-@@ -193,7 +193,7 @@ static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsig
- if (gotten == got_plus)
- goto got_it;
- else if (escape == esc_all) {
-- warn(LOGOPT_ANY, MODPREFIX
-+ warn(logopt, MODPREFIX
- "unmatched \" in map key %s", key);
- goto next;
- } else if (escape != esc_val)
-@@ -208,7 +208,7 @@ static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsig
- if (key_len == KEY_MAX_LEN) {
- state = st_badent;
- gotten = got_nothing;
-- warn(LOGOPT_ANY,
-+ warn(logopt,
- MODPREFIX "map key \"%s...\" "
- "is too long. The maximum key "
- "length is %d", key,
-@@ -245,7 +245,7 @@ static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsig
- state = st_begin;
- if (gotten == got_real || gotten == getting)
- goto got_it;
-- warn(LOGOPT_ANY, MODPREFIX
-+ warn(logopt, MODPREFIX
- "bad map entry \"%s...\" for key "
- "\"%s\"", mapent, key);
- goto next;
-@@ -286,7 +286,7 @@ static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsig
- if (ch == '\n') {
- if (escape == esc_all) {
- state = st_begin;
-- warn(LOGOPT_ANY, MODPREFIX
-+ warn(logopt, MODPREFIX
- "unmatched \" in %s for key %s",
- mapent, key);
- goto next;
-@@ -310,7 +310,7 @@ static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsig
- goto got_it;
- ungetc(nch, f);
- } else {
-- warn(LOGOPT_ANY,
-+ warn(logopt,
- MODPREFIX "map entry \"%s...\" for key "
- "\"%s\" is too long. The maximum entry"
- " size is %d", mapent, key,
-@@ -388,6 +388,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- struct lookup_context *ctxt = (struct lookup_context *) context;
- unsigned int timeout = master->default_timeout;
- unsigned int logging = master->default_logging;
-+ unsigned int logopt = master->logopt;
- char *buffer;
- int blen;
- char *path;
-@@ -402,29 +403,28 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- return NSS_STATUS_UNAVAIL;
-
- if (master->depth > MAX_INCLUDE_DEPTH) {
-- error(LOGOPT_ANY,
-- MODPREFIX
-+ error(logopt, MODPREFIX
- "maximum include depth exceeded %s", master->name);
- return NSS_STATUS_UNAVAIL;
- }
-
- path = alloca(KEY_MAX_LEN + 1);
- if (!path) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX "could not malloc storage for path");
- return NSS_STATUS_UNAVAIL;
- }
-
- ent = alloca(MAPENT_MAX_LEN + 1);
- if (!ent) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX "could not malloc storage for mapent");
- return NSS_STATUS_UNAVAIL;
- }
-
- f = fopen(ctxt->mapname, "r");
- if (!f) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX "could not open master map file %s",
- ctxt->mapname);
- return NSS_STATUS_UNAVAIL;
-@@ -438,19 +438,19 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- }
-
- while(1) {
-- entry = read_one(f, path, &path_len, ent, &ent_len);
-+ entry = read_one(logopt, f, path, &path_len, ent, &ent_len);
- if (!entry) {
- if (feof(f))
- break;
- if (ferror(f)) {
-- warn(LOGOPT_ANY, MODPREFIX
-+ warn(logopt, MODPREFIX
- "error reading map %s", ctxt->mapname);
- break;
- }
- continue;
- }
-
-- debug(LOGOPT_NONE, MODPREFIX "read entry %s", path);
-+ debug(logopt, MODPREFIX "read entry %s", path);
-
- /*
- * If key starts with '+' it has to be an
-@@ -470,7 +470,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- master->depth++;
- status = lookup_nss_read_master(master, age);
- if (!status)
-- warn(LOGOPT_ANY,
-+ warn(logopt,
- MODPREFIX
- "failed to read included master map %s",
- master->name);
-@@ -482,7 +482,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- blen = path_len + 1 + ent_len + 1;
- buffer = malloc(blen);
- if (!buffer) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX "could not malloc parse buffer");
- return NSS_STATUS_UNAVAIL;
- }
-@@ -503,7 +503,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- }
-
- if (fstat(fd, &st)) {
-- crit(LOGOPT_ANY, MODPREFIX "file map %s, could not stat",
-+ crit(logopt, MODPREFIX "file map %s, could not stat",
- ctxt->mapname);
- return NSS_STATUS_UNAVAIL;
- }
-@@ -684,12 +684,12 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
- }
-
- while(1) {
-- entry = read_one(f, key, &k_len, mapent, &m_len);
-+ entry = read_one(ap->logopt, f, key, &k_len, mapent, &m_len);
- if (!entry) {
- if (feof(f))
- break;
- if (ferror(f)) {
-- warn(LOGOPT_ANY, MODPREFIX
-+ warn(ap->logopt, MODPREFIX
- "error reading map %s", ctxt->mapname);
- break;
- }
-@@ -791,7 +791,7 @@ static int lookup_one(struct autofs_point *ap,
- }
-
- while(1) {
-- entry = read_one(f, mkey, &k_len, mapent, &m_len);
-+ entry = read_one(ap->logopt, f, mkey, &k_len, mapent, &m_len);
- if (entry) {
- /*
- * If key starts with '+' it has to be an
-@@ -860,7 +860,7 @@ static int lookup_one(struct autofs_point *ap,
- break;
-
- if (ferror(f)) {
-- warn(LOGOPT_ANY, MODPREFIX
-+ warn(ap->logopt, MODPREFIX
- "error reading map %s", ctxt->mapname);
- break;
- }
-@@ -904,7 +904,7 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt)
- }
-
- while(1) {
-- entry = read_one(f, mkey, &k_len, mapent, &m_len);
-+ entry = read_one(ap->logopt, f, mkey, &k_len, mapent, &m_len);
- if (entry) {
- int eq;
-
-@@ -925,7 +925,7 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt)
- break;
-
- if (ferror(f)) {
-- warn(LOGOPT_ANY, MODPREFIX
-+ warn(ap->logopt, MODPREFIX
- "error reading map %s", ctxt->mapname);
- break;
- }
-diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c
-index f30e9b2..649e24c 100644
---- a/modules/lookup_hesiod.c
-+++ b/modules/lookup_hesiod.c
-@@ -48,7 +48,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- return 1;
- }
-
-@@ -58,7 +58,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- /* Initialize the hesiod context. */
- if (hesiod_init(&(ctxt->hesiod_context)) != 0) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "hesiod_init(): %s", estr);
-+ logerr(MODPREFIX "hesiod_init(): %s", estr);
- free(ctxt);
- return 1;
- }
-@@ -70,7 +70,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- /* Open the parser, if we can. */
- ctxt->parser = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
- if (!ctxt->parser) {
-- crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
-+ logerr(MODPREFIX "failed to open parse context");
- free(ctxt);
- return 1;
- }
-diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
-index d711611..d746e42 100644
---- a/modules/lookup_hosts.c
-+++ b/modules/lookup_hosts.c
-@@ -57,7 +57,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- return 1;
- }
-
-@@ -65,7 +65,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
-
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc, argv);
- if (!ctxt->parse) {
-- crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
-+ logerr(MODPREFIX "failed to open parse context");
- free(ctxt);
- return 1;
- }
-@@ -94,7 +94,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
-
- status = pthread_mutex_lock(&hostent_mutex);
- if (status) {
-- error(LOGOPT_ANY, MODPREFIX "failed to lock hostent mutex");
-+ error(ap->logopt, MODPREFIX "failed to lock hostent mutex");
- return NSS_STATUS_UNAVAIL;
- }
-
-@@ -110,7 +110,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
-
- status = pthread_mutex_unlock(&hostent_mutex);
- if (status)
-- error(LOGOPT_ANY, MODPREFIX "failed to unlock hostent mutex");
-+ error(ap->logopt, MODPREFIX "failed to unlock hostent mutex");
-
- source->age = age;
-
-@@ -157,10 +157,10 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
- }
-
- if (*name == '/')
-- msg(MODPREFIX
-+ info(ap->logopt, MODPREFIX
- "can't find path in hosts map %s", name);
- else
-- msg(MODPREFIX
-+ info(ap->logopt, MODPREFIX
- "can't find path in hosts map %s/%s",
- ap->path, name);
-
-@@ -216,7 +216,7 @@ done:
- if (!mapent) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(ap->logopt, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- rpc_exports_free(exp);
- return NSS_STATUS_UNAVAIL;
- }
-@@ -230,7 +230,7 @@ done:
- if (!mapent) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(ap->logopt, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- rpc_exports_free(exp);
- return NSS_STATUS_UNAVAIL;
- }
-diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index c0f228b..00215af 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -49,9 +49,9 @@ 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 *);
-+static LDAP *auth_init(unsigned logopt, const char *, struct lookup_context *);
-
--int bind_ldap_anonymous(LDAP *ldap, struct lookup_context *ctxt)
-+int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
- {
- int rv;
-
-@@ -62,15 +62,14 @@ int bind_ldap_anonymous(LDAP *ldap, struct lookup_context *ctxt)
-
- if (rv != LDAP_SUCCESS) {
- if (!ctxt->uri) {
-- crit(LOGOPT_ANY,
-- MODPREFIX "Unable to bind to the LDAP server: "
-+ crit(logopt, 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: "
-+ info(logopt, MODPREFIX "Unable to bind to the LDAP server: "
- "%s, error %s", uri->uri, ldap_err2string(rv));
- }
- return -1;
-@@ -79,12 +78,11 @@ int bind_ldap_anonymous(LDAP *ldap, struct lookup_context *ctxt)
- return 0;
- }
-
--int unbind_ldap_connection(LDAP *ldap, struct lookup_context *ctxt)
-+int unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
- {
- int rv;
-
- #ifdef WITH_SASL
-- debug(LOGOPT_NONE, "use_tls: %d", ctxt->use_tls);
- /*
- * The OpenSSL library can't handle having its message and error
- * string database loaded multiple times and segfaults if the
-@@ -102,13 +100,12 @@ int unbind_ldap_connection(LDAP *ldap, struct lookup_context *ctxt)
-
- rv = ldap_unbind_ext(ldap, NULL, NULL);
- if (rv != LDAP_SUCCESS)
-- error(LOGOPT_ANY,
-- "unbind failed: %s", ldap_err2string(rv));
-+ error(logopt, "unbind failed: %s", ldap_err2string(rv));
-
- return rv;
- }
-
--LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt)
-+LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt)
- {
- LDAP *ldap = NULL;
- struct timeval timeout = { ctxt->timeout, 0 };
-@@ -120,9 +117,9 @@ LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt)
- /* Initialize the LDAP context. */
- rv = ldap_initialize(&ldap, uri);
- if (rv != LDAP_OPT_SUCCESS) {
-- crit(LOGOPT_ANY,
-- MODPREFIX "couldn't initialize LDAP connection to %s",
-- uri ? uri : "default server");
-+ info(logopt, MODPREFIX
-+ "couldn't initialize LDAP connection to %s",
-+ uri ? uri : "default");
- return NULL;
- }
-
-@@ -133,7 +130,7 @@ LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt)
- ldap_unbind_ext(ldap, NULL, NULL);
- rv = ldap_initialize(&ldap, uri);
- if (rv != LDAP_OPT_SUCCESS) {
-- crit(LOGOPT_ANY, MODPREFIX "couldn't initialize LDAP");
-+ crit(logopt, MODPREFIX "couldn't initialize LDAP");
- return NULL;
- }
- ctxt->version = 2;
-@@ -144,7 +141,7 @@ LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt)
- /* Set synchronous call timeout */
- rv = ldap_set_option(ldap, LDAP_OPT_TIMEOUT, &timeout);
- if (rv != LDAP_OPT_SUCCESS)
-- info(LOGOPT_ANY, MODPREFIX
-+ info(logopt, MODPREFIX
- "failed to set synchronous call timeout to %d",
- timeout.tv_sec);
- }
-@@ -152,16 +149,14 @@ LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt)
- /* 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",
-+ info(logopt, MODPREFIX "failed to set connection timeout to %d",
- net_timeout.tv_sec);
-
- #ifdef WITH_SASL
- if (ctxt->use_tls) {
- if (ctxt->version == 2) {
- if (ctxt->tls_required) {
-- error(LOGOPT_ANY,
-- MODPREFIX
-+ error(logopt, MODPREFIX
- "TLS required but connection is version 2");
- ldap_unbind_ext(ldap, NULL, NULL);
- return NULL;
-@@ -171,16 +166,15 @@ LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt)
-
- rv = ldap_start_tls_s(ldap, NULL, NULL);
- if (rv != LDAP_SUCCESS) {
-- unbind_ldap_connection(ldap, ctxt);
-+ unbind_ldap_connection(logopt, ldap, ctxt);
- if (ctxt->tls_required) {
-- error(LOGOPT_ANY,
-- MODPREFIX
-+ error(logopt, MODPREFIX
- "TLS required but START_TLS failed: %s",
- ldap_err2string(rv));
- return NULL;
- }
- ctxt->use_tls = LDAP_TLS_DONT_USE;
-- ldap = init_ldap_connection(uri, ctxt);
-+ ldap = init_ldap_connection(logopt, uri, ctxt);
- if (ldap)
- ctxt->use_tls = LDAP_TLS_INIT;
- return ldap;
-@@ -192,7 +186,7 @@ LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt)
- return ldap;
- }
-
--static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key)
-+static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key)
- {
- char buf[PARSE_MAX_BUF];
- char *query, *dn, *qdn;
-@@ -206,7 +200,7 @@ static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *cla
- attrs[1] = NULL;
-
- if (!ctxt->mapname && !ctxt->base) {
-- error(LOGOPT_ANY, MODPREFIX "no master map to lookup");
-+ error(logopt, MODPREFIX "no master map to lookup");
- return 0;
- }
-
-@@ -218,7 +212,7 @@ static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *cla
- query = alloca(l);
- if (query == NULL) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "alloca: %s", estr);
-+ crit(logopt, MODPREFIX "alloca: %s", estr);
- return NSS_STATUS_UNAVAIL;
- }
-
-@@ -229,14 +223,14 @@ static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *cla
- if (ctxt->mapname) {
- if (sprintf(query, "(&(objectclass=%s)(%s=%.*s))", class,
- key, (int) strlen(ctxt->mapname), ctxt->mapname) >= l) {
-- debug(LOGOPT_NONE,
-+ debug(logopt,
- MODPREFIX "error forming query string");
- return 0;
- }
- scope = LDAP_SCOPE_SUBTREE;
- } else {
- if (sprintf(query, "(objectclass=%s)", class) >= l) {
-- debug(LOGOPT_NONE,
-+ debug(logopt,
- MODPREFIX "error forming query string");
- return 0;
- }
-@@ -259,15 +253,14 @@ static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *cla
- else {
- struct ldap_searchdn *this = ctxt->sdns;
-
-- debug(LOGOPT_NONE, MODPREFIX
-- "check search base list");
-+ debug(logopt, 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
-+ debug(logopt, MODPREFIX
- "found search base under %s",
- this->basedn);
- break;
-@@ -283,7 +276,7 @@ static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *cla
- }
-
- if ((rv != LDAP_SUCCESS) || !result) {
-- error(LOGOPT_NONE,
-+ error(logopt,
- MODPREFIX "query failed for %s: %s",
- query, ldap_err2string(rv));
- return 0;
-@@ -292,9 +285,9 @@ 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 "found query dn %s", dn);
-+ debug(logopt, MODPREFIX "found query dn %s", dn);
- } else {
-- debug(LOGOPT_NONE,
-+ debug(logopt,
- MODPREFIX "query succeeded, no matches for %s",
- query);
- ldap_msgfree(result);
-@@ -373,7 +366,7 @@ static struct ldap_schema *alloc_common_schema(struct ldap_schema *s)
- return schema;
- }
-
--static int find_query_dn(LDAP *ldap, struct lookup_context *ctxt)
-+static int find_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
- {
- struct ldap_schema *schema;
- unsigned int i;
-@@ -384,11 +377,10 @@ static int find_query_dn(LDAP *ldap, struct lookup_context *ctxt)
- 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)) {
-+ if (get_query_dn(logopt, ldap, ctxt, class, key)) {
- schema = alloc_common_schema(&common_schema[i]);
- if (!schema) {
-- error(LOGOPT_ANY,
-- MODPREFIX "failed to allocate schema");
-+ error(logopt, MODPREFIX "failed to allocate schema");
- return 0;
- }
- ctxt->schema = schema;
-@@ -399,28 +391,26 @@ static int find_query_dn(LDAP *ldap, struct lookup_context *ctxt)
- return 0;
- }
-
--static int do_bind(LDAP *ldap, struct lookup_context *ctxt)
-+static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
- {
- char *host = NULL, *nhost;
- int rv, need_base = 1;
-
- #ifdef WITH_SASL
-- debug(LOGOPT_NONE, "auth_required: %d, sasl_mech %s",
-+ debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s",
- ctxt->auth_required, ctxt->sasl_mech);
-
- if (ctxt->sasl_mech ||
- (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT))) {
-- rv = autofs_sasl_bind(ldap, ctxt);
-- debug(LOGOPT_NONE, MODPREFIX
-- "autofs_sasl_bind returned %d", rv);
-+ rv = autofs_sasl_bind(logopt, ldap, ctxt);
-+ debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
- } else {
-- rv = bind_ldap_anonymous(ldap, ctxt);
-- debug(LOGOPT_NONE,
-- MODPREFIX "ldap anonymous bind returned %d", rv);
-+ rv = bind_ldap_anonymous(logopt, ldap, ctxt);
-+ debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv);
- }
- #else
-- rv = bind_ldap_anonymous(ldap, ctxt);
-- debug(LOGOPT_NONE, MODPREFIX "ldap anonymous bind returned %d", rv);
-+ rv = bind_ldap_anonymous(logopt, ldap, ctxt);
-+ debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv);
- #endif
-
- if (rv != 0)
-@@ -428,13 +418,13 @@ static int do_bind(LDAP *ldap, struct lookup_context *ctxt)
-
- rv = ldap_get_option(ldap, LDAP_OPT_HOST_NAME, &host);
- if (rv != LDAP_SUCCESS || !host) {
-- debug(LOGOPT_ANY, "failed to get hostname for connection");
-+ debug(logopt, "failed to get hostname for connection");
- return 0;
- }
-
- nhost = strdup(host);
- if (!nhost) {
-- debug(LOGOPT_ANY, "failed to alloc context for hostname");
-+ debug(logopt, "failed to alloc context for hostname");
- return 0;
- }
- ldap_memfree(host);
-@@ -463,16 +453,16 @@ static int do_bind(LDAP *ldap, struct lookup_context *ctxt)
- * base dn for searches.
- */
- if (!ctxt->schema) {
-- if (!find_query_dn(ldap, ctxt)) {
-- error(LOGOPT_ANY,
-- MODPREFIX "failed to find valid query dn");
-+ if (!find_query_dn(logopt, ldap, ctxt)) {
-+ warn(logopt,
-+ MODPREFIX "failed to find valid query dn");
- 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)) {
-- error(LOGOPT_ANY, MODPREFIX "failed to get query dn");
-+ if (!get_query_dn(logopt, ldap, ctxt, class, key)) {
-+ error(logopt, MODPREFIX "failed to get query dn");
- return 0;
- }
- }
-@@ -480,23 +470,23 @@ static int do_bind(LDAP *ldap, struct lookup_context *ctxt)
- return 1;
- }
-
--static LDAP *do_connect(const char *uri, struct lookup_context *ctxt)
-+static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context *ctxt)
- {
- LDAP *ldap;
-
-- ldap = init_ldap_connection(uri, ctxt);
-+ ldap = init_ldap_connection(logopt, uri, ctxt);
- if (!ldap)
- return NULL;
-
-- if (!do_bind(ldap, ctxt)) {
-- unbind_ldap_connection(ldap, ctxt);
-+ if (!do_bind(logopt, ldap, ctxt)) {
-+ unbind_ldap_connection(logopt, ldap, ctxt);
- return NULL;
- }
-
- return ldap;
- }
-
--static LDAP *connect_to_server(const char *uri, struct lookup_context *ctxt)
-+static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_context *ctxt)
- {
- LDAP *ldap;
-
-@@ -506,19 +496,19 @@ static LDAP *connect_to_server(const char *uri, struct lookup_context *ctxt)
- * authentication.
- */
- if (ctxt->auth_required & LDAP_AUTH_REQUIRED) {
-- ldap = auth_init(uri, ctxt);
-+ ldap = auth_init(logopt, uri, ctxt);
- if (!ldap && ctxt->auth_required & LDAP_AUTH_AUTODETECT)
-- warn(LOGOPT_NONE,
-+ info(logopt,
- "no authentication mechanisms auto detected.");
- if (!ldap) {
-- error(LOGOPT_ANY, MODPREFIX
-+ error(logopt, 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");
-+ if (!do_bind(logopt, ldap, ctxt)) {
-+ unbind_ldap_connection(logopt, ldap, ctxt);
-+ error(logopt, MODPREFIX "cannot bind to server");
- return NULL;
- }
-
-@@ -526,16 +516,18 @@ static LDAP *connect_to_server(const char *uri, struct lookup_context *ctxt)
- }
- #endif
-
-- ldap = do_connect(uri, ctxt);
-+ ldap = do_connect(logopt, uri, ctxt);
- if (!ldap) {
-- error(LOGOPT_ANY, MODPREFIX "cannot connect to server");
-+ warn(logopt,
-+ MODPREFIX "couldn't connect to server %s",
-+ uri ? uri : "default");
- return NULL;
- }
-
- return ldap;
- }
-
--static LDAP *find_server(struct lookup_context *ctxt)
-+static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
- {
- LDAP *ldap = NULL;
- struct ldap_uri *this;
-@@ -547,10 +539,9 @@ static LDAP *find_server(struct lookup_context *ctxt)
- 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);
-+ ldap = connect_to_server(logopt, this->uri, ctxt);
- if (ldap) {
-- debug(LOGOPT_ANY, "connexted to uri %s", this->uri);
-+ info(logopt, "connected to uri %s", this->uri);
- break;
- }
- list_del_init(&this->list);
-@@ -568,17 +559,17 @@ static LDAP *find_server(struct lookup_context *ctxt)
- return ldap;
- }
-
--static LDAP *do_reconnect(struct lookup_context *ctxt)
-+static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
- {
- LDAP *ldap;
-
- if (ctxt->server || !ctxt->uri) {
-- ldap = do_connect(ctxt->server, ctxt);
-+ ldap = do_connect(logopt, 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);
-+ ldap = do_connect(logopt, this->uri, ctxt);
- if (ldap)
- return ldap;
- /* Failed to connect, put at end of list */
-@@ -589,15 +580,15 @@ static LDAP *do_reconnect(struct lookup_context *ctxt)
- autofs_sasl_done(ctxt);
-
- /* Current server failed connect, try the rest */
-- ldap = find_server(ctxt);
-+ ldap = find_server(logopt, ctxt);
- if (!ldap)
-- error(LOGOPT_ANY, MODPREFIX "failed to find available server");
-+ error(logopt, MODPREFIX "failed to find available server");
-
- return ldap;
- }
-
- #ifdef WITH_SASL
--int get_property(xmlNodePtr node, const char *prop, char **value)
-+int get_property(unsigned logopt, xmlNodePtr node, const char *prop, char **value)
- {
- xmlChar *ret;
- xmlChar *property = (xmlChar *) prop;
-@@ -608,8 +599,7 @@ int get_property(xmlNodePtr node, const char *prop, char **value)
- }
-
- if (!(*value = strdup((char *) ret))) {
-- error(LOGOPT_ANY,
-- MODPREFIX "strdup failed with %d", errno);
-+ logerr(MODPREFIX "strdup failed with %d", errno);
- xmlFree(ret);
- return -1;
- }
-@@ -645,7 +635,7 @@ int authtype_requires_creds(const char *authtype)
- * then no further action is necessary. If it is not, the caller is free
- * to then use another method to determine how to connect to the server.
- */
--int parse_ldap_config(struct lookup_context *ctxt)
-+int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
- {
- int ret = 0, fallback = 0;
- unsigned int auth_required = LDAP_AUTH_NOTREQUIRED;
-@@ -662,7 +652,7 @@ int parse_ldap_config(struct lookup_context *ctxt)
-
- auth_conf = (char *) defaults_get_auth_conf_file();
- if (!auth_conf) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX "failed to get auth config file name.");
- return 0;
- }
-@@ -687,7 +677,7 @@ int parse_ldap_config(struct lookup_context *ctxt)
- ctxt->client_princ = NULL;
- return 0;
- }
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX "stat(2) failed with error %s.",
- strerror(errno));
- return 0;
-@@ -696,8 +686,7 @@ int parse_ldap_config(struct lookup_context *ctxt)
- if (!S_ISREG(st.st_mode) ||
- st.st_uid != 0 || st.st_gid != 0 ||
- (st.st_mode & 0x01ff) != 0600) {
-- error(LOGOPT_ANY,
-- MODPREFIX
-+ error(logopt, MODPREFIX
- "Configuration file %s exists, but is not usable. "
- "Please make sure that it is owned by root, group "
- "is root, and the mode is 0600.",
-@@ -708,30 +697,29 @@ int parse_ldap_config(struct lookup_context *ctxt)
- xmlInitParser();
- doc = xmlParseFile(auth_conf);
- if (!doc) {
-- warn(LOGOPT_ANY,
-- MODPREFIX "xmlParseFile failed for %s.", auth_conf);
-+ error(logopt, MODPREFIX
-+ "xmlParseFile failed for %s.", auth_conf);
- goto out;
- }
-
- root = xmlDocGetRootElement(doc);
- if (!root) {
-- debug(LOGOPT_ANY,
-- MODPREFIX "empty xml document (%s).", auth_conf);
-+ debug(logopt, MODPREFIX
-+ "empty xml document (%s).", auth_conf);
- fallback = 1;
- goto out;
- }
-
- if (xmlStrcmp(root->name, (const xmlChar *)"autofs_ldap_sasl_conf")) {
-- error(LOGOPT_ANY,
-- MODPREFIX
-+ error(logopt, MODPREFIX
- "The root node of the XML document %s is not "
- "autofs_ldap_sasl_conf.", auth_conf);
- goto out;
- }
-
-- ret = get_property(root, "usetls", &usetls);
-+ ret = get_property(logopt, root, "usetls", &usetls);
- if (ret != 0) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX
- "Failed read the usetls property from "
- "the configuration file %s.", auth_conf);
-@@ -746,7 +734,7 @@ int parse_ldap_config(struct lookup_context *ctxt)
- else if (!strcasecmp(usetls, "no"))
- use_tls = LDAP_TLS_DONT_USE;
- else {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX
- "The usetls property must have value "
- "\"yes\" or \"no\".");
-@@ -756,9 +744,9 @@ int parse_ldap_config(struct lookup_context *ctxt)
- free(usetls);
- }
-
-- ret = get_property(root, "tlsrequired", &tlsrequired);
-+ ret = get_property(logopt, root, "tlsrequired", &tlsrequired);
- if (ret != 0) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX
- "Failed read the tlsrequired property from "
- "the configuration file %s.", auth_conf);
-@@ -773,7 +761,7 @@ int parse_ldap_config(struct lookup_context *ctxt)
- else if (!strcasecmp(tlsrequired, "no"))
- tls_required = LDAP_TLS_DONT_USE;
- else {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX
- "The tlsrequired property must have value "
- "\"yes\" or \"no\".");
-@@ -783,9 +771,9 @@ int parse_ldap_config(struct lookup_context *ctxt)
- free(tlsrequired);
- }
-
-- ret = get_property(root, "authrequired", &authrequired);
-+ ret = get_property(logopt, root, "authrequired", &authrequired);
- if (ret != 0) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX
- "Failed read the authrequired property from "
- "the configuration file %s.", auth_conf);
-@@ -802,7 +790,7 @@ int parse_ldap_config(struct lookup_context *ctxt)
- else if (!strcasecmp(authrequired, "autodetect"))
- auth_required = LDAP_AUTH_AUTODETECT;
- else {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX
- "The authrequired property must have value "
- "\"yes\", \"no\" or \"autodetect\".");
-@@ -812,9 +800,9 @@ int parse_ldap_config(struct lookup_context *ctxt)
- free(authrequired);
- }
-
-- ret = get_property(root, "authtype", &authtype);
-+ ret = get_property(logopt, root, "authtype", &authtype);
- if (ret != 0) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX
- "Failed read the authtype property from the "
- "configuration file %s.", auth_conf);
-@@ -822,10 +810,10 @@ int parse_ldap_config(struct lookup_context *ctxt)
- }
-
- if (authtype && authtype_requires_creds(authtype)) {
-- ret = get_property(root, "user", &user);
-- ret |= get_property(root, "secret", &secret);
-+ ret = get_property(logopt, root, "user", &user);
-+ ret |= get_property(logopt, root, "secret", &secret);
- if (ret != 0 || (!user || !secret)) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX
- "%s authentication type requires a username "
- "and a secret. Please fix your configuration "
-@@ -845,7 +833,7 @@ int parse_ldap_config(struct lookup_context *ctxt)
- * We allow the admin to specify the principal to use for the
- * client. The default is "autofsclient/hostname@REALM".
- */
-- (void)get_property(root, "clientprinc", &client_princ);
-+ (void)get_property(logopt, root, "clientprinc", &client_princ);
-
- ctxt->auth_conf = auth_conf;
- ctxt->use_tls = use_tls;
-@@ -856,15 +844,15 @@ int parse_ldap_config(struct lookup_context *ctxt)
- ctxt->secret = secret;
- ctxt->client_princ = client_princ;
-
-- debug(LOGOPT_NONE,
-+ debug(logopt, MODPREFIX
- "ldap authentication configured with the following options:");
-- debug(LOGOPT_NONE,
-+ debug(logopt, MODPREFIX
- "use_tls: %u, "
- "tls_required: %u, "
- "auth_required: %u, "
- "sasl_mech: %s",
- use_tls, tls_required, auth_required, authtype);
-- debug(LOGOPT_NONE,
-+ debug(logopt, MODPREFIX
- "user: %s, "
- "secret: %s, "
- "client principal: %s",
-@@ -889,7 +877,7 @@ out:
- * Returns ldap connection on success, with authtype, user and secret
- * filled in as appropriate. Returns NULL on failre.
- */
--static LDAP *auth_init(const char *uri, struct lookup_context *ctxt)
-+static LDAP *auth_init(unsigned logopt, const char *uri, struct lookup_context *ctxt)
- {
- int ret;
- LDAP *ldap;
-@@ -900,11 +888,11 @@ static LDAP *auth_init(const char *uri, struct lookup_context *ctxt)
- * if the permissions on the file were incorrect, or if the
- * specified authentication type is not valid.
- */
-- ret = parse_ldap_config(ctxt);
-+ ret = parse_ldap_config(logopt, ctxt);
- if (ret)
- return NULL;
-
-- ldap = init_ldap_connection(uri, ctxt);
-+ ldap = init_ldap_connection(logopt, uri, ctxt);
- if (!ldap)
- return NULL;
-
-@@ -916,7 +904,7 @@ static LDAP *auth_init(const char *uri, struct lookup_context *ctxt)
- * to use. If kerberos is used, it will also take care to initialize
- * the credential cache and the client and service principals.
- */
-- ret = autofs_sasl_init(ldap, ctxt);
-+ ret = autofs_sasl_init(logopt, ldap, ctxt);
- if (ret) {
- ctxt->sasl_mech = NULL;
- return NULL;
-@@ -930,7 +918,7 @@ static LDAP *auth_init(const char *uri, struct lookup_context *ctxt)
- * Take an input string as specified in the master map, and break it
- * down into a server name and basedn.
- */
--static int parse_server_string(const char *url, struct lookup_context *ctxt)
-+static int parse_server_string(unsigned logopt, const char *url, struct lookup_context *ctxt)
- {
- char buf[MAX_ERR_BUF], *tmp = NULL, proto[9];
- const char *ptr, *name;
-@@ -939,8 +927,7 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
- memset(proto, 0, 9);
- ptr = url;
-
-- debug(LOGOPT_NONE,
-- MODPREFIX
-+ debug(logopt, MODPREFIX
- "Attempting to parse LDAP information from string \"%s\".", ptr);
-
- ctxt->port = LDAP_PORT;
-@@ -974,7 +961,7 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
- if (!tmp) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- return 0;
- }
- ctxt->server = tmp;
-@@ -987,7 +974,7 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
- memcpy(ctxt->server, s, l);
- ptr = q + 1;
- } else {
-- crit(LOGOPT_ANY,
-+ crit(logopt,
- MODPREFIX "invalid LDAP map syntax %s", ptr);
- return 0;
- /* TODO: why did I put this here, the parser shouldn't let this by
-@@ -996,7 +983,7 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
- if (!tmp) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ crit(logopt, MODPREFIX "malloc: %s", estr);
- return 0;
- }
- ctxt->server = tmp;
-@@ -1014,7 +1001,7 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
- q++;
-
- if (*q != ':') {
-- crit(LOGOPT_ANY,
-+ crit(logopt,
- MODPREFIX "invalid LDAP map syntax %s", ptr);
- return 0;
- }
-@@ -1031,7 +1018,7 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
- if (!tmp) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- return 0;
- }
- ctxt->server = tmp;
-@@ -1072,7 +1059,7 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
- else {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- if (ctxt->server)
- free(ctxt->server);
- return 0;
-@@ -1083,7 +1070,7 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
- if (!base) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- if (ctxt->server)
- free(ctxt->server);
- return 0;
-@@ -1097,7 +1084,7 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
- if (!map) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- if (ctxt->server)
- free(ctxt->server);
- return 0;
-@@ -1109,16 +1096,16 @@ static int parse_server_string(const char *url, struct lookup_context *ctxt)
-
- if (!ctxt->server && *proto) {
- if (!strncmp(proto, "ldaps", 5)) {
-- warn(LOGOPT_ANY, MODPREFIX
-+ info(logopt, MODPREFIX
- "server must be given to force ldaps, connection "
- "will use LDAP client configured protocol");
- }
- }
- done:
- if (ctxt->mapname)
-- debug(LOGOPT_NONE, MODPREFIX "mapname %s", ctxt->mapname);
-+ debug(logopt, MODPREFIX "mapname %s", ctxt->mapname);
- else
-- debug(LOGOPT_NONE, MODPREFIX "server \"%s\", base dn \"%s\"",
-+ debug(logopt, MODPREFIX "server \"%s\", base dn \"%s\"",
- ctxt->server ? ctxt->server : "(default)",
- ctxt->base);
-
-@@ -1175,8 +1162,6 @@ static void validate_uris(struct list_head *list)
-
- /* 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);
-@@ -1202,7 +1187,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- return 1;
- }
- memset(ctxt, 0, sizeof(struct lookup_context));
-@@ -1215,7 +1200,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- * Parse out the server name and base dn, and fill them
- * into the proper places in the lookup context structure.
- */
-- if (!parse_server_string(argv[0], ctxt)) {
-+ if (!parse_server_string(LOGOPT_NONE, argv[0], ctxt)) {
- error(LOGOPT_ANY, MODPREFIX "cannot parse server string");
- free_context(ctxt);
- return 1;
-@@ -1236,13 +1221,13 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- }
-
- if (ctxt->server || !ctxt->uri) {
-- ldap = connect_to_server(ctxt->server, ctxt);
-+ ldap = connect_to_server(LOGOPT_NONE, ctxt->server, ctxt);
- if (!ldap) {
- free_context(ctxt);
- return 1;
- }
- } else {
-- ldap = find_server(ctxt);
-+ ldap = find_server(LOGOPT_NONE, ctxt);
- if (!ldap) {
- free_context(ctxt);
- error(LOGOPT_ANY, MODPREFIX
-@@ -1250,13 +1235,13 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- return 1;
- }
- }
-- unbind_ldap_connection(ldap, ctxt);
-+ unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt);
-
- /* Open the parser, if we can. */
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
- if (!ctxt->parse) {
- free_context(ctxt);
-- crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
-+ logerr(MODPREFIX "failed to open parse context");
- return 1;
- }
- *context = ctxt;
-@@ -1269,6 +1254,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- struct lookup_context *ctxt = (struct lookup_context *) context;
- unsigned int timeout = master->default_timeout;
- unsigned int logging = master->default_logging;
-+ unsigned int logopt = master->logopt;
- int rv, l, count, blen;
- char buf[PARSE_MAX_BUF];
- char *query;
-@@ -1293,45 +1279,44 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- query = alloca(l);
- if (query == NULL) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- return NSS_STATUS_UNAVAIL;
- }
-
- if (sprintf(query, "(objectclass=%s)", class) >= l) {
-- debug(LOGOPT_NONE, MODPREFIX "error forming query string");
-+ error(logopt, MODPREFIX "error forming query string");
- return NSS_STATUS_UNAVAIL;
- }
- query[l] = '\0';
-
- /* Initialize the LDAP context. */
-- ldap = do_reconnect(ctxt);
-+ ldap = do_reconnect(logopt, ctxt);
- if (!ldap)
- return NSS_STATUS_UNAVAIL;
-
- /* Look around. */
-- debug(LOGOPT_NONE,
-+ debug(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) {
-- error(LOGOPT_NONE,
-- MODPREFIX "query failed for %s: %s",
-+ error(logopt, MODPREFIX "query failed for %s: %s",
- query, ldap_err2string(rv));
-- unbind_ldap_connection(ldap, ctxt);
-+ unbind_ldap_connection(logging, ldap, ctxt);
- return NSS_STATUS_NOTFOUND;
- }
-
- e = ldap_first_entry(ldap, result);
- if (!e) {
-- debug(LOGOPT_NONE,
-+ debug(logopt,
- MODPREFIX "query succeeded, no matches for %s",
- query);
- ldap_msgfree(result);
-- unbind_ldap_connection(ldap, ctxt);
-+ unbind_ldap_connection(logging, ldap, ctxt);
- return NSS_STATUS_NOTFOUND;
- } else
-- debug(LOGOPT_NONE, MODPREFIX "examining entries");
-+ debug(logopt, MODPREFIX "examining entries");
-
- while (e) {
- keyValue = ldap_get_values(ldap, e, entry);
-@@ -1346,7 +1331,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- * each map entry
- */
- if (ldap_count_values(keyValue) > 1) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX
- "key %s has duplicate entries - ignoring",
- *keyValue);
-@@ -1358,7 +1343,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- * inclusion is only valid in file maps.
- */
- if (**keyValue == '+') {
-- warn(LOGOPT_ANY,
-+ warn(logopt,
- MODPREFIX
- "ignoreing '+' map entry - not in file map");
- goto next;
-@@ -1366,7 +1351,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
-
- values = ldap_get_values(ldap, e, info);
- if (!values || !*values) {
-- debug(LOGOPT_NONE,
-+ debug(logopt,
- MODPREFIX "no %s defined for %s", info, query);
- goto next;
- }
-@@ -1376,7 +1361,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- */
- count = ldap_count_values(values);
- if (count > 1) {
-- error(LOGOPT_ANY,
-+ error(logopt,
- MODPREFIX
- "one value per key allowed in master map");
- ldap_value_free(values);
-@@ -1385,7 +1370,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
-
- blen = strlen(*keyValue) + 1 + strlen(*values) + 1;
- if (blen > PARSE_MAX_BUF) {
-- error(LOGOPT_ANY, MODPREFIX "map entry too long");
-+ error(logopt, MODPREFIX "map entry too long");
- ldap_value_free(values);
- goto next;
- }
-@@ -1403,7 +1388,7 @@ next:
-
- /* Clean up. */
- ldap_msgfree(result);
-- unbind_ldap_connection(ldap, ctxt);
-+ unbind_ldap_connection(logopt, ldap, ctxt);
-
- return NSS_STATUS_SUCCESS;
- }
-@@ -1445,7 +1430,7 @@ static int read_one_map(struct autofs_point *ap,
- query = alloca(l);
- if (query == NULL) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- return NSS_STATUS_UNAVAIL;
- }
-
-@@ -1456,7 +1441,7 @@ static int read_one_map(struct autofs_point *ap,
- query[l] = '\0';
-
- /* Initialize the LDAP context. */
-- ldap = do_reconnect(ctxt);
-+ ldap = do_reconnect(ap->logopt, ctxt);
- if (!ldap)
- return NSS_STATUS_UNAVAIL;
-
-@@ -1470,7 +1455,7 @@ static int read_one_map(struct autofs_point *ap,
- debug(ap->logopt,
- MODPREFIX "query failed for %s: %s",
- query, ldap_err2string(rv));
-- unbind_ldap_connection(ldap, ctxt);
-+ unbind_ldap_connection(ap->logopt, ldap, ctxt);
- *result_ldap = rv;
- return NSS_STATUS_NOTFOUND;
- }
-@@ -1480,7 +1465,7 @@ static int read_one_map(struct autofs_point *ap,
- debug(ap->logopt,
- MODPREFIX "query succeeded, no matches for %s", query);
- ldap_msgfree(result);
-- unbind_ldap_connection(ldap, ctxt);
-+ unbind_ldap_connection(ap->logopt, ldap, ctxt);
- return NSS_STATUS_NOTFOUND;
- } else
- debug(ap->logopt, MODPREFIX "examining entries");
-@@ -1612,8 +1597,7 @@ static int read_one_map(struct autofs_point *ap,
- if (!mapent) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt,
-- MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- ldap_value_free_len(bvValues);
- goto next;
- }
-@@ -1633,8 +1617,7 @@ static int read_one_map(struct autofs_point *ap,
- } else {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt,
-- MODPREFIX "realloc: %s", estr);
-+ logerr(MODPREFIX "realloc: %s", estr);
- }
- }
- }
-@@ -1669,7 +1652,7 @@ next:
-
- /* Clean up. */
- ldap_msgfree(result);
-- unbind_ldap_connection(ldap, ctxt);
-+ unbind_ldap_connection(ap->logopt, ldap, ctxt);
-
- source->age = age;
-
-@@ -1766,7 +1749,7 @@ static int lookup_one(struct autofs_point *ap,
- query[ql] = '\0';
-
- /* Initialize the LDAP context. */
-- ldap = do_reconnect(ctxt);
-+ ldap = do_reconnect(ap->logopt, ctxt);
- if (!ldap)
- return CHE_FAIL;
-
-@@ -1777,7 +1760,7 @@ static int lookup_one(struct autofs_point *ap,
-
- if ((rv != LDAP_SUCCESS) || !result) {
- crit(ap->logopt, MODPREFIX "query failed for %s", query);
-- unbind_ldap_connection(ldap, ctxt);
-+ unbind_ldap_connection(ap->logopt, ldap, ctxt);
- return CHE_FAIL;
- }
-
-@@ -1789,7 +1772,7 @@ static int lookup_one(struct autofs_point *ap,
- debug(ap->logopt,
- MODPREFIX "got answer, but no entry for %s", query);
- ldap_msgfree(result);
-- unbind_ldap_connection(ldap, ctxt);
-+ unbind_ldap_connection(ap->logopt, ldap, ctxt);
- return CHE_MISSING;
- }
-
-@@ -1897,8 +1880,7 @@ static int lookup_one(struct autofs_point *ap,
- if (!mapent) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt,
-- MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- ldap_value_free_len(bvValues);
- goto next;
- }
-@@ -1918,8 +1900,7 @@ static int lookup_one(struct autofs_point *ap,
- } else {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt,
-- MODPREFIX "realloc: %s", estr);
-+ logerr(MODPREFIX "realloc: %s", estr);
- }
- }
- }
-@@ -1955,7 +1936,7 @@ next:
- }
-
- ldap_msgfree(result);
-- unbind_ldap_connection(ldap, ctxt);
-+ unbind_ldap_connection(ap->logopt, ldap, ctxt);
-
- /* Failed to find wild entry, update cache if needed */
- pthread_cleanup_push(cache_lock_cleanup, mc);
-diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
-index 8fa94ae..601d48e 100644
---- a/modules/lookup_multi.c
-+++ b/modules/lookup_multi.c
-@@ -73,7 +73,7 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
- if (nsswitch_parse(&nsslist)) {
- if (!list_empty(&nsslist))
- free_sources(&nsslist);
-- error(LOGOPT_ANY, "can't to read name service switch config.");
-+ logerr("can't to read name service switch config.");
- return NULL;
- }
-
-@@ -92,7 +92,7 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
- 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);
-+ logerr(MODPREFIX "error: %s", estr);
- free_sources(&nsslist);
- return NULL;
- }
-@@ -150,7 +150,7 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void *
- memset(ctxt, 0, sizeof(struct lookup_context));
-
- if (argc < 1) {
-- crit(LOGOPT_ANY, MODPREFIX "No map list");
-+ logerr(MODPREFIX "No map list");
- goto error_out;
- }
-
-@@ -176,8 +176,7 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void *
- if (!strcmp(ctxt->argl[an], "--")) {
- ctxt->argl[an] = NULL;
- if (!args) {
-- crit(LOGOPT_ANY,
-- MODPREFIX "error assigning map args");
-+ logerr(MODPREFIX "error assigning map args");
- goto error_out;
- }
- ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args);
-@@ -201,7 +200,7 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void *
- 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");
-+ logerr(MODPREFIX "error opening module");
- goto error_out;
- }
- }
-@@ -211,7 +210,7 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void *
-
- nomem:
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "error: %s", estr);
-+ logerr(MODPREFIX "error: %s", estr);
- error_out:
- if (ctxt) {
- for (i = 0; i < ctxt->n; i++) {
-diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
-index 83e99e0..ff8bd49 100644
---- a/modules/lookup_nisplus.c
-+++ b/modules/lookup_nisplus.c
-@@ -41,13 +41,13 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "%s", estr);
-+ logerr(MODPREFIX "%s", estr);
- return 1;
- }
-
- if (argc < 1) {
- free(ctxt);
-- crit(LOGOPT_ANY, MODPREFIX "No map name");
-+ logmsg(MODPREFIX "No map name");
- return 1;
- }
- ctxt->mapname = argv[0];
-@@ -59,7 +59,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- ctxt->domainname = nis_local_directory();
- if (!ctxt->domainname) {
- free(ctxt);
-- crit(LOGOPT_ANY, MODPREFIX "NIS+ domain not set");
-+ logmsg(MODPREFIX "NIS+ domain not set");
- return 1;
- }
-
-@@ -69,7 +69,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
- if (!ctxt->parse) {
- free(ctxt);
-- crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
-+ logerr(MODPREFIX "failed to open parse context");
- return 1;
- }
- *context = ctxt;
-@@ -81,7 +81,8 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- {
- struct lookup_context *ctxt = (struct lookup_context *) context;
- unsigned int timeout = master->default_timeout;
-- unsigned int logging = master->default_logging;
-+ unsigned int logging = master->default_logging;
-+ unsigned int logopt = master->logopt;
- char *tablename;
- nis_result *result;
- nis_object *this;
-@@ -95,7 +96,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- tablename = alloca(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20);
- if (!tablename) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- pthread_setcancelstate(cur_state, NULL);
- return NSS_STATUS_UNAVAIL;
- }
-@@ -105,8 +106,8 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- result = nis_lookup(tablename, FOLLOW_PATH | FOLLOW_LINKS);
- if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
- nis_freeresult(result);
-- crit(LOGOPT_ANY,
-- MODPREFIX "couldn't locat nis+ table %s", ctxt->mapname);
-+ crit(logopt,
-+ MODPREFIX "couldn't locate nis+ table %s", ctxt->mapname);
- pthread_setcancelstate(cur_state, NULL);
- return NSS_STATUS_NOTFOUND;
- }
-@@ -116,7 +117,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- result = nis_list(tablename, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
- if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
- nis_freeresult(result);
-- crit(LOGOPT_ANY,
-+ crit(logopt,
- MODPREFIX "couldn't enumrate nis+ map %s", ctxt->mapname);
- pthread_setcancelstate(cur_state, NULL);
- return NSS_STATUS_UNAVAIL;
-@@ -139,8 +140,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
-
- buffer = malloc(ENTRY_LEN(this, 0) + 1 + ENTRY_LEN(this, 1) + 1);
- if (!buffer) {
-- error(LOGOPT_ANY,
-- MODPREFIX "could not malloc parse buffer");
-+ logerr(MODPREFIX "could not malloc parse buffer");
- continue;
- }
-
-@@ -182,7 +182,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
- tablename = alloca(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20);
- if (!tablename) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- pthread_setcancelstate(cur_state, NULL);
- return NSS_STATUS_UNAVAIL;
- }
-@@ -193,7 +193,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
- if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
- nis_freeresult(result);
- crit(ap->logopt,
-- MODPREFIX "couldn't locat nis+ table %s", ctxt->mapname);
-+ MODPREFIX "couldn't locate nis+ table %s", ctxt->mapname);
- pthread_setcancelstate(cur_state, NULL);
- return NSS_STATUS_NOTFOUND;
- }
-@@ -274,7 +274,7 @@ static int lookup_one(struct autofs_point *ap,
- strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20);
- if (!tablename) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- pthread_setcancelstate(cur_state, NULL);
- return -1;
- }
-@@ -327,7 +327,7 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt)
- tablename = alloca(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20);
- if (!tablename) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- pthread_setcancelstate(cur_state, NULL);
- return -1;
- }
-diff --git a/modules/lookup_program.c b/modules/lookup_program.c
-index 2fd521a..e28168e 100644
---- a/modules/lookup_program.c
-+++ b/modules/lookup_program.c
-@@ -51,28 +51,26 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- return 1;
- }
-
- if (argc < 1) {
-- crit(LOGOPT_ANY, MODPREFIX "No map name");
-+ logmsg(MODPREFIX "No map name");
- free(ctxt);
- return 1;
- }
- ctxt->mapname = argv[0];
-
- if (ctxt->mapname[0] != '/') {
-- crit(LOGOPT_ANY,
-- MODPREFIX "program map %s is not an absolute pathname",
-+ logmsg(MODPREFIX "program map %s is not an absolute pathname",
- ctxt->mapname);
- free(ctxt);
- return 1;
- }
-
- if (access(ctxt->mapname, X_OK)) {
-- crit(LOGOPT_ANY,
-- MODPREFIX "program map %s missing or not executable",
-+ logmsg(MODPREFIX "program map %s missing or not executable",
- ctxt->mapname);
- free(ctxt);
- return 1;
-@@ -83,7 +81,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
-
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
- if (!ctxt->parse) {
-- crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
-+ logmsg(MODPREFIX "failed to open parse context");
- free(ctxt);
- return 1;
- }
-@@ -163,7 +161,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
- mapent = (char *) malloc(MAPENT_MAX_LEN + 1);
- if (!mapent) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- return NSS_STATUS_UNAVAIL;
- }
-
-@@ -176,7 +174,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
- */
- if (pipe(pipefd)) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "pipe: %s", estr);
-+ logerr(MODPREFIX "pipe: %s", estr);
- goto out_free;
- }
- if (pipe(epipefd)) {
-@@ -188,7 +186,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
- f = fork();
- if (f < 0) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "fork: %s", estr);
-+ logerr(MODPREFIX "fork: %s", estr);
- close(pipefd[0]);
- close(pipefd[1]);
- close(epipefd[0]);
-@@ -271,8 +269,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
- ++alloci));
- if (!tmp) {
- alloci--;
-- error(ap->logopt,
-- MODPREFIX "realloc: %s",
-+ logerr(MODPREFIX "realloc: %s",
- strerror(errno));
- break;
- }
-@@ -308,12 +305,12 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
- } else if (ch == '\n') {
- *errp = '\0';
- if (errbuf[0])
-- error(ap->logopt, ">> %s", errbuf);
-+ logmsg(">> %s", errbuf);
- errp = errbuf;
- } else {
- if (errp >= &errbuf[1023]) {
- *errp = '\0';
-- error(ap->logopt, ">> %s", errbuf);
-+ logmsg(">> %s", errbuf);
- errp = errbuf;
- }
- *(errp++) = ch;
-@@ -325,7 +322,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
- *mapp = '\0';
- if (errp > errbuf) {
- *errp = '\0';
-- error(ap->logopt, ">> %s", errbuf);
-+ logmsg(">> %s", errbuf);
- }
-
- close(pipefd[0]);
-@@ -333,12 +330,12 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
-
- if (waitpid(f, &status, 0) != f) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "waitpid: %s", estr);
-+ logerr(MODPREFIX "waitpid: %s", estr);
- goto out_free;
- }
-
- if (mapp == mapent || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
-- msg(MODPREFIX "lookup for %s failed", name);
-+ info(ap->logopt, MODPREFIX "lookup for %s failed", name);
- goto out_free;
- }
-
-diff --git a/modules/lookup_userhome.c b/modules/lookup_userhome.c
-index efcab0b..680ddaf 100644
---- a/modules/lookup_userhome.c
-+++ b/modules/lookup_userhome.c
-@@ -73,7 +73,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
- /* Create the appropriate symlink */
- if (chdir(ap->path)) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "chdir failed: %s", estr);
-+ logerr(MODPREFIX "chdir failed: %s", estr);
- return NSS_STATUS_UNAVAIL;
- }
-
-@@ -88,7 +88,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
-
- if (symlink(pw->pw_dir, name) && errno != EEXIST) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "symlink failed: %s", estr);
-+ logerr(MODPREFIX "symlink failed: %s", estr);
- return NSS_STATUS_UNAVAIL;
- }
-
-diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
-index da280cc..63fc8e3 100644
---- a/modules/lookup_yp.c
-+++ b/modules/lookup_yp.c
-@@ -45,12 +45,14 @@ struct lookup_context {
- struct callback_master_data {
- unsigned timeout;
- unsigned logging;
-+ unsigned logopt;
- time_t age;
- };
-
- struct callback_data {
- struct autofs_point *ap;
- struct map_source *source;
-+ unsigned logopt;
- time_t age;
- };
-
-@@ -111,20 +113,18 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "%s", estr);
-+ logerr(MODPREFIX "%s", estr);
- return 1;
- }
- memset(ctxt, 0, sizeof(struct lookup_context));
-
- if (argc < 1) {
- free(ctxt);
-- crit(LOGOPT_ANY, MODPREFIX "no map name");
-+ logerr(MODPREFIX "no map name");
- return 1;
- }
- ctxt->mapname = argv[0];
-
-- debug(LOGOPT_NONE, MODPREFIX "ctxt->mapname=%s", ctxt->mapname);
--
- /* This should, but doesn't, take a const char ** */
- err = yp_get_default_domain((char **) &ctxt->domainname);
- if (err) {
-@@ -133,8 +133,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- memcpy(name, ctxt->mapname, len);
- name[len] = '\0';
- free(ctxt);
-- debug(LOGOPT_NONE, MODPREFIX "map %s: %s", name,
-- yperr_string(err));
-+ logerr(MODPREFIX "map %s: %s", name, yperr_string(err));
- return 1;
- }
-
-@@ -146,7 +145,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
- if (!ctxt->parse) {
- free(ctxt);
-- crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
-+ logmsg(MODPREFIX "failed to open parse context");
- return 1;
- }
- *context = ctxt;
-@@ -161,6 +160,7 @@ int yp_all_master_callback(int status, char *ypkey, int ypkeylen,
- (struct callback_master_data *) ypcb_data;
- unsigned int timeout = cbdata->timeout;
- unsigned int logging = cbdata->logging;
-+ unsigned int logopt = cbdata->logopt;
- time_t age = cbdata->age;
- char *buffer;
- unsigned int len;
-@@ -182,7 +182,7 @@ int yp_all_master_callback(int status, char *ypkey, int ypkeylen,
-
- buffer = alloca(len);
- if (!buffer) {
-- error(LOGOPT_ANY, MODPREFIX "could not malloc parse buffer");
-+ error(logopt, MODPREFIX "could not malloc parse buffer");
- return 0;
- }
- memset(buffer, 0, len);
-@@ -201,6 +201,8 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- struct lookup_context *ctxt = (struct lookup_context *) context;
- struct ypall_callback ypcb;
- struct callback_master_data ypcb_data;
-+ unsigned int logging = master->default_logging;
-+ unsigned int logopt = master->logopt;
- char *mapname;
- int err;
-
-@@ -211,7 +213,8 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- strcpy(mapname, ctxt->mapname);
-
- ypcb_data.timeout = master->default_timeout;
-- ypcb_data.logging = master->default_logging;
-+ ypcb_data.logging = logging;
-+ ypcb_data.logopt = logopt;
- ypcb_data.age = age;
-
- ypcb.foreach = yp_all_master_callback;
-@@ -232,7 +235,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- if (err == YPERR_SUCCESS)
- return NSS_STATUS_SUCCESS;
-
-- warn(LOGOPT_ANY,
-+ info(logopt,
- MODPREFIX "read of master map %s failed: %s",
- mapname, yperr_string(err));
-
-@@ -249,6 +252,7 @@ int yp_all_callback(int status, char *ypkey, int ypkeylen,
- struct autofs_point *ap = cbdata->ap;
- struct map_source *source = cbdata->source;
- struct mapent_cache *mc = source->mc;
-+ unsigned int logopt = cbdata->logopt;
- time_t age = cbdata->age;
- char *key, *mapent;
- int ret;
-@@ -264,8 +268,10 @@ int yp_all_callback(int status, char *ypkey, int ypkeylen,
- return 0;
-
- key = sanitize_path(ypkey, ypkeylen, ap->type, ap->logopt);
-- if (!key)
-+ if (!key) {
-+ error(logopt, MODPREFIX "invalid path %s", ypkey);
- return 0;
-+ }
-
- mapent = alloca(vallen + 1);
- strncpy(mapent, val, vallen);
-@@ -288,6 +294,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
- struct lookup_context *ctxt = (struct lookup_context *) context;
- struct ypall_callback ypcb;
- struct callback_data ypcb_data;
-+ unsigned int logopt = ap->logopt;
- struct map_source *source;
- char *mapname;
- int err;
-@@ -298,6 +305,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
-
- ypcb_data.ap = ap;
- ypcb_data.source = source;
-+ ypcb_data.logopt = logopt;
- ypcb_data.age = age;
-
- ypcb.foreach = yp_all_callback;
-diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
-index c45b91b..356fb14 100644
---- a/modules/mount_autofs.c
-+++ b/modules/mount_autofs.c
-@@ -64,7 +64,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
- fullpath = alloca(strlen(root) + name_len + 2);
- if (!fullpath) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- return 1;
- }
-
-@@ -156,7 +156,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
- }
- nap = entry->ap;
- nap->parent = ap;
-- set_mnt_logging(nap);
-
- argc = 1;
-
-@@ -208,7 +207,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
- return 1;
- }
-
-- source->mc = cache_init(source);
-+ source->mc = cache_init(entry->ap, source);
- if (!source->mc) {
- error(ap->logopt, MODPREFIX "failed to init source cache");
- master_free_mapent(entry);
-diff --git a/modules/mount_bind.c b/modules/mount_bind.c
-index cb17ce4..04284f5 100644
---- a/modules/mount_bind.c
-+++ b/modules/mount_bind.c
-@@ -52,16 +52,14 @@ int mount_init(void **context)
- if (lstat(t1_dir, &st1) == -1)
- goto out;
-
-- err = spawn_mount(log_debug, "-n", "--bind", t1_dir, t2_dir, NULL);
-+ err = spawn_mount(LOGOPT_NONE, "-n", "--bind", t1_dir, t2_dir, NULL);
- if (err == 0 &&
- lstat(t2_dir, &st2) == 0 &&
- st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino) {
- bind_works = 1;
- }
-
-- debug(LOGOPT_NONE, MODPREFIX "bind_works = %d", bind_works);
--
-- spawn_umount(log_debug, "-n", t2_dir, NULL);
-+ spawn_umount(LOGOPT_NONE, "-n", t2_dir, NULL);
-
- out:
- rmdir(t1_dir);
-@@ -91,7 +89,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- fullpath = alloca(rlen + name_len + 2);
- if (!fullpath) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- return 1;
- }
-
-@@ -139,7 +137,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- "calling mount --bind " SLOPPY " -o %s %s %s",
- options, what, fullpath);
-
-- err = spawn_bind_mount(log_debug,
-+ err = spawn_bind_mount(ap->logopt,
- SLOPPYOPT "-o", options, what, fullpath, NULL);
-
- if (err) {
-diff --git a/modules/mount_changer.c b/modules/mount_changer.c
-index 6e04c7c..08d9147 100644
---- a/modules/mount_changer.c
-+++ b/modules/mount_changer.c
-@@ -66,7 +66,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- fullpath = alloca(rlen + name_len + 2);
- if (!fullpath) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- return 1;
- }
-
-@@ -80,7 +80,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
-
- debug(ap->logopt, MODPREFIX "calling umount %s", what);
-
-- err = spawn_umount(log_debug, what, NULL);
-+ err = spawn_umount(ap->logopt, what, NULL);
- if (err) {
- error(ap->logopt,
- MODPREFIX
-@@ -115,18 +115,18 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- MODPREFIX "calling mount -t %s " SLOPPY "-o %s %s %s",
- fstype, options, what, fullpath);
-
-- err = spawn_mount(log_debug, "-t", fstype,
-+ err = spawn_mount(ap->logopt, "-t", fstype,
- SLOPPYOPT "-o", options, what, fullpath, NULL);
- } else {
- debug(ap->logopt,
- MODPREFIX "calling mount -t %s %s %s",
- fstype, what, fullpath);
-
-- err = spawn_mount(log_debug, "-t", fstype, what, fullpath, NULL);
-+ err = spawn_mount(ap->logopt, "-t", fstype, what, fullpath, NULL);
- }
-
- if (err) {
-- msg(MODPREFIX "failed to mount %s (type %s) on %s",
-+ info(ap->logopt, MODPREFIX "failed to mount %s (type %s) on %s",
- what, fstype, fullpath);
-
- if (ap->type != LKP_INDIRECT)
-@@ -137,7 +137,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
-
- return 1;
- } else {
-- msg(MODPREFIX "mounted %s type %s on %s",
-+ info(ap->logopt, MODPREFIX "mounted %s type %s on %s",
- what, fstype, fullpath);
- return 0;
- }
-@@ -161,7 +161,7 @@ int swapCD(const char *device, const char *slotName)
- /* open device */
- fd = open(device, O_RDONLY | O_NONBLOCK);
- if (fd < 0) {
-- error(LOGOPT_ANY, MODPREFIX "Opening device %s failed : %s",
-+ logerr(MODPREFIX "Opening device %s failed : %s",
- device, strerror(errno));
- return 1;
- }
-@@ -174,7 +174,7 @@ int swapCD(const char *device, const char *slotName)
- /* Check CD player status */
- total_slots_available = ioctl(fd, CDROM_CHANGER_NSLOTS);
- if (total_slots_available <= 1) {
-- error(LOGOPT_ANY, MODPREFIX
-+ logerr(MODPREFIX
- "Device %s is not an ATAPI compliant CD changer.",
- device);
- return 1;
-@@ -183,14 +183,14 @@ int swapCD(const char *device, const char *slotName)
- /* load */
- slot = ioctl(fd, CDROM_SELECT_DISC, slot);
- if (slot < 0) {
-- error(LOGOPT_ANY, MODPREFIX "CDROM_SELECT_DISC failed");
-+ logerr(MODPREFIX "CDROM_SELECT_DISC failed");
- return 1;
- }
-
- /* close device */
- status = close(fd);
- if (status != 0) {
-- error(LOGOPT_ANY, MODPREFIX "close failed for `%s': %s",
-+ logerr(MODPREFIX "close failed for `%s': %s",
- device, strerror(errno));
- return 1;
- }
-diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c
-index 45f0615..8cf9937 100644
---- a/modules/mount_ext2.c
-+++ b/modules/mount_ext2.c
-@@ -58,7 +58,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- fullpath = alloca(rlen + name_len + 2);
- if (!fullpath) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- return 1;
- }
-
-@@ -108,11 +108,11 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- if (ro) {
- debug(ap->logopt,
- MODPREFIX "calling %s -n %s", fsck_prog, what);
-- err = spawnl(log_debug, fsck_prog, fsck_prog, "-n", what, NULL);
-+ err = spawnl(ap->logopt, fsck_prog, fsck_prog, "-n", what, NULL);
- } else {
- debug(ap->logopt,
- MODPREFIX "calling %s -p %s", fsck_prog, what);
-- err = spawnl(log_debug, fsck_prog, fsck_prog, "-p", what, NULL);
-+ err = spawnl(ap->logopt, fsck_prog, fsck_prog, "-p", what, NULL);
- }
-
- /*
-@@ -132,17 +132,17 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- debug(ap->logopt,
- MODPREFIX "calling mount -t %s " SLOPPY "-o %s %s %s",
- fstype, options, what, fullpath);
-- err = spawn_mount(log_debug, "-t", fstype,
-+ err = spawn_mount(ap->logopt, "-t", fstype,
- SLOPPYOPT "-o", options, what, fullpath, NULL);
- } else {
- debug(ap->logopt,
- MODPREFIX "calling mount -t %s %s %s",
- fstype, what, fullpath);
-- err = spawn_mount(log_debug, "-t", fstype, what, fullpath, NULL);
-+ err = spawn_mount(ap->logopt, "-t", fstype, what, fullpath, NULL);
- }
-
- if (err) {
-- msg(MODPREFIX "failed to mount %s (type %s) on %s",
-+ info(ap->logopt, MODPREFIX "failed to mount %s (type %s) on %s",
- what, fstype, fullpath);
-
- if (ap->type != LKP_INDIRECT)
-@@ -153,7 +153,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
-
- return 1;
- } else {
-- debug(ap->logopt,
-+ info(ap->logopt,
- MODPREFIX "mounted %s type %s on %s",
- what, fstype, fullpath);
- return 0;
-diff --git a/modules/mount_generic.c b/modules/mount_generic.c
-index 1f43baa..85b4391 100644
---- a/modules/mount_generic.c
-+++ b/modules/mount_generic.c
-@@ -57,7 +57,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- fullpath = alloca(rlen + name_len + 2);
- if (!fullpath) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- return 1;
- }
-
-@@ -93,16 +93,16 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- MODPREFIX "calling mount -t %s " SLOPPY "-o %s %s %s",
- fstype, options, what, fullpath);
-
-- err = spawn_mount(log_debug, "-t", fstype,
-+ err = spawn_mount(ap->logopt, "-t", fstype,
- SLOPPYOPT "-o", options, what, fullpath, NULL);
- } else {
- debug(ap->logopt, MODPREFIX "calling mount -t %s %s %s",
- fstype, what, fullpath);
-- err = spawn_mount(log_debug, "-t", fstype, what, fullpath, NULL);
-+ err = spawn_mount(ap->logopt, "-t", fstype, what, fullpath, NULL);
- }
-
- if (err) {
-- msg(MODPREFIX "failed to mount %s (type %s) on %s",
-+ info(ap->logopt, MODPREFIX "failed to mount %s (type %s) on %s",
- what, fstype, fullpath);
-
- if (ap->type != LKP_INDIRECT)
-@@ -113,7 +113,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
-
- return 1;
- } else {
-- msg(MODPREFIX "mounted %s type %s on %s",
-+ info(ap->logopt, MODPREFIX "mounted %s type %s on %s",
- what, fstype, fullpath);
- return 0;
- }
-diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
-index e4480c5..bad21fc 100644
---- a/modules/mount_nfs.c
-+++ b/modules/mount_nfs.c
-@@ -133,14 +133,14 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- else
- vers = NFS_VERS_MASK | NFS_PROTO_MASK;
-
-- if (!parse_location(&hosts, what)) {
-- warn(ap->logopt, MODPREFIX "no hosts available");
-+ if (!parse_location(ap->logopt, &hosts, what)) {
-+ info(ap->logopt, MODPREFIX "no hosts available");
- return 1;
- }
-- prune_host_list(&hosts, vers, nfsoptions, ap->random_selection);
-+ prune_host_list(ap->logopt, &hosts, vers, nfsoptions, ap->random_selection);
-
- if (!hosts) {
-- warn(ap->logopt, MODPREFIX "no hosts available");
-+ info(ap->logopt, MODPREFIX "no hosts available");
- return 1;
- }
-
-@@ -159,7 +159,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- fullpath = alloca(rlen + name_len + 2);
- if (!fullpath) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- free_host_list(&hosts);
- return 1;
- }
-@@ -252,19 +252,19 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- MODPREFIX "calling mount -t %s " SLOPPY
- "-o %s %s %s", fstype, nfsoptions, loc, fullpath);
-
-- err = spawn_mount(log_debug,
-+ err = spawn_mount(ap->logopt,
- "-t", fstype, SLOPPYOPT "-o",
- nfsoptions, loc, fullpath, NULL);
- } else {
- debug(ap->logopt,
- MODPREFIX "calling mount -t %s %s %s",
- fstype, loc, fullpath);
-- err = spawn_mount(log_debug,
-+ err = spawn_mount(ap->logopt,
- "-t", fstype, loc, fullpath, NULL);
- }
-
- if (!err) {
-- msg(MODPREFIX "mounted %s on %s", loc, fullpath);
-+ info(ap->logopt, MODPREFIX "mounted %s on %s", loc, fullpath);
- free(loc);
- free_host_list(&hosts);
- ap->ghost = save_ghost;
-@@ -280,7 +280,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
-
- /* If we get here we've failed to complete the mount */
-
-- msg(MODPREFIX "nfs: mount failure %s on %s", what, fullpath);
-+ info(ap->logopt, MODPREFIX "nfs: mount failure %s on %s", what, fullpath);
-
- if (ap->type != LKP_INDIRECT)
- return 1;
-diff --git a/modules/parse_sun.c b/modules/parse_sun.c
-index 079bda6..186e567 100644
---- a/modules/parse_sun.c
-+++ b/modules/parse_sun.c
-@@ -277,7 +277,7 @@ int parse_init(int argc, const char *const *argv, void **context)
-
- if (!(ctxt = (struct parse_context *) malloc(sizeof(struct parse_context)))) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- *context = NULL;
- return 1;
- }
-@@ -302,7 +302,7 @@ int parse_init(int argc, const char *const *argv, void **context)
-
- if (!def) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(LOGOPT_ANY, MODPREFIX "strdup: %s", estr);
-+ logerr(MODPREFIX "strdup: %s", estr);
- break;
- }
-
-@@ -387,7 +387,7 @@ int parse_init(int argc, const char *const *argv, void **context)
- if (!noptstr) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- kill_context(ctxt);
-- crit(LOGOPT_ANY, MODPREFIX "%s", estr);
-+ logerr(MODPREFIX "%s", estr);
- *context = NULL;
- return 1;
- }
-@@ -408,7 +408,7 @@ int parse_init(int argc, const char *const *argv, void **context)
- char *tmp = concat_options(gbl_options, ctxt->optstr);
- if (!tmp) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(LOGOPT_ANY, MODPREFIX "concat_options: %s", estr);
-+ logerr(MODPREFIX "concat_options: %s", estr);
- free(gbl_options);
- } else
- ctxt->optstr = tmp;
-@@ -472,7 +472,7 @@ static char *concat_options(char *left, char *right)
-
- if (ret == NULL) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
-+ logerr(MODPREFIX "malloc: %s", estr);
- return NULL;
- }
-
-@@ -637,8 +637,7 @@ static int check_is_multi(const char *mapent)
- int not_first_chunk = 0;
-
- if (!p) {
-- crit(LOGOPT_ANY,
-- MODPREFIX "unexpected NULL map entry pointer");
-+ logerr(MODPREFIX "unexpected NULL map entry pointer");
- return 0;
- }
-
-@@ -1021,7 +1020,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
- pmapent = alloca(mapent_len + 1);
- if (!pmapent) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- ctxt->subst = removestdenv(ctxt->subst);
- macro_unlock();
- pthread_setcancelstate(cur_state, NULL);
-@@ -1041,7 +1040,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
- options = strdup(ctxt->optstr ? ctxt->optstr : "");
- if (!options) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(ap->logopt, MODPREFIX "strdup: %s", estr);
-+ logerr(MODPREFIX "strdup: %s", estr);
- return 1;
- }
- optlen = strlen(options);
-@@ -1119,7 +1118,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
- if (!m_root) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- free(options);
-- error(ap->logopt, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- return 1;
- }
- strcpy(m_root, name);
-@@ -1129,7 +1128,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
- if (!m_root) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- free(options);
-- error(ap->logopt, MODPREFIX "alloca: %s", estr);
-+ logerr(MODPREFIX "alloca: %s", estr);
- return 1;
- }
- strcpy(m_root, ap->path);
-diff --git a/modules/replicated.c b/modules/replicated.c
-index e15587c..14b20a9 100644
---- a/modules/replicated.c
-+++ b/modules/replicated.c
-@@ -113,7 +113,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
- 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);
-+ logerr("socket creation failed: %s", estr);
- return PROXIMITY_ERROR;
- }
-
-@@ -127,7 +127,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
- ret = ioctl(sock, SIOCGIFCONF, &ifc);
- if (ret == -1) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(LOGOPT_ANY, "ioctl: %s", estr);
-+ logerr("ioctl: %s", estr);
- close(sock);
- return PROXIMITY_ERROR;
- }
-@@ -176,7 +176,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
- ret = ioctl(sock, SIOCGIFNETMASK, &nmptr);
- if (ret == -1) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-- error(LOGOPT_ANY, "ioctl: %s", estr);
-+ logerr("ioctl: %s", estr);
- close(sock);
- return PROXIMITY_ERROR;
- }
-@@ -387,7 +387,7 @@ static unsigned short get_port_option(const char *options)
- return (unsigned short) port;
- }
-
--static unsigned int get_nfs_info(struct host *host,
-+static unsigned int get_nfs_info(unsigned logopt, struct host *host,
- struct conn_info *pm_info, struct conn_info *rpc_info,
- const char *proto, unsigned int version,
- const char *options, unsigned int random_selection)
-@@ -533,7 +533,7 @@ done_ver:
- return supported;
- }
-
--static int get_vers_and_cost(struct host *host,
-+static int get_vers_and_cost(unsigned logopt, struct host *host,
- unsigned int version, const char *options,
- unsigned int random_selection)
- {
-@@ -559,7 +559,7 @@ static int get_vers_and_cost(struct host *host,
- vers &= version;
-
- if (version & UDP_REQUESTED) {
-- supported = get_nfs_info(host,
-+ supported = get_nfs_info(logopt, host,
- &pm_info, &rpc_info, "udp", vers,
- options, random_selection);
- if (supported) {
-@@ -569,7 +569,7 @@ static int get_vers_and_cost(struct host *host,
- }
-
- if (version & TCP_REQUESTED) {
-- supported = get_nfs_info(host,
-+ supported = get_nfs_info(logopt, host,
- &pm_info, &rpc_info, "tcp", vers,
- options, random_selection);
- if (supported) {
-@@ -581,7 +581,7 @@ static int get_vers_and_cost(struct host *host,
- return ret;
- }
-
--static int get_supported_ver_and_cost(struct host *host,
-+static int get_supported_ver_and_cost(unsigned logopt, struct host *host,
- unsigned int version, const char *options,
- unsigned int random_selection)
- {
-@@ -636,7 +636,7 @@ static int get_supported_ver_and_cost(struct host *host,
- vers = NFS4_VERSION;
- break;
- default:
-- crit(LOGOPT_ANY, "called with invalid version: 0x%x\n", version);
-+ crit(logopt, "called with invalid version: 0x%x\n", version);
- return 0;
- }
-
-@@ -701,7 +701,7 @@ done:
- return 0;
- }
-
--int prune_host_list(struct host **list,
-+int prune_host_list(unsigned logopt, struct host **list,
- unsigned int vers, const char *options,
- unsigned int random_selection)
- {
-@@ -742,7 +742,7 @@ int prune_host_list(struct host **list,
- break;
-
- if (this->name) {
-- status = get_vers_and_cost(this, vers,
-+ status = get_vers_and_cost(logopt, this, vers,
- options, random_selection);
- if (!status) {
- if (this == first) {
-@@ -833,7 +833,7 @@ int prune_host_list(struct host **list,
- remove_host(list, this);
- add_host(&new, this);
- } else {
-- status = get_supported_ver_and_cost(this,
-+ status = get_supported_ver_and_cost(logopt, this,
- selected_version, options,
- random_selection);
- if (status) {
-@@ -886,11 +886,9 @@ static int add_host_addrs(struct host **list, const char *host, unsigned int wei
- buf, MAX_IFC_BUF, &result, &ghn_errno);
- if (ret || !result) {
- if (ghn_errno == -1)
-- error(LOGOPT_ANY,
-- "host %s: lookup failure %d", host, errno);
-+ logmsg("host %s: lookup failure %d", host, errno);
- else
-- error(LOGOPT_ANY,
-- "host %s: lookup failure %d", host, ghn_errno);
-+ logmsg("host %s: lookup failure %d", host, ghn_errno);
- return 0;
- }
-
-@@ -965,7 +963,7 @@ static int add_local_path(struct host **hosts, const char *path)
- return 1;
- }
-
--int parse_location(struct host **hosts, const char *list)
-+int parse_location(unsigned logopt, struct host **hosts, const char *list)
- {
- char *str, *p, *delim;
- unsigned int empty = 1;
-@@ -1072,8 +1070,7 @@ void dump_host_list(struct host *hosts)
-
- this = hosts;
- while (this) {
-- debug(LOGOPT_ANY,
-- "name %s path %s version %x proximity %u weight %u cost %u",
-+ logmsg("name %s path %s version %x proximity %u weight %u cost %u",
- this->name, this->path, this->version,
- this->proximity, this->weight, this->cost);
- this = this->next;
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 85af0ad..fcfbe62 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -50,6 +50,7 @@
- - fix off-by-one error for lookup of map keys exactly 255 characters long.
- - improve handling of server not available.
- - fix LDAP_URI server selection.
-+- add authentication option for using an external credential cache.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
-index 5b5c475..d6a754d 100644
---- a/include/lookup_ldap.h
-+++ b/include/lookup_ldap.h
-@@ -67,10 +67,10 @@ struct lookup_context {
- char *user;
- char *secret;
- char *client_princ;
-+ char *client_cc;
- int kinit_done;
- int kinit_successful;
- #ifdef WITH_SASL
-- krb5_principal krb5_client_princ;
- krb5_context krb5ctxt;
- krb5_ccache krb5_ccache;
- sasl_conn_t *sasl_conn;
-diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
-index 303b7f2..f24f46b 100644
---- a/modules/cyrus-sasl.c
-+++ b/modules/cyrus-sasl.c
-@@ -72,6 +72,7 @@
- */
- static const char *krb5ccenv = "KRB5CCNAME";
- static const char *krb5ccval = "MEMORY:_autofstkt";
-+static const char *default_client = "autofsclient";
- static pthread_mutex_t krb5cc_mutex = PTHREAD_MUTEX_INITIALIZER;
- static unsigned int krb5cc_in_use = 0;
-
-@@ -376,7 +377,7 @@ int
- sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
- {
- krb5_error_code ret;
-- krb5_principal tgs_princ, krb5_client_princ = ctxt->krb5_client_princ;
-+ krb5_principal tgs_princ, krb5_client_princ;
- krb5_creds my_creds;
- char *tgs_name;
- int status;
-@@ -386,8 +387,8 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
- ctxt->kinit_done = 1;
-
- debug(logopt,
-- "initializing kerberos ticket: client principal %s ",
-- ctxt->client_princ ? ctxt->client_princ : "autofsclient");
-+ "initializing kerberos ticket: client principal %s",
-+ ctxt->client_princ ? ctxt->client_princ : default_client);
-
- ret = krb5_init_context(&ctxt->krb5ctxt);
- if (ret) {
-@@ -424,13 +425,12 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
- "calling krb5_sname_to_principal using defaults");
-
- ret = krb5_sname_to_principal(ctxt->krb5ctxt, NULL,
-- "autofsclient", KRB5_NT_SRV_HST,
-+ default_client, KRB5_NT_SRV_HST,
- &krb5_client_princ);
- if (ret) {
- error(logopt,
- "krb5_sname_to_principal failed for "
-- "%s with error %d",
-- ctxt->client_princ ? "" : "autofsclient", ret);
-+ "%s with error %d", default_client, ret);
- goto out_cleanup_cc;
- }
-
-@@ -441,11 +441,11 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
- debug(logopt,
- "krb5_unparse_name failed with error %d",
- ret);
-- goto out_cleanup_cc;
-+ goto out_cleanup_client_princ;
- }
-
- debug(logopt,
-- "principal used for authentication: \"%s\"", tmp_name);
-+ "principal used for authentication: %s", tmp_name);
-
- krb5_free_unparsed_name(ctxt->krb5ctxt, tmp_name);
- }
-@@ -461,14 +461,14 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
- if (ret) {
- error(logopt,
- "krb5_build_principal failed with error %d", ret);
-- goto out_cleanup_cc;
-+ goto out_cleanup_client_princ;
- }
-
- ret = krb5_unparse_name(ctxt->krb5ctxt, tgs_princ, &tgs_name);
- if (ret) {
- error(logopt, "krb5_unparse_name failed with error %d",
- ret);
-- goto out_cleanup_cc;
-+ goto out_cleanup_client_princ;
- }
-
- debug(logopt, "Using tgs name %s", tgs_name);
-@@ -486,7 +486,6 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
- goto out_cleanup_unparse;
- }
-
--
- status = pthread_mutex_lock(&krb5cc_mutex);
- if (status)
- fatal(status);
-@@ -503,7 +502,7 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
- if (ret) {
- error(logopt,
- "krb5_cc_initialize failed with error %d", ret);
-- goto out_cleanup_unparse;
-+ goto out_cleanup_creds;
- }
-
- /* and store credentials for that principal */
-@@ -511,26 +510,34 @@ sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt)
- if (ret) {
- error(logopt,
- "krb5_cc_store_cred failed with error %d", ret);
-- goto out_cleanup_unparse;
-+ goto out_cleanup_creds;
- }
-
- /* finally, set the environment variable to point to our
- * credentials cache */
- if (setenv(krb5ccenv, krb5ccval, 1) != 0) {
- error(logopt, "setenv failed with %d", errno);
-- goto out_cleanup_unparse;
-+ goto out_cleanup_creds;
- }
- ctxt->kinit_successful = 1;
-
- debug(logopt, "Kerberos authentication was successful!");
-
- krb5_free_unparsed_name(ctxt->krb5ctxt, tgs_name);
-+ krb5_free_cred_contents(ctxt->krb5ctxt, &my_creds);
-+ krb5_free_principal(ctxt->krb5ctxt, tgs_princ);
-+ krb5_free_principal(ctxt->krb5ctxt, krb5_client_princ);
-
- return 0;
-
--out_cleanup_unparse:
-+out_cleanup_creds:
- krb5cc_in_use--;
-+ krb5_free_cred_contents(ctxt->krb5ctxt, &my_creds);
-+out_cleanup_unparse:
-+ krb5_free_principal(ctxt->krb5ctxt, tgs_princ);
- krb5_free_unparsed_name(ctxt->krb5ctxt, tgs_name);
-+out_cleanup_client_princ:
-+ krb5_free_principal(ctxt->krb5ctxt, krb5_client_princ);
- out_cleanup_cc:
- status = pthread_mutex_lock(&krb5cc_mutex);
- if (status)
-@@ -554,6 +561,152 @@ out_cleanup_cc:
- }
-
- /*
-+ * Check a client given external credential cache.
-+ *
-+ * Returns 0 upon success. ctxt->kinit_done and ctxt->kinit_successful
-+ * are set for cleanup purposes. The krb5 context and ccache entries in
-+ * the lookup_context are also filled in.
-+ *
-+ * Upon failure, -1 is returned.
-+ */
-+int
-+sasl_do_kinit_ext_cc(unsigned logopt, struct lookup_context *ctxt)
-+{
-+ krb5_principal def_princ;
-+ krb5_principal krb5_client_princ;
-+ krb5_error_code ret;
-+ char *cc_princ, *client_princ;
-+
-+ if (ctxt->kinit_done)
-+ return 0;
-+ ctxt->kinit_done = 1;
-+
-+ debug(logopt,
-+ "using external credential cache for auth: client principal %s",
-+ ctxt->client_princ ? ctxt->client_princ : default_client);
-+
-+ ret = krb5_init_context(&ctxt->krb5ctxt);
-+ if (ret) {
-+ error(logopt, "krb5_init_context failed with %d", ret);
-+ return -1;
-+ }
-+
-+ ret = krb5_cc_resolve(ctxt->krb5ctxt, ctxt->client_cc, &ctxt->krb5_ccache);
-+ if (ret) {
-+ error(logopt, "krb5_cc_resolve failed with error %d",
-+ ret);
-+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
-+ krb5_free_context(ctxt->krb5ctxt);
-+ return -1;
-+ }
-+
-+ ret = krb5_cc_get_principal(ctxt->krb5ctxt, ctxt->krb5_ccache, &def_princ);
-+ if (ret) {
-+ error(logopt, "krb5_cc_get_principal failed with error %d", ret);
-+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
-+ krb5_free_context(ctxt->krb5ctxt);
-+ return -1;
-+ }
-+
-+ ret = krb5_unparse_name(ctxt->krb5ctxt, def_princ, &cc_princ);
-+ if (ret) {
-+ error(logopt, "krb5_unparse_name failed with error %d", ret);
-+ krb5_free_principal(ctxt->krb5ctxt, def_princ);
-+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
-+ krb5_free_context(ctxt->krb5ctxt);
-+ return -1;
-+ }
-+
-+ debug(logopt, "external credential cache default principal %s", cc_princ);
-+
-+ /*
-+ * If the principal isn't set in the config construct the default
-+ * so we can check against the default principal of the external
-+ * cred cache.
-+ */
-+ if (ctxt->client_princ)
-+ client_princ = ctxt->client_princ;
-+ else {
-+ debug(logopt,
-+ "calling krb5_sname_to_principal using defaults");
-+
-+ ret = krb5_sname_to_principal(ctxt->krb5ctxt, NULL,
-+ default_client, KRB5_NT_SRV_HST,
-+ &krb5_client_princ);
-+ if (ret) {
-+ error(logopt,
-+ "krb5_sname_to_principal failed for "
-+ "%s with error %d", default_client, ret);
-+ krb5_free_principal(ctxt->krb5ctxt, def_princ);
-+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
-+ krb5_free_context(ctxt->krb5ctxt);
-+ return -1;
-+ }
-+
-+
-+ ret = krb5_unparse_name(ctxt->krb5ctxt,
-+ krb5_client_princ, &client_princ);
-+ if (ret) {
-+ debug(logopt,
-+ "krb5_unparse_name failed with error %d",
-+ ret);
-+ krb5_free_principal(ctxt->krb5ctxt, krb5_client_princ);
-+ krb5_free_principal(ctxt->krb5ctxt, def_princ);
-+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
-+ krb5_free_context(ctxt->krb5ctxt);
-+ return -1;
-+ }
-+
-+ debug(logopt,
-+ "principal used for authentication: %s", client_princ);
-+
-+ krb5_free_principal(ctxt->krb5ctxt, krb5_client_princ);
-+ }
-+
-+ /*
-+ * Check if the principal to be used matches the default principal in
-+ * the external cred cache.
-+ */
-+ if (strcmp(cc_princ, client_princ)) {
-+ error(logopt,
-+ "configured client principal %s ",
-+ ctxt->client_princ);
-+ error(logopt,
-+ "external credential cache default principal %s",
-+ cc_princ);
-+ error(logopt,
-+ "cannot use credential cache, external "
-+ "default principal does not match configured "
-+ "principal");
-+ if (!ctxt->client_princ)
-+ krb5_free_unparsed_name(ctxt->krb5ctxt, client_princ);
-+ krb5_free_unparsed_name(ctxt->krb5ctxt, cc_princ);
-+ krb5_free_principal(ctxt->krb5ctxt, def_princ);
-+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
-+ krb5_free_context(ctxt->krb5ctxt);
-+ return -1;
-+ }
-+
-+ if (!ctxt->client_princ)
-+ krb5_free_unparsed_name(ctxt->krb5ctxt, client_princ);
-+ krb5_free_unparsed_name(ctxt->krb5ctxt, cc_princ);
-+ krb5_free_principal(ctxt->krb5ctxt, def_princ);
-+
-+ /* Set the environment variable to point to the external cred cache */
-+ if (setenv(krb5ccenv, ctxt->client_cc, 1) != 0) {
-+ error(logopt, "setenv failed with %d", errno);
-+ krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
-+ krb5_free_context(ctxt->krb5ctxt);
-+ return -1;
-+ }
-+ ctxt->kinit_successful = 1;
-+
-+ debug(logopt, "Kerberos authentication was successful!");
-+
-+ return 0;
-+}
-+
-+/*
- * Attempt to bind to the ldap server using a given authentication
- * mechanism. ldap should be a properly initialzed ldap pointer.
- *
-@@ -570,7 +723,11 @@ sasl_bind_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const c
- int result;
-
- if (!strncmp(mech, "GSSAPI", 6)) {
-- if (sasl_do_kinit(logopt, ctxt) != 0)
-+ if (ctxt->client_cc)
-+ result = sasl_do_kinit_ext_cc(logopt, ctxt);
-+ else
-+ result = sasl_do_kinit(logopt, ctxt);
-+ if (result != 0)
- return NULL;
- }
-
-@@ -774,7 +931,7 @@ autofs_sasl_done(struct lookup_context *ctxt)
- if (status)
- fatal(status);
-
-- if (--krb5cc_in_use)
-+ if (--krb5cc_in_use || ctxt->client_cc)
- ret = krb5_cc_close(ctxt->krb5ctxt, ctxt->krb5_ccache);
- else
- ret = krb5_cc_destroy(ctxt->krb5ctxt, ctxt->krb5_ccache);
-diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index 93f0477..13fbff7 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -651,7 +651,7 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
- xmlNodePtr root = NULL;
- char *authrequired, *auth_conf, *authtype;
- char *user = NULL, *secret = NULL;
-- char *client_princ = NULL;
-+ char *client_princ = NULL, *client_cc = NULL;
- char *usetls, *tlsrequired;
-
- authtype = user = secret = NULL;
-@@ -840,6 +840,7 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
- * client. The default is "autofsclient/hostname@REALM".
- */
- (void)get_property(logopt, root, "clientprinc", &client_princ);
-+ (void)get_property(logopt, root, "credentialcache", &client_cc);
-
- ctxt->auth_conf = auth_conf;
- ctxt->use_tls = use_tls;
-@@ -851,6 +852,7 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
- ctxt->user = user;
- ctxt->secret = secret;
- ctxt->client_princ = client_princ;
-+ ctxt->client_cc = client_cc;
-
- debug(logopt, MODPREFIX
- "ldap authentication configured with the following options:");
-@@ -863,9 +865,10 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
- debug(logopt, MODPREFIX
- "user: %s, "
- "secret: %s, "
-- "client principal: %s",
-+ "client principal: %s "
-+ "credential cache: %s",
- user, secret ? "specified" : "unspecified",
-- client_princ);
-+ client_princ, client_cc);
-
- out:
- xmlFreeDoc(doc);
-@@ -1128,6 +1131,8 @@ static void free_context(struct lookup_context *ctxt)
- free(ctxt->secret);
- if (ctxt->client_princ)
- free(ctxt->client_princ);
-+ if (ctxt->client_cc)
-+ free(ctxt->client_cc);
- if (ctxt->mapname)
- free(ctxt->mapname);
- if (ctxt->qdn)
-diff --git a/samples/autofs_ldap_auth.conf b/samples/autofs_ldap_auth.conf
-index e10d1ea..a1f60c0 100644
---- a/samples/autofs_ldap_auth.conf
-+++ b/samples/autofs_ldap_auth.conf
-@@ -56,6 +56,11 @@ clientprinc - When using GSSAPI authentication, this attribute is
- consulted to determine the principal name to use when
- authenticating to the directory server. By default, this will
- be set to "autofsclient/<fqdn>@<REALM>.
-+
-+credentialcache - When using GSSAPI authentication, this attribute
-+ can be used to specify an externally configured credential
-+ cache that is used during authentication. By default, autofs
-+ will setup a memory based credential cache.
- -->
-
- <autofs_ldap_sasl_conf
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 1bf4b27..678e764 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -10,6 +10,7 @@
- - add quoting for exports gathered by hosts map.
- - fix wait time resolution in alarm and state queue handlers.
- - fix handling of quoted slash alone.
-+- fix parse confusion between attribute and attribute value.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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;
- }
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 98d082c..20562bd 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -13,6 +13,7 @@
- - fix parse confusion between attribute and attribute value.
- - fix version passed to get_supported_ver_and_cost.
- - mark map instances stale so they aren't "cleaned" during updates.
-+- fix large file compile time option.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index c6ab15f..5aee44c 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -16,6 +16,7 @@
- - fix large file compile time option.
- - don't fail on empty master map.
- - add support for the "%" hack for case insensitive attribute schemas.
-+- fix "nosymlink" option handling and add desription to man page.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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" : "";
-
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 678e764..aa5d1c1 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -11,6 +11,7 @@
- - fix wait time resolution in alarm and state queue handlers.
- - fix handling of quoted slash alone.
- - fix parse confusion between attribute and attribute value.
-+- fix version passed to get_supported_ver_and_cost.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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);
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 9312ad5..6379d18 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -47,6 +47,7 @@
- - fix for dynamic logging breaking non-sasl build (Guillaume Rousse)
- - eliminate NULL proc ping for singleton host or local mounts.
- - fix incorrect read/write size of startup status token (Matthias Koenig).
-+- fix off-by-one error for lookup of map keys exactly 255 characters long.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/modules/lookup_file.c b/modules/lookup_file.c
-index 23ea07d..550bf5c 100644
---- a/modules/lookup_file.c
-+++ b/modules/lookup_file.c
-@@ -1047,7 +1047,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
-
- debug(ap->logopt, MODPREFIX "looking up %s", name);
-
-- key_len = snprintf(key, KEY_MAX_LEN, "%s", name);
-+ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name);
- if (key_len > KEY_MAX_LEN)
- return NSS_STATUS_NOTFOUND;
-
-diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index 93a1b40..b8484a2 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -2053,7 +2053,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
-
- debug(ap->logopt, MODPREFIX "looking up %s", name);
-
-- key_len = snprintf(key, KEY_MAX_LEN, "%s", name);
-+ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name);
- if (key_len > KEY_MAX_LEN)
- return NSS_STATUS_NOTFOUND;
-
-diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
-index bb1ca42..fee8b16 100644
---- a/modules/lookup_nisplus.c
-+++ b/modules/lookup_nisplus.c
-@@ -476,7 +476,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
-
- debug(ap->logopt, MODPREFIX "looking up %s", name);
-
-- key_len = snprintf(key, KEY_MAX_LEN, "%s", name);
-+ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name);
- if (key_len > KEY_MAX_LEN)
- return NSS_STATUS_NOTFOUND;
-
-diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
-index e8ca8e8..5f4f95f 100644
---- a/modules/lookup_yp.c
-+++ b/modules/lookup_yp.c
-@@ -567,7 +567,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
-
- debug(ap->logopt, MODPREFIX "looking up %s", name);
-
-- key_len = snprintf(key, KEY_MAX_LEN, "%s", name);
-+ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name);
- if (key_len > KEY_MAX_LEN)
- return NSS_STATUS_NOTFOUND;
-
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 8df22ae..2ce58b4 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -6,6 +6,7 @@
- - add multi nsswitch lookup.
- - change random multiple server selection option name to be consistent
- with existing downstream version 4 naming.
-+- fix mount point directory creation for bind mounts.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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++;
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index a7ac9fb..93c79cf 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -36,6 +36,7 @@
- - fix map entry expansion when undefined macro is present.
- - remove unused export validation code.
- - add dynamic logging (adapted from v4 patch from Jeff Moyer).
-+- fix recursive loopback mounts (Matthias Koenig).
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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--) {
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 933b1a1..0340940 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -28,6 +28,7 @@
- - work around segv at exit due to libxml2 tsd usage.
- - re-read config on HUP signal.
- - add LDAP_URI, LDAP_TIMEOUT and LDAP_NETWORK_TIMEOUT configuration options.
-+- fix forground logging and add option to man page.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/daemon/automount.c b/daemon/automount.c
-index 58f1901..51f6a8b 100644
---- a/daemon/automount.c
-+++ b/daemon/automount.c
-@@ -58,14 +58,13 @@ unsigned int global_random_selection; /* use random policy when selecting
- 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 foreground)
- {
- 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 foreground)
- }
-
- /* 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 foreground)
- 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 master *master, int sig)
- 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");
-@@ -1045,7 +1037,6 @@ 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;
-
-@@ -1058,15 +1049,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:
-@@ -1181,6 +1169,10 @@ 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))
-+ pthread_kill(state_mach_thid, SIGTERM);
-+
- return;
- }
-
-@@ -1375,7 +1367,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"
-@@ -1650,14 +1642,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",
-@@ -1702,6 +1686,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 --git a/lib/log.c b/lib/log.c
-index e639e60..b747e12 100644
---- a/lib/log.c
-+++ b/lib/log.c
-@@ -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 logopt, const char *msg, ...)
- 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 --git a/lib/master.c b/lib/master.c
-index 637ce04..abc3bc2 100644
---- a/lib/master.c
-+++ b/lib/master.c
-@@ -954,6 +954,7 @@ void master_notify_state_change(struct master *master, int sig)
-
- switch (sig) {
- case SIGTERM:
-+ case SIGINT:
- if (ap->state != ST_SHUTDOWN_PENDING &&
- ap->state != ST_SHUTDOWN_FORCE) {
- next = ST_SHUTDOWN_PENDING;
-diff --git a/man/automount.8 b/man/automount.8
-index da67a5c..e203a3e 100644
---- a/man/automount.8
-+++ b/man/automount.8
-@@ -47,6 +47,9 @@ Define a global macro substitution variable. Global definitions
- 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.
-diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
-index 9aac792..68e5dd7 100644
---- a/modules/cyrus-sasl.c
-+++ b/modules/cyrus-sasl.c
-@@ -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 --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index 4068561..c0f228b 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -857,17 +857,17 @@ int parse_ldap_config(struct lookup_context *ctxt)
- 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);
-
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 903e619..bc4d8fd 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -8,6 +8,7 @@
- with existing downstream version 4 naming.
- - fix mount point directory creation for bind mounts.
- - add quoting for exports gathered by hosts map.
-+- fix wait time resolution in alarm and state queue handlers.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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)
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index c486a7b..0fcdfd4 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -53,6 +53,7 @@
- - add authentication option for using an external credential cache.
- - expand support for the "%" hack.
- - fix to quoting for exports gathered by hosts map.
-+- use mount option "nosuid" for "-hosts" map unless "suid" is explicily specified.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 09b0541..d8a6987 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -56,6 +56,7 @@
- - use mount option "nosuid" for "-hosts" map unless "suid" is explicily specified.
- - second attempt fixing quoting for exports gathered by hosts map.
- - quell annoying "cannot open mount module" message.
-+- fix for improve handling of server not available.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/modules/lookup_file.c b/modules/lookup_file.c
-index a77068a..ab2dd0f 100644
---- a/modules/lookup_file.c
-+++ b/modules/lookup_file.c
-@@ -474,8 +474,12 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- MODPREFIX
- "failed to read included master map %s",
- master->name);
-- fclose(f);
-- return NSS_STATUS_UNAVAIL;
-+ if (!master->recurse) {
-+ master->depth--;
-+ master->recurse = 0;
-+ fclose(f);
-+ return NSS_STATUS_UNAVAIL;
-+ }
- }
- master->depth--;
- master->recurse = 0;
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 6379d18..a9e509d 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -48,6 +48,7 @@
- - eliminate NULL proc ping for singleton host or local mounts.
- - fix incorrect read/write size of startup status token (Matthias Koenig).
- - fix off-by-one error for lookup of map keys exactly 255 characters long.
-+- improve handling of server not available.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/daemon/lookup.c b/daemon/lookup.c
-index 0be10d3..eb72411 100644
---- a/daemon/lookup.c
-+++ b/daemon/lookup.c
-@@ -298,8 +298,6 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a
-
- status = lookup->lookup_read_map(ap, age, lookup->context);
-
-- map->stale = 0;
--
- /*
- * For maps that don't support enumeration return success
- * and do whatever we must to have autofs function with an
-@@ -533,6 +531,10 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time
- if (result == NSS_STATUS_UNKNOWN)
- continue;
-
-+ /* Don't try to update the map cache if it's unavailable */
-+ if (result == NSS_STATUS_UNAVAIL)
-+ map->stale = 0;
-+
- if (result == NSS_STATUS_SUCCESS) {
- at_least_one = 1;
- result = NSS_STATUS_TRYAGAIN;
-@@ -553,7 +555,7 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time
- }
- pthread_cleanup_pop(1);
-
-- if (!result || at_least_one)
-+ if (!result || at_least_one)
- return 1;
-
- return 0;
-diff --git a/daemon/state.c b/daemon/state.c
-index cf07aac..5bccfef 100644
---- a/daemon/state.c
-+++ b/daemon/state.c
-@@ -432,6 +432,7 @@ static void *do_readmap(void *arg)
- me = cache_enumerate(mc, me);
- }
- pthread_cleanup_pop(1);
-+ map->stale = 0;
- map = map->next;
- }
- pthread_cleanup_pop(1);
-diff --git a/include/automount.h b/include/automount.h
-index fa5cd97..133fd32 100644
---- a/include/automount.h
-+++ b/include/automount.h
-@@ -121,6 +121,7 @@ struct autofs_point;
- #define CHE_MISSING 0x0008
- #define CHE_COMPLETED 0x0010
- #define CHE_DUPLICATE 0x0020
-+#define CHE_UNAVAIL 0x0040
-
- #define HASHSIZE 77
- #define NEGATIVE_TIMEOUT 10
-diff --git a/modules/lookup_file.c b/modules/lookup_file.c
-index 550bf5c..a77068a 100644
---- a/modules/lookup_file.c
-+++ b/modules/lookup_file.c
-@@ -469,11 +469,14 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- master->recurse = 1;;
- master->depth++;
- status = lookup_nss_read_master(master, age);
-- if (!status)
-+ if (!status) {
- warn(logopt,
- MODPREFIX
- "failed to read included master map %s",
- master->name);
-+ fclose(f);
-+ return NSS_STATUS_UNAVAIL;
-+ }
- master->depth--;
- master->recurse = 0;
-
-@@ -484,6 +487,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- if (!buffer) {
- error(logopt,
- MODPREFIX "could not malloc parse buffer");
-+ fclose(f);
- return NSS_STATUS_UNAVAIL;
- }
- memset(buffer, 0, blen);
-@@ -721,9 +725,12 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
-
- /* Gim'ee some o' that 16k stack baby !! */
- status = lookup_nss_read_map(ap, inc_source, age);
-- if (!status)
-+ if (!status) {
- warn(ap->logopt,
- "failed to read included map %s", key);
-+ fclose(f);
-+ return NSS_STATUS_UNAVAIL;
-+ }
- } else {
- char *s_key;
-
-diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index b8484a2..7effbf1 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -1755,7 +1755,7 @@ static int lookup_one(struct autofs_point *ap,
- /* Initialize the LDAP context. */
- ldap = do_reconnect(ap->logopt, ctxt);
- if (!ldap)
-- return CHE_FAIL;
-+ return CHE_UNAVAIL;
-
- debug(ap->logopt,
- MODPREFIX "searching for \"%s\" under \"%s\"", query, ctxt->qdn);
-@@ -1999,6 +1999,21 @@ static int check_map_indirect(struct autofs_point *ap,
- if (ret == CHE_FAIL) {
- pthread_setcancelstate(cur_state, NULL);
- return NSS_STATUS_NOTFOUND;
-+ } else if (ret == CHE_UNAVAIL) {
-+ /*
-+ * If the server is down and the entry exists in the cache
-+ * and belongs to this map return success and use the entry.
-+ */
-+ struct mapent *exists = cache_lookup(mc, key);
-+ if (exists && exists->source == source) {
-+ pthread_setcancelstate(cur_state, NULL);
-+ return NSS_STATUS_SUCCESS;
-+ }
-+
-+ warn(ap->logopt,
-+ MODPREFIX "lookup for %s failed: connection failed", key);
-+
-+ return NSS_STATUS_UNAVAIL;
- }
- pthread_setcancelstate(cur_state, NULL);
-
-diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
-index fee8b16..628ffcf 100644
---- a/modules/lookup_nisplus.c
-+++ b/modules/lookup_nisplus.c
-@@ -385,9 +385,18 @@ static int check_map_indirect(struct autofs_point *ap,
- return NSS_STATUS_NOTFOUND;
-
- if (ret < 0) {
-+ /*
-+ * If the server is down and the entry exists in the cache
-+ * and belongs to this map return success and use the entry.
-+ */
-+ exists = cache_lookup(mc, key);
-+ if (exists && exists->source == source)
-+ return NSS_STATUS_SUCCESS;
-+
- warn(ap->logopt,
- MODPREFIX "lookup for %s failed: %s",
- key, nis_sperrno(-ret));
-+
- return NSS_STATUS_UNAVAIL;
- }
-
-diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
-index 5f4f95f..f5097dc 100644
---- a/modules/lookup_yp.c
-+++ b/modules/lookup_yp.c
-@@ -239,6 +239,9 @@ int lookup_read_master(struct master *master, time_t age, void *context)
- MODPREFIX "read of master map %s failed: %s",
- mapname, yperr_string(err));
-
-+ if (err == YPERR_PMAP || err == YPERR_YPSERV)
-+ return NSS_STATUS_UNAVAIL;
-+
- return NSS_STATUS_NOTFOUND;
- }
-
-@@ -336,6 +339,9 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
- MODPREFIX "read of map %s failed: %s",
- ap->path, yperr_string(err));
-
-+ if (err == YPERR_PMAP || err == YPERR_YPSERV)
-+ return NSS_STATUS_UNAVAIL;
-+
- return NSS_STATUS_NOTFOUND;
- }
-
-@@ -481,9 +487,18 @@ static int check_map_indirect(struct autofs_point *ap,
- return NSS_STATUS_NOTFOUND;
-
- if (ret < 0) {
-+ /*
-+ * If the server is down and the entry exists in the cache
-+ * and belongs to this map return success and use the entry.
-+ */
-+ exists = cache_lookup(mc, key);
-+ if (exists && exists->source == source)
-+ return NSS_STATUS_SUCCESS;
-+
- warn(ap->logopt,
- MODPREFIX "lookup for %s failed: %s",
- key, yperr_string(-ret));
-+
- return NSS_STATUS_UNAVAIL;
- }
-
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index aa5d1c1..98d082c 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -12,6 +12,7 @@
- - fix handling of quoted slash alone.
- - fix parse confusion between attribute and attribute value.
- - fix version passed to get_supported_ver_and_cost.
-+- mark map instances stale so they aren't "cleaned" during updates.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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);
- }
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 2c815e7..f8260b1 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -43,6 +43,7 @@
- - when default master map, auto.master, is used also check for auto_master.
- - fix schema selection in LDAP schema discovery.
- - update negative mount timeout handling.
-+- fix large group handling (Ryan Thomas).
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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);
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 054d4df..ef549cf 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -22,6 +22,7 @@
- - add LDAP schema discovery if no schema is configured.
- - add random selection as a master map entry option.
- - fix couple of edge case parse fails of timeout option.
-+- check for "*" when looking up wildcard in LDAP.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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");
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index da8c599..c6ab15f 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -15,6 +15,7 @@
- - mark map instances stale so they aren't "cleaned" during updates.
- - fix large file compile time option.
- - don't fail on empty master map.
-+- add support for the "%" hack for case insensitive attribute schemas.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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;
- }
+++ /dev/null
-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"
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 08afa7c..c208b31 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -24,6 +24,7 @@
- - fix couple of edge case parse fails of timeout option.
- - check for "*" when looking up wildcard in LDAP.
- - fix LDAP schema discovery.
-+- add SEARCH_BASE configuration option.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/include/defaults.h b/include/defaults.h
-index 9aec11a..0984b1c 100644
---- a/include/defaults.h
-+++ b/include/defaults.h
-@@ -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 --git a/include/lookup_ldap.h b/include/lookup_ldap.h
-index 1378b9e..1a924be 100644
---- a/include/lookup_ldap.h
-+++ b/include/lookup_ldap.h
-@@ -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 --git a/lib/defaults.c b/lib/defaults.c
-index b146f13..c2f86c0 100644
---- a/lib/defaults.c
-+++ b/lib/defaults.c
-@@ -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 char *res, const char *name, const char
- return 0;
- }
-
-+static int parse_line(char *line, char **res, char **value)
-+{
-+ volatile 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_schema(void)
- 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 --git a/man/auto.master.5.in b/man/auto.master.5.in
-index ab5ab1e..0cb2f07 100644
---- a/man/auto.master.5.in
-+++ b/man/auto.master.5.in
-@@ -230,6 +230,11 @@ values must be set, any partial schema specification will be ignored.
- .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
-diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index 9c18ca1..da52e71 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -171,10 +171,207 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
- 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_context *ctxt)
- 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,175 +1021,17 @@ static void free_context(struct lookup_context *ctxt)
- 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];
-- 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';
--
-- 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) {
-- 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.
-@@ -994,31 +1088,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
- 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 --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in
-index 85f4e34..2b1e20a 100644
---- a/redhat/autofs.sysconfig.in
-+++ b/redhat/autofs.sysconfig.in
-@@ -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 --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
-index 85f4e34..2b1e20a 100644
---- a/samples/autofs.conf.default.in
-+++ b/samples/autofs.conf.default.in
-@@ -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
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index c208b31..a2a782d 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -25,6 +25,7 @@
- - check for "*" when looking up wildcard in LDAP.
- - fix LDAP schema discovery.
- - add SEARCH_BASE configuration option.
-+- work around segv at exit due to libxml2 tsd usage.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/aclocal.m4 b/aclocal.m4
-index d0d8346..ffeb232 100644
---- a/aclocal.m4
-+++ b/aclocal.m4
-@@ -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 --git a/configure b/configure
-index b723d74..3508224 100755
---- a/configure
-+++ b/configure
-@@ -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 --git a/daemon/automount.c b/daemon/automount.c
-index 4b6584a..aeeb7cb 100644
---- a/daemon/automount.c
-+++ b/daemon/automount.c
-@@ -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 */
-@@ -1681,6 +1684,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 +1710,9 @@ int main(int argc, char *argv[])
- }
- closelog();
-
-+#ifdef LIBXML2_WORKAROUND
-+ if (dh)
-+ dlclose(dh);
-+#endif
- exit(0);
- }
-diff --git a/include/config.h.in b/include/config.h.in
-index 942694c..9669872 100644
---- a/include/config.h.in
-+++ b/include/config.h.in
-@@ -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 --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index da52e71..49a9a9b 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -1998,9 +1998,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);
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 93c79cf..ca290f9 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -37,6 +37,7 @@
- - remove unused export validation code.
- - add dynamic logging (adapted from v4 patch from Jeff Moyer).
- - fix recursive loopback mounts (Matthias Koenig).
-+- add map re-load to verbose logging.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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);
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 74d39fd..2c815e7 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -42,6 +42,7 @@
- - handle MTAB_NOTUPDATED status return from mount.
- - when default master map, auto.master, is used also check for auto_master.
- - fix schema selection in LDAP schema discovery.
-+- update negative mount timeout handling.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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"
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index fcfbe62..c29d577 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -51,6 +51,7 @@
- - improve handling of server not available.
- - fix LDAP_URI server selection.
- - add authentication option for using an external credential cache.
-+- expand support for the "%" hack.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index 13fbff7..65f1fda 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -1411,6 +1411,140 @@ next:
- return NSS_STATUS_SUCCESS;
- }
-
-+/*
-+ * Deal with encode and decode of % hack.
-+ * Return
-+ * 0 => % hack not present.
-+ * -1 => syntax error or alloc fail.
-+ * 1 transofrmed value returned.
-+ */
-+static int decode_percent_hack(const char *name, char **key)
-+{
-+ const char *tmp;
-+ char *ptr, *new;
-+
-+ if (!key)
-+ return -1;
-+
-+ *key = NULL;
-+
-+ tmp = name;
-+ while (*tmp && *tmp != '%' && *tmp != '[' && *tmp != ']')
-+ tmp++;
-+ if (!*tmp)
-+ return 0;
-+
-+ tmp = name;
-+ while (*tmp) {
-+ if (*tmp == '%') {
-+ tmp++;
-+ if (!*tmp)
-+ return -1;
-+ if (*tmp != '[')
-+ continue;
-+ tmp++;
-+ while (*tmp && *tmp != ']') {
-+ if (*tmp == '%')
-+ tmp++;
-+ tmp++;
-+ }
-+ if (!tmp)
-+ return -1;
-+ }
-+ tmp++;
-+ }
-+
-+ new = malloc(strlen(name) + 1);
-+ if (!new)
-+ return -1;
-+
-+ ptr = new;
-+ tmp = name;
-+ while (*tmp) {
-+ if (*tmp == '%' || *tmp == '[' || *tmp == ']') {
-+ tmp++;
-+ if (*tmp && *tmp != '%')
-+ continue;
-+ }
-+ *ptr++ = *tmp++;
-+ }
-+ *ptr = '\0';
-+
-+ *key = new;
-+
-+ return strlen(new);
-+}
-+
-+static int encode_percent_hack(const char *name, char **key, unsigned int use_class)
-+{
-+ const char *tmp;
-+ unsigned int len = 0;
-+ char *ptr, *new;
-+
-+ if (!key)
-+ return -1;
-+
-+ *key = NULL;
-+
-+ tmp = name;
-+ while (*tmp) {
-+ if (*tmp == '%')
-+ len++;
-+ else if (isupper(*tmp)) {
-+ tmp++;
-+ len++;
-+ if (!use_class)
-+ len++;
-+ else {
-+ if (*tmp && isupper(*tmp))
-+ len += 2;
-+ else
-+ return 0;
-+ while (*tmp && isupper(*tmp)) {
-+ len++;
-+ tmp++;
-+ }
-+ }
-+ continue;
-+ }
-+ len++;
-+ tmp++;
-+ }
-+ if (len == strlen(name))
-+ return 0;
-+
-+ new = malloc(len + 1);
-+ if (!new)
-+ return -1;
-+
-+ ptr = new;
-+ tmp = name;
-+ while (*tmp) {
-+ if (*tmp == '%')
-+ *ptr++ = '%';
-+ else if (isupper(*tmp)) {
-+ char next = *tmp++;
-+ *ptr++ = '%';
-+ if (*tmp && (!isupper(*tmp) || !use_class))
-+ *ptr++ = next;
-+ else {
-+ *ptr++ = '[';
-+ *ptr++ = next;
-+ while (*tmp && isupper(*tmp))
-+ *ptr++ = *tmp++;
-+ *ptr++ = ']';
-+ }
-+ continue;
-+ }
-+ *ptr++ = *tmp++;
-+ }
-+ *ptr = '\0';
-+
-+ *key = new;
-+
-+ return strlen(new);
-+}
-+
- static int read_one_map(struct autofs_point *ap,
- struct lookup_context *ctxt,
- time_t age, int *result_ldap)
-@@ -1518,7 +1652,7 @@ static int read_one_map(struct autofs_point *ap,
- * people using older schemas that allow '*' as a key
- * 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.
-+ * case matching ctriteria in a case insensitive attribute.
- */
- count = ldap_count_values_len(bvKey);
- if (count > 1) {
-@@ -1647,9 +1781,30 @@ static int read_one_map(struct autofs_point *ap,
- *k_val = '*';
- }
-
-- s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt);
-- if (!s_key)
-- goto next;
-+ if (strcasecmp(class, "nisObject")) {
-+ s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt);
-+ if (!s_key)
-+ goto next;
-+ } else {
-+ char *dec_key;
-+ int dec_len = decode_percent_hack(k_val, &dec_key);
-+
-+ if (dec_len < 0) {
-+ crit(ap->logopt,
-+ "could not use percent hack to decode key %s",
-+ k_val);
-+ goto next;
-+ }
-+
-+ if (dec_len == 0)
-+ s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt);
-+ else {
-+ s_key = sanitize_path(dec_key, dec_len, ap->type, ap->logopt);
-+ free(dec_key);
-+ }
-+ if (!s_key)
-+ goto next;
-+ }
-
- cache_writelock(mc);
- cache_update(mc, source, s_key, mapent, age);
-@@ -1712,6 +1867,8 @@ static int lookup_one(struct autofs_point *ap,
- char *query;
- LDAPMessage *result, *e;
- char *class, *info, *entry;
-+ char *enc_key1, *enc_key2;
-+ int enc_len1 = 0, enc_len2 = 0;
- struct berval **bvKey;
- struct berval **bvValues;
- char *attrs[3];
-@@ -1742,14 +1899,38 @@ static int lookup_one(struct autofs_point *ap,
-
- if (*qKey == '*' && qKey_len == 1)
- *qKey = '/';
-+ else if (!strcasecmp(class, "nisObject")) {
-+ enc_len1 = encode_percent_hack(qKey, &enc_key1, 0);
-+ if (enc_len1 < 0) {
-+ crit(ap->logopt,
-+ "could not use percent hack encode key %s",
-+ qKey);
-+ return CHE_FAIL;
-+ }
-+ if (enc_len1 != 0) {
-+ enc_len2 = encode_percent_hack(qKey, &enc_key2, 1);
-+ if (enc_len2 < 0) {
-+ crit(ap->logopt,
-+ "could not use percent hack encode key %s",
-+ qKey);
-+ return CHE_FAIL;
-+ }
-+ }
-+ }
-
- /* Build a query string. */
- l = strlen(class) + 3*strlen(entry) + strlen(qKey) + 35;
-+ if (enc_len1)
-+ l += 2*strlen(entry) + enc_len1 + enc_len2 + 6;
-
- query = alloca(l);
- if (query == NULL) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- crit(ap->logopt, MODPREFIX "malloc: %s", estr);
-+ if (enc_len1) {
-+ free(enc_key1);
-+ free(enc_key2);
-+ }
- return CHE_FAIL;
- }
-
-@@ -1757,8 +1938,27 @@ static int lookup_one(struct autofs_point *ap,
- * Look for an entry in class under ctxt-base
- * whose entry is equal to qKey.
- */
-- ql = sprintf(query,
-- "(&(objectclass=%s)(|(%s=%s)(%s=/)(%s=\\2A)))", class, entry, qKey, entry, entry);
-+ if (!enc_len1) {
-+ ql = sprintf(query,
-+ "(&(objectclass=%s)(|(%s=%s)(%s=/)(%s=\\2A)))",
-+ class, entry, qKey, entry, entry);
-+ } else {
-+ if (enc_len2) {
-+ ql = sprintf(query,
-+ "(&(objectclass=%s)"
-+ "(|(%s=%s)(%s=%s)(%s=%s)(%s=/)(%s=\\2A)))",
-+ class, entry, qKey,
-+ entry, enc_key1, entry, enc_key2, entry, entry);
-+ free(enc_key1);
-+ free(enc_key2);
-+ } else {
-+ ql = sprintf(query,
-+ "(&(objectclass=%s)"
-+ "(|(%s=%s)(%s=%s)(%s=/)(%s=\\2A)))",
-+ class, entry, qKey, entry, enc_key1, entry, entry);
-+ free(enc_key1);
-+ }
-+ }
- if (ql >= l) {
- error(ap->logopt,
- MODPREFIX "error forming query string");
-@@ -1934,9 +2134,30 @@ static int lookup_one(struct autofs_point *ap,
- goto next;
- }
-
-- s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt);
-- if (!s_key)
-- goto next;
-+ if (strcasecmp(class, "nisObject")) {
-+ s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt);
-+ if (!s_key)
-+ goto next;
-+ } else {
-+ char *dec_key;
-+ int dec_len = decode_percent_hack(k_val, &dec_key);
-+
-+ if (dec_len < 0) {
-+ crit(ap->logopt,
-+ "could not use percent hack to decode key %s",
-+ k_val);
-+ goto next;
-+ }
-+
-+ if (dec_len == 0)
-+ s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt);
-+ else {
-+ s_key = sanitize_path(dec_key, dec_len, ap->type, ap->logopt);
-+ free(dec_key);
-+ }
-+ if (!s_key)
-+ goto next;
-+ }
-
- cache_writelock(mc);
- ret = cache_update(mc, source, s_key, mapent, age);
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 4aa384b..09b0541 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -55,6 +55,7 @@
- - fix to quoting for exports gathered by hosts map.
- - use mount option "nosuid" for "-hosts" map unless "suid" is explicily specified.
- - second attempt fixing quoting for exports gathered by hosts map.
-+- quell annoying "cannot open mount module" message.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/daemon/mount.c b/daemon/mount.c
-index 59f8f44..494ede1 100644
---- a/daemon/mount.c
-+++ b/daemon/mount.c
-@@ -38,14 +38,21 @@ int do_mount(struct autofs_point *ap, const char *root, const char *name, int na
- char **ngp;
- int rv;
-
-- mod = open_mount(modstr = fstype, ERR_PREFIX);
-+ /* Initially look for a mount module but don't issue an error on fail */
-+ mod = open_mount(modstr = fstype, NULL);
- if (!mod) {
- for (ngp = not_generic; *ngp; ngp++) {
- if (!strcmp(fstype, *ngp))
- break;
- }
-+ /*
-+ * If there's not a known mount module use the generic module,
-+ * otherwise redo the fs mount module with error reporting
-+ */
- if (!*ngp)
- mod = open_mount(modstr = "generic", ERR_PREFIX);
-+ else
-+ mod = open_mount(modstr = fstype, ERR_PREFIX);
- if (!mod) {
- error(ap->logopt,
- "cannot find mount method for filesystem %s",
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 0fcdfd4..4aa384b 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -54,6 +54,7 @@
- - expand support for the "%" hack.
- - fix to quoting for exports gathered by hosts map.
- - use mount option "nosuid" for "-hosts" map unless "suid" is explicily specified.
-+- second attempt fixing quoting for exports gathered by hosts map.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
-index 70b13a7..1ef420e 100644
---- a/modules/lookup_hosts.c
-+++ b/modules/lookup_hosts.c
-@@ -179,14 +179,9 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
- if (*name == '/') {
- pthread_cleanup_push(cache_lock_cleanup, mc);
- mapent_len = strlen(me->mapent);
-- mapent = alloca(mapent_len + 3);
-- if (mapent) {
-- /* Add quotes to keep the parser happy */
-- mapent[0] = '"';
-- strcpy(mapent + 1, me->mapent);
-- mapent[mapent_len + 1] = '"';
-- mapent[mapent_len + 2] = '\0';
-- }
-+ mapent = alloca(mapent_len + 1);
-+ if (mapent)
-+ strcpy(mapent, me->mapent);
- pthread_cleanup_pop(0);
- }
- cache_unlock(mc);
-diff --git a/modules/parse_sun.c b/modules/parse_sun.c
-index 9a97329..a97a7aa 100644
---- a/modules/parse_sun.c
-+++ b/modules/parse_sun.c
-@@ -878,7 +878,7 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
- }
-
- if (!validate_location(loc)) {
-- warn(logopt, MODPREFIX "invalid location");
-+ warn(logopt, MODPREFIX "invalid location %s", loc);
- free(myoptions);
- free(loc);
- return 0;
-@@ -913,7 +913,7 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
-
- if (!validate_location(ent_chunk)) {
- warn(logopt,
-- MODPREFIX "invalid location %s", ent);
-+ MODPREFIX "invalid location %s", ent_chunk);
- free(ent_chunk);
- free(myoptions);
- free(loc);
-@@ -1344,6 +1344,23 @@ int parse_mount(struct autofs_point *ap, const char *name,
- int loclen;
- int l;
-
-+ /*
-+ * If this is an offset belonging to a multi-mount entry
-+ * it's already been parsed (above) and any option string
-+ * has already been stripped so just use the remainder.
-+ */
-+ if (*name == '/' &&
-+ (me = cache_lookup_distinct(mc, name)) && me->multi) {
-+ loc = strdup(p);
-+ if (!loc) {
-+ free(options);
-+ warn(ap->logopt, MODPREFIX "out of memory");
-+ return 1;
-+ }
-+ loclen = strlen(p);
-+ goto mount_it;
-+ }
-+
- l = chunklen(p, check_colon(p));
- loc = dequote(p, l, ap->logopt);
- if (!loc) {
-@@ -1361,9 +1378,9 @@ int parse_mount(struct autofs_point *ap, const char *name,
- }
-
- if (!validate_location(loc)) {
-+ warn(ap->logopt, MODPREFIX "invalid location %s", loc);
- free(loc);
- free(options);
-- warn(ap->logopt, MODPREFIX "invalid location");
- return 1;
- }
-
-@@ -1387,10 +1404,11 @@ int parse_mount(struct autofs_point *ap, const char *name,
- }
-
- if (!validate_location(ent)) {
-+ warn(ap->logopt,
-+ MODPREFIX "invalid location %s", loc);
- free(ent);
- free(loc);
- free(options);
-- warn(ap->logopt, MODPREFIX "invalid location");
- return 1;
- }
-
-@@ -1424,7 +1442,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
- MODPREFIX "entry %s is empty!", name);
- return 1;
- }
--
-+mount_it:
- debug(ap->logopt,
- MODPREFIX "core of entry: options=%s, loc=%.*s",
- options, loclen, loc);
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index c29d577..c486a7b 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -52,6 +52,7 @@
- - fix LDAP_URI server selection.
- - add authentication option for using an external credential cache.
- - expand support for the "%" hack.
-+- fix to quoting for exports gathered by hosts map.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
-index 1ef420e..70b13a7 100644
---- a/modules/lookup_hosts.c
-+++ b/modules/lookup_hosts.c
-@@ -179,9 +179,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
- if (*name == '/') {
- pthread_cleanup_push(cache_lock_cleanup, mc);
- mapent_len = strlen(me->mapent);
-- mapent = alloca(mapent_len + 1);
-- if (mapent)
-- strcpy(mapent, me->mapent);
-+ mapent = alloca(mapent_len + 3);
-+ if (mapent) {
-+ /* Add quotes to keep the parser happy */
-+ mapent[0] = '"';
-+ strcpy(mapent + 1, me->mapent);
-+ mapent[mapent_len + 1] = '"';
-+ mapent[mapent_len + 2] = '\0';
-+ }
- pthread_cleanup_pop(0);
- }
- cache_unlock(mc);
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 2ce58b4..903e619 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -7,6 +7,7 @@
- - change random multiple server selection option name to be consistent
- with existing downstream version 4 naming.
- - fix mount point directory creation for bind mounts.
-+- add quoting for exports gathered by hosts map.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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);
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index bc4d8fd..1bf4b27 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -9,6 +9,7 @@
- - fix mount point directory creation for bind mounts.
- - add quoting for exports gathered by hosts map.
- - fix wait time resolution in alarm and state queue handlers.
-+- fix handling of quoted slash alone.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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;
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index c36017a..0e9dc51 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -20,6 +20,7 @@
- - fix don't fail on empty master map.
- - if there's no "automount" entry in nsswitch.conf use "files" source.
- - add LDAP schema discovery if no schema is configured.
-+- add random selection as a master map entry option.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/daemon/automount.c b/daemon/automount.c
-index 7b79f02..4b6584a 100644
---- a/daemon/automount.c
-+++ b/daemon/automount.c
-@@ -49,9 +49,9 @@ const char *confdir = AUTOFS_CONF_DIR; /* Location of autofs config file */
-
- 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;
-@@ -1490,7 +1490,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;
-@@ -1531,7 +1531,7 @@ int main(int argc, char *argv[])
- exit(0);
-
- case 'r':
-- random_selection = 1;
-+ global_random_selection = 1;
- break;
-
- case 'O':
-diff --git a/include/automount.h b/include/automount.h
-index d9e4ecd..d55ba5c 100644
---- a/include/automount.h
-+++ b/include/automount.h
-@@ -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 --git a/include/replicated.h b/include/replicated.h
-index c77cda6..3afe9f7 100644
---- a/include/replicated.h
-+++ b/include/replicated.h
-@@ -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 --git a/lib/master_parse.y b/lib/master_parse.y
-index ab2895d..70b48be 100644
---- a/lib/master_parse.y
-+++ b/lib/master_parse.y
-@@ -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 { timeout = $2; }
- | 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 *buffer, unsigned int default_timeout, unsigne
- }
- set_mnt_logging(ap);
- }
-+ entry->ap->random_selection = random_selection;
-
- /*
- source = master_find_map_source(entry, type, format,
-diff --git a/lib/master_tok.l b/lib/master_tok.l
-index ff69a24..013a15a 100644
---- a/lib/master_tok.l
-+++ b/lib/master_tok.l
-@@ -324,6 +324,7 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{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 --git a/man/auto.master.5.in b/man/auto.master.5.in
-index 249c9a7..ab5ab1e 100644
---- a/man/auto.master.5.in
-+++ b/man/auto.master.5.in
-@@ -146,6 +146,12 @@ 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.
-+.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
-diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
-index e7a9a8a..e4480c5 100644
---- a/modules/mount_nfs.c
-+++ b/modules/mount_nfs.c
-@@ -137,7 +137,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
- 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 --git a/modules/replicated.c b/modules/replicated.c
-index 0764d4a..e15587c 100644
---- a/modules/replicated.c
-+++ b/modules/replicated.c
-@@ -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(const char *options)
- 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 *host, unsigned int version, const char
- 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 *host, unsigned int version, const char
- }
-
- 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 *host, unsigned int version, const char
- 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, unsigned int vers, const char *options)
- 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, unsigned int vers, const char *options)
- 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);
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index fe7ae00..ca171a4 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -34,6 +34,7 @@
- - fix lack of ferror() checking when reading files.
- - fix typo in autofs(5) man page.
- - fix map entry expansion when undefined macro is present.
-+- remove unused export validation code.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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) {
+++ /dev/null
-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;
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index a2a782d..9a2a8c1 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -26,6 +26,7 @@
- - fix LDAP schema discovery.
- - add SEARCH_BASE configuration option.
- - work around segv at exit due to libxml2 tsd usage.
-+- re-read config on HUP signal.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/daemon/automount.c b/daemon/automount.c
-index e9cae4e..3d6a703 100644
---- a/daemon/automount.c
-+++ b/daemon/automount.c
-@@ -986,6 +986,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 --git a/lib/master.c b/lib/master.c
-index da05bb6..637ce04 100644
---- a/lib/master.c
-+++ b/lib/master.c
-@@ -1169,6 +1169,10 @@ int master_mount_mounts(struct master *master, time_t age, int readall)
- 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) {
-diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
-index 8821f84..9aac792 100644
---- a/modules/cyrus-sasl.c
-+++ b/modules/cyrus-sasl.c
-@@ -528,6 +528,7 @@ sasl_do_kinit(struct lookup_context *ctxt)
- 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 --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
-index 49a9a9b..2baf8b8 100644
---- a/modules/lookup_ldap.c
-+++ b/modules/lookup_ldap.c
-@@ -174,7 +174,7 @@ LDAP *init_ldap_connection(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;
-+ 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, struct lookup_context *ctxt, const char *cla
-
- 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, struct lookup_context *ctxt, const char *cla
- 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, struct lookup_context *ctxt, const char *cla
- 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_context *ctxt)
- 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_point *ap,
- }
- 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) {
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index be50aad..3557b16 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -45,6 +45,7 @@
- - update negative mount timeout handling.
- - fix large group handling (Ryan Thomas).
- - fix for dynamic logging breaking non-sasl build (Guillaume Rousse)
-+- eliminate NULL proc ping for singleton host or local mounts.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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;
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 3557b16..7e58092 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -46,6 +46,7 @@
- - fix large group handling (Ryan Thomas).
- - fix for dynamic logging breaking non-sasl build (Guillaume Rousse)
- - eliminate NULL proc ping for singleton host or local mounts.
-+- fix incorrect read/write size of startup status token (Matthias Koenig).
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-diff --git a/daemon/automount.c b/daemon/automount.c
-index 7becad5..f31ec11 100644
---- a/daemon/automount.c
-+++ b/daemon/automount.c
-@@ -1125,7 +1125,7 @@ static void become_daemon(unsigned foreground)
- if (pid > 0) {
- int r;
- close(start_pipefd[1]);
-- r = read(start_pipefd[0], pst_stat, sizeof(pst_stat));
-+ r = read(start_pipefd[0], pst_stat, sizeof(*pst_stat));
- if (r < 0)
- exit(1);
- exit(*pst_stat);
-@@ -2061,12 +2061,12 @@ int main(int argc, char *argv[])
- if (!master_read_master(master_list, age, 0)) {
- master_kill(master_list);
- *pst_stat = 3;
-- res = write(start_pipefd[1], pst_stat, sizeof(pst_stat));
-+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
- close(start_pipefd[1]);
- exit(3);
- }
-
-- res = write(start_pipefd[1], pst_stat, sizeof(pst_stat));
-+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
- close(start_pipefd[1]);
-
- state_mach_thid = pthread_self();
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index ddfa6f1..2db9b39 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -30,6 +30,7 @@
- - add LDAP_URI, LDAP_TIMEOUT and LDAP_NETWORK_TIMEOUT configuration options.
- - fix forground logging and add option to man page.
- - remove unjustified, nasty comment about krb5 package.
-+- fix deadlock in submount mount module.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index fdd07d1..fe7ae00 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -33,6 +33,7 @@
- - fix deadlock in submount mount module.
- - fix lack of ferror() checking when reading files.
- - fix typo in autofs(5) man page.
-+- fix map entry expansion when undefined macro is present.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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;
+++ /dev/null
-diff --git a/CHANGELOG b/CHANGELOG
-index 0e9dc51..054d4df 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -21,6 +21,7 @@
- - if there's no "automount" entry in nsswitch.conf use "files" source.
- - add LDAP schema discovery if no schema is configured.
- - add random selection as a master map entry option.
-+- fix couple of edge case parse fails of timeout option.
-
- 18/06/2007 autofs-5.0.2
- -----------------------
-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);