diff --git a/autofs-5.0.2-add-ldap-schema-discovery.patch b/autofs-5.0.2-add-ldap-schema-discovery.patch new file mode 100644 index 0000000..494b364 --- /dev/null +++ b/autofs-5.0.2-add-ldap-schema-discovery.patch @@ -0,0 +1,650 @@ +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 + #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 + + #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; diff --git a/autofs-5.0.2-default-nsswitch.patch b/autofs-5.0.2-default-nsswitch.patch new file mode 100644 index 0000000..eae7bbf --- /dev/null +++ b/autofs-5.0.2-default-nsswitch.patch @@ -0,0 +1,51 @@ +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); + } + diff --git a/autofs-5.0.2-dont-fail-on-empty-master.patch b/autofs-5.0.2-dont-fail-on-empty-master.patch index 1919f6c..2c084a1 100644 --- a/autofs-5.0.2-dont-fail-on-empty-master.patch +++ b/autofs-5.0.2-dont-fail-on-empty-master.patch @@ -1,13 +1,109 @@ -diff --git a/lib/master.c b/lib/master.c -index 4d31959..9f24f7e 100644 ---- a/lib/master.c +diff -u b/lib/master.c b/lib/master.c +--- b/lib/master.c +++ b/lib/master.c -@@ -803,7 +803,7 @@ int master_read_master(struct master *master, time_t age, int readall) +@@ -802,8 +802,8 @@ + if (list_empty(&master->mounts)) { master_mutex_unlock(); - error(LOGOPT_ANY, "no mounts in table"); +- error(LOGOPT_ANY, "no mounts in table"); - return 0; ++ warn(LOGOPT_ANY, "no mounts in table"); + return 1; } master_mutex_unlock(); +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -61,6 +61,8 @@ static size_t kpkt_len; + + /* Attribute to create detached thread */ + pthread_attr_t thread_attr; ++/* Attribute to create normal thread */ ++pthread_attr_t thread_attr_nodetach; + + struct master_readmap_cond mrc = { + PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, NULL, 0, 0, 0, 0}; +@@ -914,7 +916,7 @@ static void *do_notify_state(void *arg) + return NULL; + } + +-static int do_signals(struct master *master, int sig) ++static pthread_t do_signals(struct master *master, int sig) + { + pthread_t thid; + int r_sig = sig; +@@ -924,7 +926,7 @@ static int do_signals(struct master *master, int sig) + if (status) + fatal(status); + +- status = pthread_create(&thid, &thread_attr, do_notify_state, &r_sig); ++ status = pthread_create(&thid, &thread_attr_nodetach, do_notify_state, &r_sig); + if (status) { + error(master->default_logging, + "mount state notify thread create failed"); +@@ -948,7 +950,7 @@ static int do_signals(struct master *master, int sig) + + pthread_cleanup_pop(1); + +- return 1; ++ return thid; + } + + static void *do_read_master(void *arg) +@@ -1038,6 +1040,7 @@ static int do_hup_signal(struct master *master, time_t age) + /* Deal with all the signal-driven events in the state machine */ + static void *statemachine(void *arg) + { ++ pthread_t thid = 0; + sigset_t signalset; + int sig; + +@@ -1048,15 +1051,17 @@ static void *statemachine(void *arg) + while (1) { + sigwait(&signalset, &sig); + +- +- if (master_list_empty(master_list)) +- return NULL; +- + switch (sig) { + case SIGTERM: + case SIGUSR2: + case SIGUSR1: +- do_signals(master_list, sig); ++ thid = do_signals(master_list, sig); ++ if (thid) { ++ pthread_join(thid, NULL); ++ if (master_list_empty(master_list)) ++ return NULL; ++ thid = 0; ++ } + break; + + case SIGHUP: +@@ -1171,10 +1176,6 @@ static void handle_mounts_cleanup(void *arg) + + msg("shut down path %s", path); + +- /* If we are the last tell the state machine to shutdown */ +- if (!submount && master_list_empty(master_list)) +- kill(getpid(), SIGTERM); +- + return; + } + +@@ -1644,6 +1645,14 @@ int main(int argc, char *argv[]) + } + #endif + ++ if (pthread_attr_init(&thread_attr_nodetach)) { ++ crit(LOGOPT_ANY, ++ "%s: failed to init thread attribute struct!", ++ program); ++ close(start_pipefd[1]); ++ exit(1); ++ } ++ + msg("Starting automounter version %s, master map %s", + version, master_list->name); + msg("using kernel protocol version %d.%02d", diff --git a/autofs.spec b/autofs.spec index 743d343..b52c93e 100644 --- a/autofs.spec +++ b/autofs.spec @@ -4,7 +4,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.0.2 -Release: 13 +Release: 14 Epoch: 1 License: GPL Group: System Environment/Daemons @@ -26,6 +26,8 @@ Patch12: autofs-5.0.2-dont-fail-on-empty-master.patch Patch13: autofs-5.0.2-ldap-percent-hack.patch Patch14: autofs-5.0.2-consistent-random-selection-option-name.patch Patch15: autofs-5.0.2-fix-mount-nfs-nosymlink.patch +Patch16: autofs-5.0.2-default-nsswitch.patch +Patch17: autofs-5.0.2-add-ldap-schema-discovery.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel Conflicts: kernel < 2.6.17 @@ -83,6 +85,8 @@ echo %{version}-%{release} > .version %patch13 -p1 %patch14 -p1 %patch15 -p1 +%patch16 -p1 +%patch17 -p1 %build #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir} @@ -135,6 +139,11 @@ fi %{_libdir}/autofs/ %changelog +* Tue Aug 28 2007 Ian Kent - 5.0.2-14 +- update patch to prevent failure 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. + * Wed Aug 22 2007 Ian Kent - 5.0.2-13 - fix "nosymlink" option handling and add desription to man page.