From 019928ca76856e4d86319fd1cb477c2346b7963f Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 03 2016 06:23:41 +0000 Subject: import autofs-5.0.7-56.el7 --- diff --git a/SOURCES/autofs-5.0.9-revert-special-case-cifs-escapes.patch b/SOURCES/autofs-5.0.9-revert-special-case-cifs-escapes.patch new file mode 100644 index 0000000..30f6413 --- /dev/null +++ b/SOURCES/autofs-5.0.9-revert-special-case-cifs-escapes.patch @@ -0,0 +1,91 @@ +autofs-5.0.9 - revert special case cifs escapes + +From: Ian Kent + +The patch this reverts added an additional dquote on the mount location +to revolve "\"s but this causes inconsistent quoting between the lookup +key and the mount location when it is substituted using the &. + +As described in the original patch: +"Since "\" is a valid seperator for cifs shares it can't be used to escape +characters in the share name passed to mount.cifs. So we have no choice +but to require that the seperator we use is "/" and de-quote the string +before sending it to mount.cifs." + +We do need to require that the seperator "/" is used which alone should +eliminate the need for an additional dequote and expect that invalid +share name mounts will fail. +--- + modules/mount_generic.c | 36 ++++++------------------------------ + 1 file changed, 6 insertions(+), 30 deletions(-) + +--- autofs-5.0.7.orig/modules/mount_generic.c ++++ autofs-5.0.7/modules/mount_generic.c +@@ -39,7 +39,6 @@ int mount_mount(struct autofs_point *ap, + { + char fullpath[PATH_MAX]; + char buf[MAX_ERR_BUF]; +- char *loc; + int err; + int len, status, existed = 1; + +@@ -75,44 +74,22 @@ int mount_mount(struct autofs_point *ap, + if (!status) + existed = 0; + +- /* +- * Special case quoting for cifs share names. +- * +- * Since "\" is a valid seperator for cifs shares it can't be +- * used to escape characters in the share name passed to +- * mount.cifs. So we have no choice but to require that the +- * seperator we use is "/" and de-quote the string before +- * sending it to mount.cifs. +- */ +- loc = NULL; +- if (strcmp(fstype, "cifs")) +- loc = strdup(what); +- else +- loc = dequote(what, strlen(what), ap->logopt); +- if (!loc) { +- error(ap->logopt, +- MODPREFIX "failed to alloc buffer for mount location"); +- return 1; +- } +- + if (options && options[0]) { + debug(ap->logopt, + MODPREFIX "calling mount -t %s " SLOPPY "-o %s %s %s", +- fstype, options, loc, fullpath); ++ fstype, options, what, fullpath); + + err = spawn_mount(ap->logopt, "-t", fstype, +- SLOPPYOPT "-o", options, loc, fullpath, NULL); ++ SLOPPYOPT "-o", options, what, fullpath, NULL); + } else { + debug(ap->logopt, MODPREFIX "calling mount -t %s %s %s", +- fstype, loc, fullpath); +- err = spawn_mount(ap->logopt, "-t", fstype, loc, fullpath, NULL); ++ fstype, what, fullpath); ++ err = spawn_mount(ap->logopt, "-t", fstype, what, fullpath, NULL); + } + + if (err) { + info(ap->logopt, MODPREFIX "failed to mount %s (type %s) on %s", +- loc, fstype, fullpath); +- +- free(loc); ++ what, fstype, fullpath); + + if (ap->type != LKP_INDIRECT) + return 1; +@@ -123,8 +100,7 @@ int mount_mount(struct autofs_point *ap, + return 1; + } else { + debug(ap->logopt, MODPREFIX "mounted %s type %s on %s", +- loc, fstype, fullpath); +- free(loc); ++ what, fstype, fullpath); + return 0; + } + } diff --git a/SOURCES/autofs-5.1.0-fix-gcc5-complaints.patch b/SOURCES/autofs-5.1.0-fix-gcc5-complaints.patch new file mode 100644 index 0000000..3f653cc --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-gcc5-complaints.patch @@ -0,0 +1,68 @@ +autofs-5.1.0 - fix gcc5 complaints + +From: Ian Kent + +gcc5 is not happy with the way dump_core() and master_get_logopt() +are declared inline, remove the inline and let the compiler decide. +--- + CHANGELOG | 1 + + daemon/spawn.c | 2 +- + include/automount.h | 2 +- + include/master.h | 2 +- + lib/master.c | 2 +- + 5 files changed, 5 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -192,6 +192,7 @@ + - fix handle_mounts() termination condition check. + - fix config old name lookup. + - fix error handling on ldap bind fail. ++- fix gcc5 complaints. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/spawn.c ++++ autofs-5.0.7/daemon/spawn.c +@@ -36,7 +36,7 @@ static pthread_mutex_t spawn_mutex = PTH + + #define MTAB_LOCK_RETRIES 3 + +-inline void dump_core(void) ++void dump_core(void) + { + sigset_t segv; + +--- autofs-5.0.7.orig/include/automount.h ++++ autofs-5.0.7/include/automount.h +@@ -241,7 +241,7 @@ const char **copy_argv(int argc, const c + int compare_argv(int argc1, const char **argv1, int argc2, const char **argv2); + int free_argv(int argc, const char **argv); + +-inline void dump_core(void); ++void dump_core(void); + int aquire_lock(void); + void release_lock(void); + int spawnl(unsigned logopt, const char *prog, ...); +--- autofs-5.0.7.orig/include/master.h ++++ autofs-5.0.7/include/master.h +@@ -120,7 +120,7 @@ void master_notify_state_change(struct m + int master_mount_mounts(struct master *, time_t, int); + int dump_map(struct master *, const char *, const char *); + int master_show_mounts(struct master *); +-extern inline unsigned int master_get_logopt(void); ++unsigned int master_get_logopt(void); + int master_list_empty(struct master *); + int master_done(struct master *); + int master_kill(struct master *); +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -1712,7 +1712,7 @@ int master_done(struct master *master) + return res; + } + +-inline unsigned int master_get_logopt(void) ++unsigned int master_get_logopt(void) + { + return master_list ? master_list->logopt : LOGOPT_NONE; + } diff --git a/SOURCES/autofs-5.1.0-guard-against-incorrect-umount-return.patch b/SOURCES/autofs-5.1.0-guard-against-incorrect-umount-return.patch new file mode 100644 index 0000000..e996fed --- /dev/null +++ b/SOURCES/autofs-5.1.0-guard-against-incorrect-umount-return.patch @@ -0,0 +1,57 @@ +autofs-5.1.0 - guard against incorrect umount return + +From: Ian Kent + +If umount(8) returns a fail but the mount is actually umounted autofs +can incorrectly try reconstruct mount triggers. This can lead to the +automount point becoming unresponsive. +--- + CHANGELOG | 1 + + daemon/automount.c | 3 ++- + lib/mounts.c | 6 ++++-- + 3 files changed, 7 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -184,6 +184,7 @@ + - fix out of order call in program map lookup. + - make service want network-online. + - add remote-fs.target systemd dependency. ++- gaurd against incorrect umount return. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -532,7 +532,8 @@ static int umount_subtree_mounts(struct + if (!is_mm_root && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { + struct amd_entry *entry; + debug(ap->logopt, "unmounting dir = %s", path); +- if (umount_ent(ap, path)) { ++ if (umount_ent(ap, path) && ++ is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { + warn(ap->logopt, "could not umount dir %s", path); + left++; + goto done; +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -2126,7 +2126,8 @@ int umount_multi_triggers(struct autofs_ + */ + if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { + info(ap->logopt, "unmounting dir = %s", root); +- if (umount_ent(ap, root)) { ++ if (umount_ent(ap, root) && ++ is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { + if (mount_multi_triggers(ap, me, root, strlen(root), "/") < 0) + warn(ap->logopt, + "failed to remount offset triggers"); +@@ -2227,7 +2228,8 @@ int clean_stale_multi_triggers(struct au + */ + if (oe->ioctlfd != -1 || + is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) { +- if (umount_ent(ap, oe->key)) { ++ if (umount_ent(ap, oe->key) && ++ is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) { + debug(ap->logopt, + "offset %s has active mount, invalidate", + oe->key); diff --git a/SOURCES/autofs-5.1.0-make-service-want-network-online.patch b/SOURCES/autofs-5.1.0-make-service-want-network-online.patch new file mode 100644 index 0000000..75f43d6 --- /dev/null +++ b/SOURCES/autofs-5.1.0-make-service-want-network-online.patch @@ -0,0 +1,38 @@ +autofs-5.1.0 - make service want network-online + +From: Ian Kent + +autofs often fails to start properly in Fedora with recent systemd. + +Changing the systemd unit to Want the network-online target works +around this. + +I'm not sure if this will cause problems for people that use file +maps and expect autofs to start without the network up but I hope +that's a small minority, if there are any at all. +--- + CHANGELOG | 1 + + samples/autofs.service.in | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -182,6 +182,7 @@ + - fix direct map expire not set for initail empty map. + - update map_hash_table_size description. + - fix out of order call in program map lookup. ++- make service want network-online. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/samples/autofs.service.in ++++ autofs-5.0.7/samples/autofs.service.in +@@ -1,6 +1,7 @@ + [Unit] + Description=Automounts filesystems on demand +-After=network.target ypbind.service sssd.service ++After=network.target ypbind.service sssd.service network-online.target ++Wants=network-online.target + + [Service] + Type=forking diff --git a/SOURCES/autofs-5.1.1-add-config-option-to-suppress-not-found-log-message.patch b/SOURCES/autofs-5.1.1-add-config-option-to-suppress-not-found-log-message.patch new file mode 100644 index 0000000..6211649 --- /dev/null +++ b/SOURCES/autofs-5.1.1-add-config-option-to-suppress-not-found-log-message.patch @@ -0,0 +1,171 @@ +autofs-5.1.1 - add config option to suppress not found log message + +From: Ian Kent + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 11 +++++++++-- + include/defaults.h | 4 +++- + lib/defaults.c | 17 +++++++++++++++++ + man/autofs.conf.5.in | 7 +++++++ + modules/lookup_hesiod.c | 6 ++++-- + redhat/autofs.conf.default.in | 8 ++++++++ + samples/autofs.conf.default.in | 8 ++++++++ + 8 files changed, 57 insertions(+), 5 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -205,6 +205,7 @@ + - fix typo in autofs_sasl_bind(). + - add configuration option to use fqdn in mounts. + - fix use-after-free in st_queue_handler(). ++- add config option to supress not found log message. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -1036,8 +1036,15 @@ static void update_negative_cache(struct + */ + cache_unlock(me->mc); + else { +- /* Notify only once after fail */ +- logmsg("key \"%s\" not found in map source(s).", name); ++ if (!defaults_disable_not_found_message()) { ++ /* This really should be a warning but the original ++ * request for this needed it to be unconditional. ++ * That produces, IMHO, unnecessary noise in the log ++ * so a configuration option has been added to provide ++ * the ability to turn it off. ++ */ ++ logmsg("key \"%s\" not found in map source(s).", name); ++ } + + /* Doesn't exist in any source, just add it somewhere */ + if (source) +--- autofs-5.0.7.orig/include/defaults.h ++++ autofs-5.0.7/include/defaults.h +@@ -47,7 +47,8 @@ + + #define DEFAULT_MAP_HASH_TABLE_SIZE "1024" + +-#define DEFAULT_USE_HOSTNAME_FOR_MOUNTS "0" ++#define DEFAULT_USE_HOSTNAME_FOR_MOUNTS "0" ++#define DEFAULT_DISABLE_NOT_FOUND_MESSAGE "0" + + /* Config entry flags */ + #define CONF_NONE 0x00000000 +@@ -165,6 +166,7 @@ unsigned int defaults_get_umount_wait(vo + const char *defaults_get_auth_conf_file(void); + unsigned int defaults_get_map_hash_table_size(void); + unsigned int defaults_use_hostname_for_mounts(void); ++unsigned int defaults_disable_not_found_message(void); + + unsigned int conf_amd_mount_section_exists(const char *); + char *conf_amd_get_arch(void); +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -73,6 +73,7 @@ + #define NAME_MAP_HASH_TABLE_SIZE "map_hash_table_size" + + #define NAME_USE_HOSTNAME_FOR_MOUNTS "use_hostname_for_mounts" ++#define NAME_DISABLE_NOT_FOUND_MESSAGE "disable_not_found_message" + + #define NAME_AMD_ARCH "arch" + #define NAME_AMD_AUTO_ATTRCACHE "auto_attrcache" +@@ -341,6 +342,11 @@ static int conf_load_autofs_defaults(voi + if (ret == CFG_FAIL) + goto error; + ++ ret = conf_update(sec, NAME_DISABLE_NOT_FOUND_MESSAGE, ++ DEFAULT_DISABLE_NOT_FOUND_MESSAGE, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ + /* LDAP_URI and SEARCH_BASE can occur multiple times */ + while ((co = conf_lookup(sec, NAME_LDAP_URI))) + conf_delete(co->section, co->name); +@@ -1717,6 +1723,17 @@ unsigned int defaults_use_hostname_for_m + + return res; + } ++ ++unsigned int defaults_disable_not_found_message(void) ++{ ++ int res; ++ ++ res = conf_get_yesno(autofs_gbl_sec, NAME_DISABLE_NOT_FOUND_MESSAGE); ++ if (res < 0) ++ res = atoi(DEFAULT_DISABLE_NOT_FOUND_MESSAGE); ++ ++ return res; ++} + + unsigned int conf_amd_mount_section_exists(const char *section) + { +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -129,6 +129,13 @@ name resolving to one that isn't respond + of attempts at a successful mount will correspond to the number of + addresses the host name resolves to the order will also not correspond + to fastest responding hosts. ++.TP ++.B disable_not_found_message ++.br ++The original request to add this log message needed it to be unconditional. ++That produces, IMHO, unnecessary noise in the log so a configuration option ++has been added to provide the ability to turn it off. The default is "no" ++to maintain the current behaviour. + .SS LDAP Configuration + .P + Configuration settings available are: +--- autofs-5.0.7.orig/modules/lookup_hesiod.c ++++ autofs-5.0.7/modules/lookup_hesiod.c +@@ -194,8 +194,10 @@ static int lookup_one(struct autofs_poin + hes_result = hesiod_resolve(ctxt->hesiod_context, key, "filsys"); + if (!hes_result || !hes_result[0]) { + int err = errno; +- error(ap->logopt, +- MODPREFIX "key \"%s\" not found in map", key); ++ if (!defaults_disable_not_found_message()) { ++ error(ap->logopt, ++ MODPREFIX "key \"%s\" not found in map", key); ++ } + status = pthread_mutex_unlock(&hesiod_mutex); + if (status) + fatal(status); +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -151,6 +151,14 @@ mount_nfs_default_protocol = 4 + # + #use_hostname_for_mounts = "no" + # ++# disable_not_found_message - The original request to add this log message ++# needed it to be unconditional. That produces, IMHO, ++# unnecessary noise in the log so a configuration option ++# has been added to provide the ability to turn it off. ++# The default is "no" to maintain the current behaviour. ++# ++#disable_not_found_message = "no" ++# + # Otions for the amd parser within autofs. + # + # amd configuration options that are aren't used, haven't been +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -150,6 +150,14 @@ browse_mode = no + # + #use_hostname_for_mounts = "no" + # ++# disable_not_found_message - The original request to add this log message ++# needed it to be unconditional. That produces, IMHO, ++# unnecessary noise in the log so a configuration option ++# has been added to provide the ability to turn it off. ++# The default is "no" to maintain the current behaviour. ++# ++#disable_not_found_message = "no" ++# + # Otions for the amd parser within autofs. + # + # amd configuration options that are aren't used, haven't been diff --git a/SOURCES/autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch b/SOURCES/autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch new file mode 100644 index 0000000..3f15df7 --- /dev/null +++ b/SOURCES/autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch @@ -0,0 +1,182 @@ +autofs-5.1.1 - add configuration option to use fqdn in mounts + +From: Ian Kent + +When a server name returns multiple IP addresses autofs uses the IP +address when performing the mount to ensure that the the host proximity +order is respected, and that servers that aren't responding aren't +tried. + +But sometimes people need to use the server name for the mount so +add a configuration option to enable that. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/defaults.h | 3 +++ + lib/defaults.c | 18 ++++++++++++++++++ + man/autofs.conf.5.in | 18 ++++++++++++++++++ + modules/mount_nfs.c | 3 ++- + modules/replicated.c | 6 ++++++ + redhat/autofs.conf.default.in | 8 ++++++++ + samples/autofs.conf.default.in | 8 ++++++++ + 8 files changed, 64 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -203,6 +203,7 @@ + - fix use after free in sun parser parse_init(). + - fix use after free in open_lookup(). + - fix typo in autofs_sasl_bind(). ++- add configuration option to use fqdn in mounts. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/defaults.h ++++ autofs-5.0.7/include/defaults.h +@@ -47,6 +47,8 @@ + + #define DEFAULT_MAP_HASH_TABLE_SIZE "1024" + ++#define DEFAULT_USE_HOSTNAME_FOR_MOUNTS "0" ++ + /* Config entry flags */ + #define CONF_NONE 0x00000000 + #define CONF_ENV 0x00000001 +@@ -162,6 +164,7 @@ unsigned int defaults_get_mount_wait(voi + unsigned int defaults_get_umount_wait(void); + const char *defaults_get_auth_conf_file(void); + unsigned int defaults_get_map_hash_table_size(void); ++unsigned int defaults_use_hostname_for_mounts(void); + + unsigned int conf_amd_mount_section_exists(const char *); + char *conf_amd_get_arch(void); +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -72,6 +72,8 @@ + + #define NAME_MAP_HASH_TABLE_SIZE "map_hash_table_size" + ++#define NAME_USE_HOSTNAME_FOR_MOUNTS "use_hostname_for_mounts" ++ + #define NAME_AMD_ARCH "arch" + #define NAME_AMD_AUTO_ATTRCACHE "auto_attrcache" + #define NAME_AMD_AUTO_DIR "auto_dir" +@@ -334,6 +336,11 @@ static int conf_load_autofs_defaults(voi + if (ret == CFG_FAIL) + goto error; + ++ ret = conf_update(sec, NAME_USE_HOSTNAME_FOR_MOUNTS, ++ DEFAULT_USE_HOSTNAME_FOR_MOUNTS, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ + /* LDAP_URI and SEARCH_BASE can occur multiple times */ + while ((co = conf_lookup(sec, NAME_LDAP_URI))) + conf_delete(co->section, co->name); +@@ -1700,6 +1707,17 @@ unsigned int defaults_get_map_hash_table + return (unsigned int) size; + } + ++unsigned int defaults_use_hostname_for_mounts(void) ++{ ++ int res; ++ ++ res = conf_get_yesno(autofs_gbl_sec, NAME_USE_HOSTNAME_FOR_MOUNTS); ++ if (res < 0) ++ res = atoi(DEFAULT_USE_HOSTNAME_FOR_MOUNTS); ++ ++ return res; ++} ++ + unsigned int conf_amd_mount_section_exists(const char *section) + { + return conf_section_exists(section); +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -111,6 +111,24 @@ entries, in this case, is usually much l + in the map. In this last case it would be unusual for the map entry + cache to grow large enough to warrant increasing the default before + an event that cleans stale entries, a map re-read for example. ++.TP ++.B use_hostname_for_mounts ++.br ++NFS mounts where the host name resolves to more than one IP address ++are probed for availability and to establish the order in which mounts ++to them should be tried. To ensure that mount attempts are made only ++to hosts that are responding and are tried in the order of hosts with ++the quickest response the IP address of the host needs to be used for ++the mount. ++ ++If it is necessary to use the hostname given in the map entry for the ++mount regardless, then set this option to "yes". ++ ++Be aware that if this is done there is no defense against the host ++name resolving to one that isn't responding and while the number ++of attempts at a successful mount will correspond to the number of ++addresses the host name resolves to the order will also not correspond ++to fastest responding hosts. + .SS LDAP Configuration + .P + Configuration settings available are: +--- autofs-5.0.7.orig/modules/mount_nfs.c ++++ autofs-5.0.7/modules/mount_nfs.c +@@ -316,7 +316,8 @@ dont_probe: + + /* Not a local host - do an NFS mount */ + +- if (this->rr && this->addr) { ++ if (this->rr && this->addr && ++ !defaults_use_hostname_for_mounts()) { + socklen_t len = INET6_ADDRSTRLEN; + char n_buf[len + 1]; + const char *n_addr; +--- autofs-5.0.7.orig/modules/replicated.c ++++ autofs-5.0.7/modules/replicated.c +@@ -667,6 +667,12 @@ int prune_host_list(unsigned logopt, str + if (!*list) + return 0; + ++ /* If we're using the host name then there's no point probing ++ * avialability and respose time. ++ */ ++ if (defaults_use_hostname_for_mounts()) ++ return 1; ++ + /* Use closest hosts to choose NFS version */ + + first = *list; +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -142,6 +142,14 @@ mount_nfs_default_protocol = 4 + # + #map_hash_table_size = 1024 + # ++# use_hostname_for_mounts - nfs mounts where the host name resolves ++# to more than one IP address normally need ++# to use the IP address to esure a mount to ++# a host that isn't responding isn't done. ++# If that behaviour is not wanted then set ++# ths to "yes", default is "no". ++# ++#use_hostname_for_mounts = "no" + # + # Otions for the amd parser within autofs. + # +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -141,6 +141,14 @@ browse_mode = no + # + #map_hash_table_size = 1024 + # ++# use_hostname_for_mounts - nfs mounts where the host name resolves ++# to more than one IP address normally need ++# to use the IP address to esure a mount to ++# a host that isn't responding isn't done. ++# If that behaviour is not wanted then set ++# ths to "yes", default is "no". ++# ++#use_hostname_for_mounts = "no" + # + # Otions for the amd parser within autofs. + # diff --git a/SOURCES/autofs-5.1.1-add-reinit-entry-point-to-modules.patch b/SOURCES/autofs-5.1.1-add-reinit-entry-point-to-modules.patch new file mode 100644 index 0000000..0c801a9 --- /dev/null +++ b/SOURCES/autofs-5.1.1-add-reinit-entry-point-to-modules.patch @@ -0,0 +1,666 @@ +autofs-5.1.1 - add reinit entry point to modules + +From: Ian Kent + +In order to avoid closing and then re-opening lookup modules +on HUP signal (since there init entry point needs to be called +for initialization) add a reinit entry point to lookup, parse +and mount modules. + +Signed-off-by: Ian Kent +--- + daemon/module.c | 39 +++++++++++++++++++++++++++++++++++++++ + include/automount.h | 15 +++++++++++++++ + modules/lookup_dir.c | 9 ++++++++- + modules/lookup_file.c | 9 ++++++++- + modules/lookup_hesiod.c | 9 ++++++++- + modules/lookup_hosts.c | 9 ++++++++- + modules/lookup_ldap.c | 9 ++++++++- + modules/lookup_multi.c | 9 ++++++++- + modules/lookup_nisplus.c | 9 ++++++++- + modules/lookup_program.c | 9 ++++++++- + modules/lookup_sss.c | 9 ++++++++- + modules/lookup_userhome.c | 9 ++++++++- + modules/lookup_yp.c | 9 ++++++++- + modules/mount_afs.c | 5 +++++ + modules/mount_autofs.c | 5 +++++ + modules/mount_bind.c | 5 +++++ + modules/mount_changer.c | 5 +++++ + modules/mount_ext2.c | 5 +++++ + modules/mount_generic.c | 5 +++++ + modules/mount_nfs.c | 5 +++++ + modules/parse_amd.c | 5 +++++ + modules/parse_hesiod.c | 5 +++++ + modules/parse_sun.c | 5 +++++ + 23 files changed, 192 insertions(+), 11 deletions(-) + +diff --git a/daemon/module.c b/daemon/module.c +index 9028aaa..3bd7a0c 100644 +--- a/daemon/module.c ++++ b/daemon/module.c +@@ -105,6 +105,7 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + } + + if (!(mod->lookup_init = (lookup_init_t) dlsym(dh, "lookup_init")) || ++ !(mod->lookup_reinit = (lookup_reinit_t) dlsym(dh, "lookup_reinit")) || + !(mod->lookup_read_master = (lookup_read_master_t) dlsym(dh, "lookup_read_master")) || + !(mod->lookup_read_map = (lookup_read_map_t) dlsym(dh, "lookup_read_map")) || + !(mod->lookup_mount = (lookup_mount_t) dlsym(dh, "lookup_mount")) || +@@ -127,6 +128,19 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + return NSS_STATUS_SUCCESS; + } + ++int reinit_lookup(struct lookup_mod *mod, const char *name, ++ const char *err_prefix, const char *mapfmt, ++ int argc, const char *const *argv) ++{ ++ if (mod->lookup_reinit(mapfmt, argc, argv, &mod->context)) { ++ if (err_prefix) ++ logerr("%scould not reinit lookup module %s", ++ err_prefix, name); ++ return 1; ++ } ++ return 0; ++} ++ + int close_lookup(struct lookup_mod *mod) + { + int rv = mod->lookup_done(mod->context); +@@ -185,6 +199,7 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix, + } + + if (!(mod->parse_init = (parse_init_t) dlsym(dh, "parse_init")) || ++ !(mod->parse_reinit = (parse_reinit_t) dlsym(dh, "parse_reinit")) || + !(mod->parse_mount = (parse_mount_t) dlsym(dh, "parse_mount")) || + !(mod->parse_done = (parse_done_t) dlsym(dh, "parse_done"))) { + if (err_prefix) +@@ -204,6 +219,18 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix, + return mod; + } + ++int reinit_parse(struct parse_mod *mod, const char *name, ++ const char *err_prefix, int argc, const char *const *argv) ++{ ++ if (mod->parse_reinit(argc, argv, &mod->context)) { ++ if (err_prefix) ++ logerr("%scould not reinit parse module %s", ++ err_prefix, name); ++ return 1; ++ } ++ return 0; ++} ++ + int close_parse(struct parse_mod *mod) + { + int rv = mod->parse_done(mod->context); +@@ -261,6 +288,7 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix) + } + + if (!(mod->mount_init = (mount_init_t) dlsym(dh, "mount_init")) || ++ !(mod->mount_reinit = (mount_reinit_t) dlsym(dh, "mount_reinit")) || + !(mod->mount_mount = (mount_mount_t) dlsym(dh, "mount_mount")) || + !(mod->mount_done = (mount_done_t) dlsym(dh, "mount_done"))) { + if (err_prefix) +@@ -280,6 +308,17 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix) + return mod; + } + ++int reinit_mount(struct mount_mod *mod, const char *name, const char *err_prefix) ++{ ++ if (mod->mount_reinit(&mod->context)) { ++ if (err_prefix) ++ logerr("%scould not reinit mount module %s", ++ err_prefix, name); ++ return 1; ++ } ++ return 0; ++} ++ + int close_mount(struct mount_mod *mod) + { + int rv = mod->mount_done(mod->context); +diff --git a/include/automount.h b/include/automount.h +index d614c10..ab3e360 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -281,12 +281,14 @@ int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key); + + #ifdef MODULE_LOOKUP + int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context); ++int lookup_reinit(const char *mapfmt, int argc, const char *const *argv, void **context); + int lookup_read_master(struct master *master, time_t age, void *context); + int lookup_read_map(struct autofs_point *, time_t, void *context); + int lookup_mount(struct autofs_point *, const char *, int, void *); + int lookup_done(void *); + #endif + typedef int (*lookup_init_t) (const char *, int, const char *const *, void **); ++typedef int (*lookup_reinit_t) (const char *, int, const char *const *, void **); + typedef int (*lookup_read_master_t) (struct master *master, time_t, void *); + typedef int (*lookup_read_map_t) (struct autofs_point *, time_t, void *); + typedef int (*lookup_mount_t) (struct autofs_point *, const char *, int, void *); +@@ -294,6 +296,7 @@ typedef int (*lookup_done_t) (void *); + + struct lookup_mod { + lookup_init_t lookup_init; ++ lookup_reinit_t lookup_reinit; + lookup_read_master_t lookup_read_master; + lookup_read_map_t lookup_read_map; + lookup_mount_t lookup_mount; +@@ -304,6 +307,9 @@ struct lookup_mod { + + int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + int argc, const char *const *argv, struct lookup_mod **lookup); ++int reinit_lookup(struct lookup_mod *mod, const char *name, ++ const char *err_prefix, const char *mapfmt, ++ int argc, const char *const *argv); + int close_lookup(struct lookup_mod *); + + /* parse module */ +@@ -312,16 +318,19 @@ int close_lookup(struct lookup_mod *); + + #ifdef MODULE_PARSE + int parse_init(int argc, const char *const *argv, void **context); ++int parse_reinit(int argc, const char *const *argv, void **context); + int parse_mount(struct autofs_point *ap, const char *name, + int name_len, const char *mapent, void *context); + int parse_done(void *); + #endif + typedef int (*parse_init_t) (int, const char *const *, void **); ++typedef int (*parse_reinit_t) (int, const char *const *, void **); + typedef int (*parse_mount_t) (struct autofs_point *, const char *, int, const char *, void *); + typedef int (*parse_done_t) (void *); + + struct parse_mod { + parse_init_t parse_init; ++ parse_reinit_t parse_reinit; + parse_mount_t parse_mount; + parse_done_t parse_done; + void *dlhandle; +@@ -330,6 +339,8 @@ struct parse_mod { + + struct parse_mod *open_parse(const char *name, const char *err_prefix, + int argc, const char *const *argv); ++int reinit_parse(struct parse_mod *, const char *name, ++ const char *err_prefix, int argc, const char *const *argv); + int close_parse(struct parse_mod *); + + /* mount module */ +@@ -338,17 +349,20 @@ int close_parse(struct parse_mod *); + + #ifdef MODULE_MOUNT + int mount_init(void **context); ++int mount_reinit(void **context); + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context); + int mount_done(void *context); + #endif + typedef int (*mount_init_t) (void **); ++typedef int (*mount_reinit_t) (void **); + typedef int (*mount_mount_t) (struct autofs_point *, const char *, const char *, int, + const char *, const char *, const char *, void *); + typedef int (*mount_done_t) (void *); + + struct mount_mod { + mount_init_t mount_init; ++ mount_reinit_t mount_reinit; + mount_mount_t mount_mount; + mount_done_t mount_done; + void *dlhandle; +@@ -356,6 +370,7 @@ struct mount_mod { + }; + + struct mount_mod *open_mount(const char *name, const char *err_prefix); ++int reinit_mount(struct mount_mod *mod, const char *name, const char *err_prefix); + int close_mount(struct mount_mod *); + + /* buffer management */ +diff --git a/modules/lookup_dir.c b/modules/lookup_dir.c +index cbeda1f..7a95e24 100644 +--- a/modules/lookup_dir.c ++++ b/modules/lookup_dir.c +@@ -51,7 +51,8 @@ struct lookup_context { + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -105,6 +106,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + static int acceptable_dirent_p(const struct dirent *e) + { + size_t namesz; +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index 7c982c6..c32a4cd 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -50,7 +50,8 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -112,6 +113,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + static int read_one(unsigned logopt, FILE *f, char *key, unsigned int *k_len, char *mapent, unsigned int *m_len) + { + char *kptr, *p; +diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c +index 526f294..de5ec08 100644 +--- a/modules/lookup_hesiod.c ++++ b/modules/lookup_hesiod.c +@@ -39,7 +39,8 @@ int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + + /* This initializes a context (persistent non-global data) for queries to + this module. */ +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt = NULL; + char buf[MAX_ERR_BUF]; +@@ -96,6 +97,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + return NSS_STATUS_UNKNOWN; +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index 53aa9d6..8ba0a4a 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -46,7 +46,8 @@ int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option); + void rpc_exports_free(exports list); + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -73,6 +74,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + return NSS_STATUS_UNKNOWN; +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index d846d8e..0f5bc48 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -1687,7 +1687,8 @@ static void validate_uris(struct list_head *list) + * This initializes a context (persistent non-global data) for queries to + * this module. Return zero if we succeed. + */ +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + unsigned int is_amd_format; + struct lookup_context *ctxt; +@@ -1835,6 +1836,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index ba8d4f0..0ee20f5 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -150,7 +150,8 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + return NULL; + } + +-int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *my_mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -244,6 +245,12 @@ error_out: + return 1; + } + ++int lookup_reinit(const char *my_mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + return NSS_STATUS_UNKNOWN; +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index d5eba47..0c66152 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -30,7 +30,8 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -76,6 +77,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index a3a7e98..fa4f54d 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -49,7 +49,8 @@ struct parse_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -100,6 +101,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + return NSS_STATUS_UNKNOWN; +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 720b5e3..c58a272 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -56,7 +56,8 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -137,6 +138,12 @@ lib_names_fail: + return 1; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + static int setautomntent(unsigned int logopt, + struct lookup_context *ctxt, const char *mapname, + void **sss_ctxt) +diff --git a/modules/lookup_userhome.c b/modules/lookup_userhome.c +index fb3caaa..c21dee9 100644 +--- a/modules/lookup_userhome.c ++++ b/modules/lookup_userhome.c +@@ -29,7 +29,14 @@ + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; /* Nothing to do */ ++} ++ ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + return 0; /* Nothing to do */ + } +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index fcf470a..1e5a7ed 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -103,7 +103,8 @@ static unsigned int get_map_order(const char *domain, const char *map) + return (unsigned int) last_changed; + } + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -165,6 +166,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int yp_all_master_callback(int status, char *ypkey, int ypkeylen, + char *val, int vallen, char *ypcb_data) + { +diff --git a/modules/mount_afs.c b/modules/mount_afs.c +index 50628ce..2a776bd 100644 +--- a/modules/mount_afs.c ++++ b/modules/mount_afs.c +@@ -25,6 +25,11 @@ int mount_init(void **context) + return 0; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context) + { +diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c +index 4846e7f..39948e6 100644 +--- a/modules/mount_autofs.c ++++ b/modules/mount_autofs.c +@@ -39,6 +39,11 @@ int mount_init(void **context) + return 0; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, + int name_len, const char *what, const char *fstype, + const char *c_options, void *context) +diff --git a/modules/mount_bind.c b/modules/mount_bind.c +index ac954e3..4864ea5 100644 +--- a/modules/mount_bind.c ++++ b/modules/mount_bind.c +@@ -67,6 +67,11 @@ out: + return 0; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context) + { +diff --git a/modules/mount_changer.c b/modules/mount_changer.c +index 5e2b47c..798f23b 100644 +--- a/modules/mount_changer.c ++++ b/modules/mount_changer.c +@@ -41,6 +41,11 @@ int mount_init(void **context) + return 0; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context) + { +diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c +index 3c87512..c00e3d5 100644 +--- a/modules/mount_ext2.c ++++ b/modules/mount_ext2.c +@@ -33,6 +33,11 @@ int mount_init(void **context) + return 0; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context) + { +diff --git a/modules/mount_generic.c b/modules/mount_generic.c +index c4108e6..ae63787 100644 +--- a/modules/mount_generic.c ++++ b/modules/mount_generic.c +@@ -33,6 +33,11 @@ int mount_init(void **context) + return 0; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, + void *context) +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 315fc99..15e1043 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -54,6 +54,11 @@ int mount_init(void **context) + return !mount_bind; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, + void *context) +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 2e3d21f..0626bf4 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -130,6 +130,11 @@ int parse_init(int argc, const char *const *argv, void **context) + return 0; + } + ++int parse_reinit(int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + static struct substvar *add_lookup_vars(struct autofs_point *ap, + const char *key, int key_len, + struct map_source *source, +diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c +index 237fd50..0b2b57f 100644 +--- a/modules/parse_hesiod.c ++++ b/modules/parse_hesiod.c +@@ -261,6 +261,11 @@ int parse_init(int argc, const char *const *argv, void **context) + return 0; + } + ++int parse_reinit(int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int parse_done(void *context) + { + return 0; +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 10dbd0c..35d6da5 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -413,6 +413,11 @@ options_done: + return 0; + } + ++int parse_reinit(int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + static const char *parse_options(const char *str, char **ret, unsigned int logopt) + { + const char *cp = str; diff --git a/SOURCES/autofs-5.1.1-add-remote-fs-target-systemd-dependency.patch b/SOURCES/autofs-5.1.1-add-remote-fs-target-systemd-dependency.patch new file mode 100644 index 0000000..cb71d92 --- /dev/null +++ b/SOURCES/autofs-5.1.1-add-remote-fs-target-systemd-dependency.patch @@ -0,0 +1,35 @@ +autofs-5.1.1 - add remote-fs.target systemd dependency + +From: Ian Kent + +If maps are stored on a NFS mount autofs will fail to start if the +systemd unit doesn't depend on the remote-fs target. + +I'm not sure how this will affect systems that don't have anything +to depend on in the remote-fs target but I expect it will not stop +the startup from functioning. +--- + CHANGELOG | 1 + + samples/autofs.service.in | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -183,6 +183,7 @@ + - update map_hash_table_size description. + - fix out of order call in program map lookup. + - make service want network-online. ++- add remote-fs.target systemd dependency. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/samples/autofs.service.in ++++ autofs-5.0.7/samples/autofs.service.in +@@ -1,6 +1,6 @@ + [Unit] + Description=Automounts filesystems on demand +-After=network.target ypbind.service sssd.service network-online.target ++After=network.target ypbind.service sssd.service network-online.target remote-fs.target + Wants=network-online.target + + [Service] diff --git a/SOURCES/autofs-5.1.1-add-type-to-struct-lookup_mod.patch b/SOURCES/autofs-5.1.1-add-type-to-struct-lookup_mod.patch new file mode 100644 index 0000000..3b148e0 --- /dev/null +++ b/SOURCES/autofs-5.1.1-add-type-to-struct-lookup_mod.patch @@ -0,0 +1,101 @@ +autofs-5.1.1 - add type to struct lookup_mod + +From: Ian Kent + +Add opened map type field to struct lookup_mod for module comparison +during reinit. + +Signed-off-by: Ian Kent +--- + daemon/module.c | 18 ++++++++++++++++++ + include/automount.h | 1 + + 2 files changed, 19 insertions(+) + +diff --git a/daemon/module.c b/daemon/module.c +index 3bd7a0c..d9921f4 100644 +--- a/daemon/module.c ++++ b/daemon/module.c +@@ -61,6 +61,7 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + char buf[MAX_ERR_BUF]; + char fnbuf[PATH_MAX]; + size_t size; ++ char *type; + void *dh; + int *ver; + +@@ -75,10 +76,20 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + return NSS_STATUS_UNAVAIL; + } + ++ type = strdup(name); ++ if (!type) { ++ free(mod); ++ if (err_prefix) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr("%s%s", err_prefix, estr); ++ } ++ } ++ + size = snprintf(fnbuf, sizeof(fnbuf), + "%s/lookup_%s.so", AUTOFS_LIB_DIR, name); + if (size >= sizeof(fnbuf)) { + free(mod); ++ free(type); + if (err_prefix) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr("%s%s", err_prefix, estr); +@@ -91,6 +102,7 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + logerr("%scannot open lookup module %s (%s)", + err_prefix, name, dlerror()); + free(mod); ++ free(type); + return NSS_STATUS_UNAVAIL; + } + +@@ -101,6 +113,7 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + err_prefix, name); + dlclose(dh); + free(mod); ++ free(type); + return NSS_STATUS_UNAVAIL; + } + +@@ -114,14 +127,18 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + logerr("%slookup module %s corrupt", err_prefix, name); + dlclose(dh); + free(mod); ++ free(type); + return NSS_STATUS_UNAVAIL; + } + + if (mod->lookup_init(mapfmt, argc, argv, &mod->context)) { + dlclose(dh); + free(mod); ++ free(type); + return NSS_STATUS_NOTFOUND; + } ++ ++ mod->type = type; + mod->dlhandle = dh; + *lookup = mod; + +@@ -145,6 +162,7 @@ int close_lookup(struct lookup_mod *mod) + { + int rv = mod->lookup_done(mod->context); + dlclose(mod->dlhandle); ++ free(mod->type); + free(mod); + return rv; + } +diff --git a/include/automount.h b/include/automount.h +index ab3e360..3ea2381 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -301,6 +301,7 @@ struct lookup_mod { + lookup_read_map_t lookup_read_map; + lookup_mount_t lookup_mount; + lookup_done_t lookup_done; ++ char *type; + void *dlhandle; + void *context; + }; diff --git a/SOURCES/autofs-5.1.1-always-set-direct-mounts-catatonic-at-exit.patch b/SOURCES/autofs-5.1.1-always-set-direct-mounts-catatonic-at-exit.patch new file mode 100644 index 0000000..fa70990 --- /dev/null +++ b/SOURCES/autofs-5.1.1-always-set-direct-mounts-catatonic-at-exit.patch @@ -0,0 +1,187 @@ +autofs-5.1.1 - always set direct mounts catatonic at exit + +From: Ian Kent + +Direct mounts are all mounted at application start or when the map +is re-read and entries have been added. + +They are only ever umounted at application exit or when the map is +re-read and entries have been removed. + +If these mounts are in use (so that they are not umounted) and aren't +set catatonic at exit and an application attempts to access the path +it will lead to a hang as there is no daemon to answer the mount +request. + +It's questionable whether to set busy direct mounts catatonic when +attempting to umount them when re-reading the map as the mount may +then expire leaving an unresponsive direct mount trigger that hasn't +yet been cleaned from the map entry cache. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/direct.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++----- + 2 files changed, 92 insertions(+), 8 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -186,6 +186,7 @@ + - add remote-fs.target systemd dependency. + - gaurd against incorrect umount return. + - fix typo in autofs.conf. ++- always set direct mounts catatonic at exit. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/direct.c ++++ autofs-5.0.7/daemon/direct.c +@@ -82,6 +82,65 @@ static void mnts_cleanup(void *arg) + return; + } + ++/* When exiting direct mount triggers must be set catatonic, regardless ++ * of whether they are busy on not, to avoid a hang on access once the ++ * daemon has gone away. ++ */ ++static int set_direct_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd) ++{ ++ struct ioctl_ops *ops = get_ioctl_ops(); ++ unsigned int opened = 0; ++ char buf[MAX_ERR_BUF]; ++ int fd = -1; ++ int error; ++ ++ /* In case the miscellaneous device isn't being used try ++ * and use an existing ioctl control fd. In this case if ++ * we don't already have an ioctl fd the mount can't be ++ * set catatonic if it's covered. ++ */ ++ if (ioctlfd >= 0) ++ fd = ioctlfd; ++ else if (me->ioctlfd >= 0) ++ fd = me->ioctlfd; ++ else { ++ error = ops->open(ap->logopt, &fd, me->dev, me->key); ++ if (error == -1) { ++ int err = errno; ++ char *estr; ++ ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ "failed to open ioctlfd for %s, error: %s", ++ me->key, estr); ++ return err; ++ } ++ opened = 1; ++ } ++ ++ if (fd >= 0) { ++ error = ops->catatonic(ap->logopt, fd); ++ if (error == -1) { ++ int err = errno; ++ char *estr; ++ ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ "failed to set %s catatonic, error: %s", ++ me->key, estr); ++ if (opened) ++ ops->close(ap->logopt, fd); ++ return err; ++ } ++ if (opened) ++ ops->close(ap->logopt, fd); ++ } ++ ++ debug(ap->logopt, "set %s catatonic", me->key); ++ ++ return 0; ++} ++ + int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me) + { + struct ioctl_ops *ops = get_ioctl_ops(); +@@ -97,7 +156,8 @@ int do_umount_autofs_direct(struct autof + } + + if (me->ioctlfd != -1) { +- if (tree_is_mounted(mnts, me->key, MNTS_REAL)) { ++ if (ap->state == ST_READMAP && ++ tree_is_mounted(mnts, me->key, MNTS_REAL)) { + error(ap->logopt, + "attempt to umount busy direct mount %s", + me->key); +@@ -116,7 +176,12 @@ int do_umount_autofs_direct(struct autof + if (rv) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, "ioctl failed: %s", estr); +- if (opened && ioctlfd != -1) ++ /* The ioctl failed so this probably won't ++ * work either but since we opened it here ++ * try anyway. We should set these catatonic ++ * too but .... ++ */ ++ if (opened) + ops->close(ap->logopt, ioctlfd); + return 1; + } else if (!status) { +@@ -124,18 +189,20 @@ int do_umount_autofs_direct(struct autof + error(ap->logopt, + "ask umount returned busy for %s", + me->key); +- if (opened && ioctlfd != -1) ++ if (ap->state != ST_READMAP) ++ set_direct_mount_catatonic(ap, me, ioctlfd); ++ if (opened) + ops->close(ap->logopt, ioctlfd); + return 1; + } else { + me->ioctlfd = -1; +- ops->catatonic(ap->logopt, ioctlfd); ++ set_direct_mount_catatonic(ap, me, ioctlfd); + ops->close(ap->logopt, ioctlfd); + goto force_umount; + } + } + me->ioctlfd = -1; +- ops->catatonic(ap->logopt, ioctlfd); ++ set_direct_mount_catatonic(ap, me, ioctlfd); + ops->close(ap->logopt, ioctlfd); + } else { + error(ap->logopt, +@@ -212,15 +279,31 @@ int umount_autofs_direct(struct autofs_p + cache_readlock(mc); + me = cache_enumerate(mc, NULL); + while (me) { ++ int error; ++ + ne = cache_lookup_distinct(nc, me->key); + if (ne && map->master_line > ne->age) { + me = cache_enumerate(mc, me); + continue; + } + +- /* TODO: check return, locking me */ +- do_umount_autofs_direct(ap, mnts, me); +- ++ /* The daemon is exiting so ... ++ * If we get a fail here we must make our ++ * best effort to set the direct mount trigger ++ * catatonic regardless of the reason for the ++ * failed umount. ++ */ ++ error = do_umount_autofs_direct(ap, mnts, me); ++ if (!error) ++ goto done; ++ ++ error = set_direct_mount_catatonic(ap, me, me->ioctlfd); ++ if (!error) ++ goto done; ++ ++ /* We really need to set this, last ditch attempt */ ++ set_direct_mount_catatonic(ap, me, -1); ++done: + me = cache_enumerate(mc, me); + } + pthread_cleanup_pop(1); diff --git a/SOURCES/autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch b/SOURCES/autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch new file mode 100644 index 0000000..0879443 --- /dev/null +++ b/SOURCES/autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch @@ -0,0 +1,73 @@ +autofs-5.1.1 - change lookup to use reinit instead of reopen + +From: Ian Kent + +When a HUP signal is received lookup module are cloed and then re-opened. +This can occassionally cause a problem with library data segemets and +lead to a SEGV. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 32 +++++++++++++++++++++----------- + 2 files changed, 22 insertions(+), 11 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -195,6 +195,7 @@ + - fix gcc5 complaints. + - fix missing source sss in multi map lookup. + - fix update_hosts_mounts() return. ++- change lookup to use reinit instead of reopen. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -300,17 +300,27 @@ static int do_read_map(struct autofs_poi + struct lookup_mod *lookup; + int status; + +- status = open_lookup(map->type, "", map->format, +- map->argc, map->argv, &lookup); +- if (status != NSS_STATUS_SUCCESS) { +- debug(ap->logopt, "lookup module %s failed", map->type); +- return status; +- } +- ++ lookup = NULL; + master_source_writelock(ap->entry); +- if (map->lookup) +- close_lookup(map->lookup); +- map->lookup = lookup; ++ if (!map->lookup) { ++ status = open_lookup(map->type, "", map->format, ++ map->argc, map->argv, &lookup); ++ if (status != NSS_STATUS_SUCCESS) { ++ master_source_unlock(ap->entry); ++ debug(ap->logopt, ++ "lookup module %s open failed", map->type); ++ return status; ++ } ++ map->lookup = lookup; ++ } else { ++ lookup = map->lookup; ++ status = lookup->lookup_reinit(map->format, ++ map->argc, map->argv, ++ &lookup->context); ++ if (status) ++ warn(ap->logopt, ++ "lookup module %s reinit failed", map->type); ++ } + master_source_unlock(ap->entry); + + if (!map->stale) +@@ -742,7 +752,7 @@ int do_lookup_mount(struct autofs_point + map->format, map->argc, map->argv, &lookup); + if (status != NSS_STATUS_SUCCESS) { + debug(ap->logopt, +- "lookup module %s failed", map->type); ++ "lookup module %s open failed", map->type); + return status; + } + map->lookup = lookup; diff --git a/SOURCES/autofs-5.1.1-factor-out-alloc-multi-map-context.patch b/SOURCES/autofs-5.1.1-factor-out-alloc-multi-map-context.patch new file mode 100644 index 0000000..f42e418 --- /dev/null +++ b/SOURCES/autofs-5.1.1-factor-out-alloc-multi-map-context.patch @@ -0,0 +1,203 @@ +autofs-5.1.1 - factor out alloc multi map context + +From: Ian Kent + +Seperate out the context allocation function for the multi map module. + +Signed-off-by: Ian Kent +--- + modules/lookup_multi.c | 161 +++++++++++++++++++++++++----------------------- + 1 file changed, 85 insertions(+), 76 deletions(-) + +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index 36ace11..433b424 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -40,6 +40,84 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + ++static int free_multi_context(struct lookup_context *); ++ ++static struct lookup_context *alloc_context(const char *format, ++ int argc, const char *const *argv) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ char **args; ++ int i, an; ++ char *estr; ++ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) ++ goto nomem; ++ ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ if (argc < 1) { ++ logerr(MODPREFIX "No map list"); ++ goto error_out; ++ } ++ ++ ctxt->n = 1; /* Always at least one map */ ++ for (i = 0; i < argc; i++) { ++ if (!strcmp(argv[i], "--")) /* -- separates maps */ ++ ctxt->n++; ++ } ++ ++ if (!(ctxt->m = malloc(ctxt->n * sizeof(struct module_info))) || ++ !(ctxt->argl = malloc((argc + 1) * sizeof(const char *)))) ++ goto nomem; ++ ++ memset(ctxt->m, 0, ctxt->n * sizeof(struct module_info)); ++ ++ 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) ++ args = (char **) &ctxt->argl[an]; ++ ++ if (strcmp(ctxt->argl[an], "--")) ++ ctxt->m[i].argc++; ++ else { ++ ctxt->argl[an] = NULL; ++ if (!args) { ++ logerr(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++; ++ } ++ } ++ ++ /* 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; ++ } ++ ++ return ctxt; ++ ++nomem: ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "error: %s", estr); ++ ++error_out: ++ free_multi_context(ctxt); ++ free(ctxt); ++ ++ return NULL; ++} ++ + static int free_multi_context(struct lookup_context *ctxt) + { + int rv; +@@ -180,95 +258,26 @@ 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 **args; +- int i, an; +- char *estr; ++ int i; + +- ctxt = malloc(sizeof(struct lookup_context)); ++ ctxt = alloc_context(my_mapfmt, argc, argv); + if (!ctxt) +- goto nomem; +- +- memset(ctxt, 0, sizeof(struct lookup_context)); +- +- if (argc < 1) { +- logerr(MODPREFIX "No map list"); +- goto error_out; +- } +- +- ctxt->n = 1; /* Always at least one map */ +- for (i = 0; i < argc; i++) { +- if (!strcmp(argv[i], "--")) /* -- separates maps */ +- ctxt->n++; +- } +- +- if (!(ctxt->m = malloc(ctxt->n * sizeof(struct module_info))) || +- !(ctxt->argl = malloc((argc + 1) * sizeof(const char *)))) +- goto nomem; +- +- memset(ctxt->m, 0, ctxt->n * sizeof(struct module_info)); +- +- 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) { +- args = (char **) &ctxt->argl[an]; +- } +- if (!strcmp(ctxt->argl[an], "--")) { +- ctxt->argl[an] = NULL; +- if (!args) { +- logerr(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++; +- } +- } +- +- /* 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; +- } ++ return 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) { + logerr(MODPREFIX "error opening module"); +- goto error_out; ++ free_multi_context(ctxt); ++ free(ctxt); ++ return 1; + } + } + + *context = ctxt; +- return 0; + +-nomem: +- estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "error: %s", estr); +-error_out: +- if (ctxt) { +- if (ctxt->m) { +- 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); +- } +- free(ctxt->m); +- } +- if (ctxt->argl) +- free(ctxt->argl); +- free(ctxt); +- } +- return 1; ++ return 0; + } + + int lookup_reinit(const char *my_mapfmt, diff --git a/SOURCES/autofs-5.1.1-factor-out-free-multi-map-context.patch b/SOURCES/autofs-5.1.1-factor-out-free-multi-map-context.patch new file mode 100644 index 0000000..19670bd --- /dev/null +++ b/SOURCES/autofs-5.1.1-factor-out-free-multi-map-context.patch @@ -0,0 +1,68 @@ +autofs-5.1.1 - factor out free multi map context + +From: Ian Kent + +Seperate out the free context function for the multi map module. + +Signed-off-by: Ian Kent +--- + modules/lookup_multi.c | 38 +++++++++++++++++++++++++++++--------- + 1 file changed, 29 insertions(+), 9 deletions(-) + +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index 0ee20f5..36ace11 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -40,6 +40,32 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + ++static int free_multi_context(struct lookup_context *ctxt) ++{ ++ int rv; ++ ++ if (!ctxt) ++ return 0; ++ ++ rv = 0; ++ if (ctxt->m) { ++ int i; ++ ++ 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->m); ++ } ++ ++ if (ctxt->argl) ++ free(ctxt->argl); ++ ++ return rv; ++} ++ + static struct lookup_mod *nss_open_lookup(const char *format, int argc, const char **argv) + { + struct list_head nsslist; +@@ -306,16 +332,10 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + int lookup_done(void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- int i, rv = 0; ++ int rv; + +- 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); ++ rv = free_multi_context(ctxt); + free(ctxt); ++ + return rv; + } diff --git a/SOURCES/autofs-5.1.1-fix-config-old-name-lookup.patch b/SOURCES/autofs-5.1.1-fix-config-old-name-lookup.patch new file mode 100644 index 0000000..ccf77c9 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-config-old-name-lookup.patch @@ -0,0 +1,54 @@ +autofs-5.1.1 - fix config old name lookup + +From: Ian Kent + +There are three cases needed to handle configuration name lookup. + +First there's the configuration key name, the name match is case +insensitive so the recent case change isn't a seperate case. + +But the much older configuration key names that began with "DEFAULT_" +need special handling. + +There are two cases that need to be covered: +1) an old name is given but a new name needs to be located. +2) a new name is given but an old name needs to be located. + +Only 1) is currently covered, so fix that in conf_lookup(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/defaults.c | 11 +++++++++++ + 2 files changed, 12 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -190,6 +190,7 @@ + - log pipe read errors. + - fix rwlock unlock crash. + - fix handle_mounts() termination condition check. ++- fix config old name lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -727,6 +727,17 @@ static struct conf_option *conf_lookup(c + */ + if (strlen(key) > 8 && !strncasecmp("DEFAULT_", key, 8)) + co = conf_lookup_key(section, key + 8); ++ else { ++ /* A new key name has been given but the value ++ * we seek is stored under an old key name (which ++ * includes the "DEFAULT_" prefix or doesn't exist. ++ */ ++ char old_key[PATH_MAX + 1]; ++ ++ strcpy(old_key, "DEFAULT_"); ++ strcat(old_key, key); ++ co = conf_lookup_key(section, old_key); ++ } + } + + return co; diff --git a/SOURCES/autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch b/SOURCES/autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch new file mode 100644 index 0000000..8c637d8 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch @@ -0,0 +1,87 @@ +autofs-5.1.1 - fix error handling on ldap bind fail + +From: Ian Kent + +When calling unbind_ldap_connection() if a sasl connection is +being used then autofs_sasl_unbind() should be called and not +ldap_unbind_ext(), otherwise the ldap connection release code +could be called twice. + +So, in unbind_ldap_connection() check if a sasl connection is in +use and unbind it if it is otherwise call ldap_unbind_ext() to +release the ldap connection. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 17 ++++++++++------- + 2 files changed, 11 insertions(+), 7 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -191,6 +191,7 @@ + - fix rwlock unlock crash. + - fix handle_mounts() termination condition check. + - fix config old name lookup. ++- fix error handling on ldap bind fail. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -216,15 +216,18 @@ int bind_ldap_simple(unsigned logopt, LD + + int __unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) + { +- int rv; ++ int rv = LDAP_SUCCESS; + + if (ctxt->use_tls == LDAP_TLS_RELEASE) + ctxt->use_tls = LDAP_TLS_INIT; + #ifdef WITH_SASL +- autofs_sasl_unbind(ctxt); +-#endif +- ++ if (ctxt->auth_required & LDAP_NEED_AUTH) ++ autofs_sasl_unbind(ctxt); ++ else ++ rv = ldap_unbind_ext(ldap, NULL, NULL); ++#else + rv = ldap_unbind_ext(ldap, NULL, NULL); ++#endif + if (rv != LDAP_SUCCESS) + error(logopt, "unbind failed: %s", ldap_err2string(rv)); + +@@ -302,7 +305,7 @@ LDAP *__init_ldap_connection(unsigned lo + + rv = ldap_start_tls_s(ldap, NULL, NULL); + if (rv != LDAP_SUCCESS) { +- __unbind_ldap_connection(logopt, ldap, ctxt); ++ ldap_unbind_ext(ldap, NULL, NULL); + if (ctxt->tls_required) { + error(logopt, MODPREFIX + "TLS required but START_TLS failed: %s", +@@ -576,14 +579,13 @@ static int do_bind(unsigned logopt, LDAP + char *host = NULL, *nhost; + int rv; + ++ ldapinit_mutex_lock(); + #ifdef WITH_SASL + debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s", + ctxt->auth_required, ctxt->sasl_mech); + + if (ctxt->auth_required & LDAP_NEED_AUTH) { +- ldapinit_mutex_lock(); + rv = autofs_sasl_bind(logopt, ldap, ctxt); +- ldapinit_mutex_unlock(); + debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv); + } else { + rv = bind_ldap_simple(logopt, ldap, uri, ctxt); +@@ -593,6 +595,7 @@ static int do_bind(unsigned logopt, LDAP + rv = bind_ldap_simple(logopt, ldap, uri, ctxt); + debug(logopt, MODPREFIX "ldap simple bind returned %d", rv); + #endif ++ ldapinit_mutex_unlock(); + + if (rv != 0) + return 0; diff --git a/SOURCES/autofs-5.1.1-fix-fix-gcc5-complaints.patch b/SOURCES/autofs-5.1.1-fix-fix-gcc5-complaints.patch new file mode 100644 index 0000000..6880f65 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-fix-gcc5-complaints.patch @@ -0,0 +1,23 @@ +autofs-5.1.1 - fix fix gcc5 complaints + +From: Ian Kent + +Remove a stray declare of dump_core(). + +Signed-off-by: Ian Kent +--- + lib/rpc_subs.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 846c40e..84fae9e 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -77,7 +77,6 @@ static const rpcvers_t mount_vers[] = { + }; + + static int connect_nb(int, struct sockaddr *, socklen_t, struct timeval *); +-inline void dump_core(void); + + /* + * Perform a non-blocking connect on the socket fd. diff --git a/SOURCES/autofs-5.1.1-fix-handle_mounts-termination-condition-check.patch b/SOURCES/autofs-5.1.1-fix-handle_mounts-termination-condition-check.patch new file mode 100644 index 0000000..1da74b8 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-handle_mounts-termination-condition-check.patch @@ -0,0 +1,239 @@ +autofs-5.1.1 - fix handle_mounts() termination condition check + +From: Ian Kent + +In get_pkt(), if a kernel request is present on the kernel pipe and +the autofs mount point state changes to ST_SHUTDOWN after the poll(2) +check but before the request has been processed the handle_mounts() +thread will exit without shutting down the autofs mount point. + +So change the handle_mounts() exit condition check to take account +of this case. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 191 ++++++++++++++++++++++++++++------------------------- + 2 files changed, 105 insertions(+), 87 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -189,6 +189,7 @@ + - always set direct mounts catatonic at exit. + - log pipe read errors. + - fix rwlock unlock crash. ++- fix handle_mounts() termination condition check. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -1659,6 +1659,99 @@ static void submount_source_unlock_neste + master_source_unlock(parent->entry); + } + ++int handle_mounts_exit(struct autofs_point *ap) ++{ ++ int ret, cur_state; ++ ++ /* ++ * If we're a submount we need to ensure our parent ++ * doesn't try to mount us again until our shutdown ++ * is complete and that any outstanding mounts are ++ * completed before we try to shutdown. ++ */ ++ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); ++ ++ master_mutex_lock(); ++ ++ if (!ap->submount) ++ master_source_writelock(ap->entry); ++ else { ++ /* ++ * If a mount request arrives before the locks are ++ * aquired just return to ready state. ++ */ ++ ret = submount_source_writelock_nested(ap); ++ if (ret) { ++ warn(ap->logopt, ++ "can't shutdown submount: mount in progress"); ++ /* Return to ST_READY is done immediately */ ++ st_add_task(ap, ST_READY); ++ master_mutex_unlock(); ++ pthread_setcancelstate(cur_state, NULL); ++ return 0; ++ } ++ } ++ ++ if (ap->state != ST_SHUTDOWN) { ++ if (!ap->submount) ++ alarm_add(ap, ap->exp_runfreq); ++ /* Return to ST_READY is done immediately */ ++ st_add_task(ap, ST_READY); ++ if (ap->submount) ++ submount_source_unlock_nested(ap); ++ else ++ master_source_unlock(ap->entry); ++ master_mutex_unlock(); ++ ++ pthread_setcancelstate(cur_state, NULL); ++ return 0; ++ } ++ ++ alarm_delete(ap); ++ st_remove_tasks(ap); ++ st_wait_task(ap, ST_ANY, 0); ++ ++ /* ++ * For a direct mount map all mounts have already gone ++ * by the time we get here and since we only ever ++ * umount direct mounts at shutdown there is no need ++ * to check for possible recovery. ++ */ ++ if (ap->type == LKP_DIRECT) { ++ umount_autofs(ap, NULL, 1); ++ handle_mounts_cleanup(ap); ++ return 1; ++ } ++ ++ /* ++ * If umount_autofs returns non-zero it wasn't able ++ * to complete the umount and has left the mount intact ++ * so we can continue. This can happen if a lookup ++ * occurs while we're trying to umount. ++ */ ++ ret = umount_autofs(ap, NULL, 1); ++ if (!ret) { ++ handle_mounts_cleanup(ap); ++ return 1; ++ } ++ ++ /* Failed shutdown returns to ready */ ++ warn(ap->logopt, "can't shutdown: filesystem %s still busy", ap->path); ++ if (!ap->submount) ++ alarm_add(ap, ap->exp_runfreq); ++ /* Return to ST_READY is done immediately */ ++ st_add_task(ap, ST_READY); ++ if (ap->submount) ++ submount_source_unlock_nested(ap); ++ else ++ master_source_unlock(ap->entry); ++ master_mutex_unlock(); ++ ++ pthread_setcancelstate(cur_state, NULL); ++ ++ return 0; ++} ++ + void *handle_mounts(void *arg) + { + struct startup_cond *suc; +@@ -1714,97 +1807,21 @@ void *handle_mounts(void *arg) + + pthread_setcancelstate(cancel_state, NULL); + +- while (ap->state != ST_SHUTDOWN) { ++ while (1) { + if (handle_packet(ap)) { +- int ret, cur_state; +- +- /* +- * If we're a submount we need to ensure our parent +- * doesn't try to mount us again until our shutdown +- * is complete and that any outstanding mounts are +- * completed before we try to shutdown. +- */ +- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- +- master_mutex_lock(); +- +- if (ap->submount) { +- /* +- * If a mount request arrives before the locks are +- * aquired just return to ready state. +- */ +- ret = submount_source_writelock_nested(ap); +- if (ret) { +- warn(ap->logopt, +- "can't shutdown submount: mount in progress"); +- /* Return to ST_READY is done immediately */ +- st_add_task(ap, ST_READY); +- master_mutex_unlock(); +- pthread_setcancelstate(cur_state, NULL); +- continue; +- } +- } else +- master_source_writelock(ap->entry); +- +- if (ap->state != ST_SHUTDOWN) { +- if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); +- /* Return to ST_READY is done immediately */ +- st_add_task(ap, ST_READY); +- if (ap->submount) +- submount_source_unlock_nested(ap); +- else +- master_source_unlock(ap->entry); +- master_mutex_unlock(); +- +- pthread_setcancelstate(cur_state, NULL); +- continue; +- } +- +- alarm_delete(ap); +- st_remove_tasks(ap); +- st_wait_task(ap, ST_ANY, 0); +- +- /* +- * For a direct mount map all mounts have already gone +- * by the time we get here and since we only ever +- * umount direct mounts at shutdown there is no need +- * to check for possible recovery. +- */ +- if (ap->type == LKP_DIRECT) { +- umount_autofs(ap, NULL, 1); +- handle_mounts_cleanup(ap); ++ if (handle_mounts_exit(ap)) + break; +- } ++ } + +- /* +- * If umount_autofs returns non-zero it wasn't able +- * to complete the umount and has left the mount intact +- * so we can continue. This can happen if a lookup +- * occurs while we're trying to umount. +- */ +- ret = umount_autofs(ap, NULL, 1); +- if (!ret) { +- handle_mounts_cleanup(ap); ++ /* If we get here a packet has been received and handled ++ * and the autofs mount point has not been shutdown. But ++ * if the autofs mount point has been set to ST_SHUTDOWN ++ * we should attempt to perform the shutdown cleanup and ++ * exit if successful. ++ */ ++ if (ap->state == ST_SHUTDOWN) { ++ if (handle_mounts_exit(ap)) + break; +- } +- +- /* Failed shutdown returns to ready */ +- warn(ap->logopt, +- "can't shutdown: filesystem %s still busy", +- ap->path); +- if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); +- /* Return to ST_READY is done immediately */ +- st_add_task(ap, ST_READY); +- if (ap->submount) +- submount_source_unlock_nested(ap); +- else +- master_source_unlock(ap->entry); +- master_mutex_unlock(); +- +- pthread_setcancelstate(cur_state, NULL); +- + } + } + diff --git a/SOURCES/autofs-5.1.1-fix-map-format-check-in-nss_open_lookup-multi-map-module.patch b/SOURCES/autofs-5.1.1-fix-map-format-check-in-nss_open_lookup-multi-map-module.patch new file mode 100644 index 0000000..21ca47d --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-map-format-check-in-nss_open_lookup-multi-map-module.patch @@ -0,0 +1,47 @@ +autofs-5.1.1 - fix map format check in nss_open_lookup() multi map module + +From: Ian Kent + +The nss_open_lookup() function doesn't properly allow for map format when +it's given with the map type. + +Signed-off-by: Ian Kent +--- + modules/lookup_multi.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index 433b424..f8ebf94 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -24,6 +24,8 @@ + #include "automount.h" + #include "nsswitch.h" + ++#define MAX_MAP_TYPE_STRING 20 ++ + #define MODPREFIX "lookup(multi): " + + struct module_info { +@@ -166,11 +168,17 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + !strncmp(argv[0], "ldaps", 5) || + !strncmp(argv[0], "ldap", 4) || + !strncmp(argv[0], "sss", 3)) { +- const char *fmt = strchr(argv[0], ','); +- if (fmt) ++ char type[MAX_MAP_TYPE_STRING]; ++ char *fmt; ++ ++ strcpy(type, argv[0]); ++ fmt = strchr(type, ','); ++ if (!fmt) ++ fmt = (char *) format; ++ else { ++ *fmt = '\0'; + fmt++; +- else +- fmt = format; ++ } + open_lookup(argv[0], MODPREFIX, fmt, argc - 1, argv + 1, &mod); + return mod; + } diff --git a/SOURCES/autofs-5.1.1-fix-memory-leak-in-ldap-do_init.patch b/SOURCES/autofs-5.1.1-fix-memory-leak-in-ldap-do_init.patch new file mode 100644 index 0000000..e043ce4 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-memory-leak-in-ldap-do_init.patch @@ -0,0 +1,33 @@ +autofs-5.1.1 - fix memory leak in ldap do_init() + +From: Ian Kent + +Fix error return without free of temporory allocated storage in +do_init(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 1 + + 2 files changed, 2 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -199,6 +199,7 @@ + - fix unbind sasl external mech. + - fix sasl connection concurrancy problem. + - fix memory leak in nisplus lookup_reinit(). ++- fix memory leak in ldap do_init(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -1752,6 +1752,7 @@ static int do_init(const char *mapfmt, + */ + if (!parse_server_string(LOGOPT_NONE, tmp, ctxt)) { + error(LOGOPT_ANY, MODPREFIX "cannot parse server string"); ++ free(tmp); + return 1; + } + free(tmp); diff --git a/SOURCES/autofs-5.1.1-fix-memory-leak-in-nisplus-lookup_reinit.patch b/SOURCES/autofs-5.1.1-fix-memory-leak-in-nisplus-lookup_reinit.patch new file mode 100644 index 0000000..23cc485 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-memory-leak-in-nisplus-lookup_reinit.patch @@ -0,0 +1,36 @@ +autofs-5.1.1 - fix memory leak in nisplus lookup_reinit() + +From: Ian Kent + +Don't forget to free context on reinit error. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_nisplus.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -198,6 +198,7 @@ + - change lookup to use reinit instead of reopen. + - fix unbind sasl external mech. + - fix sasl connection concurrancy problem. ++- fix memory leak in nisplus lookup_reinit(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_nisplus.c ++++ autofs-5.0.7/modules/lookup_nisplus.c +@@ -116,8 +116,10 @@ int lookup_reinit(const char *mapfmt, + + new->parse = ctxt->parse; + ret = do_init(mapfmt, argc, argv, new, 1); +- if (ret) ++ if (ret) { ++ free(new); + return 1; ++ } + + *context = new; + diff --git a/SOURCES/autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch b/SOURCES/autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch new file mode 100644 index 0000000..f5a10c7 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch @@ -0,0 +1,34 @@ +autofs-5.1.1 - fix missing source sss in multi map lookup + +From: Ian Kent + +The sss source isn't accounted for in the multi map lookup module. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_multi.c | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -193,6 +193,7 @@ + - fix config old name lookup. + - fix error handling on ldap bind fail. + - fix gcc5 complaints. ++- fix missing source sss in multi map lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_multi.c ++++ autofs-5.0.7/modules/lookup_multi.c +@@ -58,7 +58,8 @@ static struct lookup_mod *nss_open_looku + !strncmp(argv[0], "nisplus", 7) || + !strncmp(argv[0], "nis", 3) || + !strncmp(argv[0], "ldaps", 5) || +- !strncmp(argv[0], "ldap", 4)) { ++ !strncmp(argv[0], "ldap", 4) || ++ !strncmp(argv[0], "sss", 3)) { + const char *fmt = strchr(argv[0], ','); + if (fmt) + fmt++; diff --git a/SOURCES/autofs-5.1.1-fix-nameing-typo-in-autofs-conf.patch b/SOURCES/autofs-5.1.1-fix-nameing-typo-in-autofs-conf.patch new file mode 100644 index 0000000..906ea55 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-nameing-typo-in-autofs-conf.patch @@ -0,0 +1,46 @@ +autofs-5.1.1 - fix 'nameing' typo in autofs.conf + +From: Ian Kent + +Change nameing to naming at about line 118 in autofs package default +configurations. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + redhat/autofs.conf.default.in | 2 +- + samples/autofs.conf.default.in | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -185,6 +185,7 @@ + - make service want network-online. + - add remote-fs.target systemd dependency. + - gaurd against incorrect umount return. ++- fix typo in autofs.conf. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -115,7 +115,7 @@ mount_nfs_default_protocol = 4 + #entry_attribute = cn + #value_attribute= nisMapEntry + # +-# Other common LDAP nameing ++# Other common LDAP naming + # + #map_object_class = automountMap + #entry_object_class = automount +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -114,7 +114,7 @@ browse_mode = no + #entry_attribute = cn + #value_attribute= nisMapEntry + # +-# Other common LDAP nameing ++# Other common LDAP naming + # + #map_object_class = automountMap + #entry_object_class = automount diff --git a/SOURCES/autofs-5.1.1-fix-nsswitch-handling-when-opening-multi-map.patch b/SOURCES/autofs-5.1.1-fix-nsswitch-handling-when-opening-multi-map.patch new file mode 100644 index 0000000..720eaf2 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-nsswitch-handling-when-opening-multi-map.patch @@ -0,0 +1,48 @@ +autofs-5.1.1 - fix nsswitch handling when opening multi map + +From: Ian Kent + +When initializing the lookup module for multi-map entries nsswitch +actions should be honoured to the extent they can be. In particular +the case of a map not found should use an nsswitch action (if present) +to work out whether to continue looking or return a failure. + +Signed-off-by: Ian Kent +--- + modules/lookup_multi.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index 55035e4..ba8d4f0 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -84,6 +84,7 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + list_for_each(p, head) { + struct nss_source *this; + int status; ++ int ret; + + this = list_entry(p, struct nss_source, list); + +@@ -127,6 +128,10 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + + argv[0] = save_argv0; + free(path); ++ ++ ret = check_nss_result(this, status); ++ if (ret >= 0) ++ break; + } + + status = open_lookup(this->source, MODPREFIX, +@@ -135,6 +140,10 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + free_sources(&nsslist); + return mod; + } ++ ++ ret = check_nss_result(this, status); ++ if (ret >= 0) ++ break; + } + free_sources(&nsslist); + diff --git a/SOURCES/autofs-5.1.1-fix-rwlock-unlock-crash.patch b/SOURCES/autofs-5.1.1-fix-rwlock-unlock-crash.patch new file mode 100644 index 0000000..d52bcfe --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-rwlock-unlock-crash.patch @@ -0,0 +1,63 @@ +autofs-5.1.1 - fix rwlock unlock crash + +From: Ian Kent + +It should be the case that the only way that automount can exit +the kernel communication read loop is after reading a packet and +performing shutdown operations. + +However there are reports of pthread_rwlock_unlock() being called +from the exit cleanup function when the lock it is trying to unlock +is not held. + +But the call to the cleanup function is outside the communication +loop so call it from each of the loop break points instead so that +the expected locks must be held. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 7 ++++--- + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -188,6 +188,7 @@ + - fix typo in autofs.conf. + - always set direct mounts catatonic at exit. + - log pipe read errors. ++- fix rwlock unlock crash. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -1773,6 +1773,7 @@ void *handle_mounts(void *arg) + */ + if (ap->type == LKP_DIRECT) { + umount_autofs(ap, NULL, 1); ++ handle_mounts_cleanup(ap); + break; + } + +@@ -1783,8 +1784,10 @@ void *handle_mounts(void *arg) + * occurs while we're trying to umount. + */ + ret = umount_autofs(ap, NULL, 1); +- if (!ret) ++ if (!ret) { ++ handle_mounts_cleanup(ap); + break; ++ } + + /* Failed shutdown returns to ready */ + warn(ap->logopt, +@@ -1805,8 +1808,6 @@ void *handle_mounts(void *arg) + } + } + +- handle_mounts_cleanup(ap); +- + return NULL; + } + diff --git a/SOURCES/autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch b/SOURCES/autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch new file mode 100644 index 0000000..02671a9 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch @@ -0,0 +1,828 @@ +autofs-5.1.1 - fix sasl connection concurrancy problem + +From: Ian Kent + +After using the contributed Cyrus SASL code in autofs for years I've +finally looked at the Cyrus SASL C API RFC only to find that the +library isn't thread safe unless a connection context per thread is +used, similar to the LDAP library. + +To be fair this code originated prior to the threaded version of +autofs so it's my bad I didn't check. + +But having seen this I have no choice but to make the sasl context +per thread not per autofs lookup context. + +Also extend the mutual exclusion even further. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/lookup_ldap.h | 16 ++-- + modules/cyrus-sasl.c | 46 ++++++----- + modules/lookup_ldap.c | 198 +++++++++++++++++++++++++------------------------- + 4 files changed, 136 insertions(+), 125 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -197,6 +197,7 @@ + - fix update_hosts_mounts() return. + - change lookup to use reinit instead of reopen. + - fix unbind sasl external mech. ++- fix sasl connection concurrancy problem. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/lookup_ldap.h ++++ autofs-5.0.7/include/lookup_ldap.h +@@ -34,6 +34,13 @@ struct ldap_searchdn { + struct ldap_searchdn *next; + }; + ++struct ldap_conn { ++ LDAP *ldap; ++#ifdef WITH_SASL ++ sasl_conn_t *sasl_conn; ++#endif ++}; ++ + struct lookup_context { + char *mapname; + unsigned int format; +@@ -86,7 +93,6 @@ struct lookup_context { + /* Kerberos */ + krb5_context krb5ctxt; + krb5_ccache krb5_ccache; +- sasl_conn_t *sasl_conn; + /* SASL external */ + char *extern_cert; + char *extern_key; +@@ -113,16 +119,16 @@ struct lookup_context { + + /* lookup_ldap.c */ + 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 unbind_ldap_connection(unsigned logopt, struct ldap_conn *conn, struct lookup_context *ctxt); + int authtype_requires_creds(const char *authtype); + + #ifdef WITH_SASL + /* cyrus-sasl.c */ + int autofs_sasl_client_init(unsigned logopt); + 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(LDAP *ldap, struct lookup_context *ctxt); +-void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt); ++int autofs_sasl_bind(unsigned logopt, struct ldap_conn *conn, struct lookup_context *ctxt); ++void autofs_sasl_unbind(struct ldap_conn *conn, struct lookup_context *ctxt); ++void autofs_sasl_dispose(struct ldap_conn *conn, struct lookup_context *ctxt); + void autofs_sasl_done(void); + /* cyrus-sasl-extern */ + int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt); +--- autofs-5.0.7.orig/modules/cyrus-sasl.c ++++ autofs-5.0.7/modules/cyrus-sasl.c +@@ -855,16 +855,19 @@ sasl_choose_mech(unsigned logopt, LDAP * + * Routine called when unbinding an ldap connection. + */ + void +-autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt) ++autofs_sasl_unbind(struct ldap_conn *conn, struct lookup_context *ctxt) + { + if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) { +- ldap_unbind_s(ldap); ++ if (conn->ldap) { ++ ldap_unbind_s(conn->ldap); ++ conn->ldap = NULL; ++ } + return; + } + +- if (ctxt->sasl_conn) { +- sasl_dispose(&ctxt->sasl_conn); +- ctxt->sasl_conn = NULL; ++ if (conn->sasl_conn) { ++ sasl_dispose(&conn->sasl_conn); ++ conn->sasl_conn = NULL; + } + } + +@@ -878,13 +881,10 @@ autofs_sasl_unbind(LDAP *ldap, struct lo + * -1 - Failure + */ + int +-autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) ++autofs_sasl_bind(unsigned logopt, ++ struct ldap_conn *conn, struct lookup_context *ctxt) + { +- sasl_conn_t *conn = NULL; +- +- /* If we already have a connection use it */ +- if (ctxt->sasl_conn) +- return 0; ++ sasl_conn_t *sasl_conn = NULL; + + if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) { + int result; +@@ -893,7 +893,7 @@ autofs_sasl_bind(unsigned logopt, LDAP * + "Attempting sasl bind with mechanism %s", + ctxt->sasl_mech); + +- result = do_sasl_extern(ldap, ctxt); ++ result = do_sasl_extern(conn->ldap, ctxt); + if (result) + debug(logopt, + "Failed to authenticate with mech %s", +@@ -923,14 +923,16 @@ autofs_sasl_bind(unsigned logopt, LDAP * + * auth mechanism. + */ + if (ctxt->sasl_mech) +- conn = sasl_bind_mech(logopt, ldap, ctxt, ctxt->sasl_mech); ++ sasl_conn = sasl_bind_mech(logopt, ++ conn->ldap, ctxt, ctxt->sasl_mech); + else +- conn = sasl_choose_mech(logopt, ldap, ctxt); ++ sasl_conn = sasl_choose_mech(logopt, conn->ldap, ctxt); + + if (!conn) + return -1; + +- ctxt->sasl_conn = conn; ++ conn->sasl_conn = sasl_conn; ++ + return 0; + } + +@@ -938,19 +940,21 @@ autofs_sasl_bind(unsigned logopt, LDAP * + * Destructor routine. This should be called when finished with an ldap + * session. + */ +-void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt) ++void autofs_sasl_dispose(struct ldap_conn *conn, struct lookup_context *ctxt) + { + int status, ret; + + if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) { +- if (ldap) +- ldap_unbind_s(ldap); ++ if (conn && conn->ldap) { ++ ldap_unbind_s(conn->ldap); ++ conn->ldap = NULL; ++ } + return; + } + +- if (ctxt->sasl_conn) { +- sasl_dispose(&ctxt->sasl_conn); +- ctxt->sasl_conn = NULL; ++ if (conn && conn->sasl_conn) { ++ sasl_dispose(&conn->sasl_conn); ++ conn->sasl_conn = NULL; + } + + if (ctxt->kinit_successful) { +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -214,7 +214,9 @@ int bind_ldap_simple(unsigned logopt, LD + return 0; + } + +-int __unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) ++int __unbind_ldap_connection(unsigned logopt, ++ struct ldap_conn *conn, ++ struct lookup_context *ctxt) + { + int rv = LDAP_SUCCESS; + +@@ -222,30 +224,35 @@ int __unbind_ldap_connection(unsigned lo + ctxt->use_tls = LDAP_TLS_INIT; + #ifdef WITH_SASL + if (ctxt->auth_required & LDAP_NEED_AUTH) +- autofs_sasl_unbind(ldap, ctxt); +- else +- rv = ldap_unbind_ext(ldap, NULL, NULL); +-#else +- rv = ldap_unbind_ext(ldap, NULL, NULL); ++ autofs_sasl_unbind(conn, ctxt); ++ /* No, sasl_dispose does not release the ldap connection ++ * unless it's using sasl EXTERNAL ++ */ + #endif ++ if (conn->ldap) { ++ rv = ldap_unbind_ext(conn->ldap, NULL, NULL); ++ conn->ldap = NULL; ++ } + if (rv != LDAP_SUCCESS) + error(logopt, "unbind failed: %s", ldap_err2string(rv)); + + return rv; + } + +-int unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) ++int unbind_ldap_connection(unsigned logopt, ++ struct ldap_conn *conn, ++ struct lookup_context *ctxt) + { + int rv; + + ldapinit_mutex_lock(); +- rv = __unbind_ldap_connection(logopt, ldap, ctxt); ++ rv = __unbind_ldap_connection(logopt, conn, ctxt); + ldapinit_mutex_unlock(); + + return rv; + } + +-LDAP *__init_ldap_connection(unsigned logopt, 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 }; +@@ -313,7 +320,7 @@ LDAP *__init_ldap_connection(unsigned lo + return NULL; + } + ctxt->use_tls = LDAP_TLS_DONT_USE; +- ldap = __init_ldap_connection(logopt, uri, ctxt); ++ ldap = init_ldap_connection(logopt, uri, ctxt); + if (ldap) + ctxt->use_tls = LDAP_TLS_INIT; + return ldap; +@@ -324,17 +331,6 @@ LDAP *__init_ldap_connection(unsigned lo + return ldap; + } + +-LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt) +-{ +- LDAP *ldap; +- +- ldapinit_mutex_lock(); +- ldap = __init_ldap_connection(logopt, uri, ctxt); +- ldapinit_mutex_unlock(); +- +- return ldap; +-} +- + static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key) + { + char buf[MAX_ERR_BUF]; +@@ -574,33 +570,32 @@ static int find_query_dn(unsigned logopt + return 0; + } + +-static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt) ++static int do_bind(unsigned logopt, struct ldap_conn *conn, ++ const char *uri, struct lookup_context *ctxt) + { + char *host = NULL, *nhost; + int rv; + +- ldapinit_mutex_lock(); + #ifdef WITH_SASL + debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s", + ctxt->auth_required, ctxt->sasl_mech); + + if (ctxt->auth_required & LDAP_NEED_AUTH) { +- rv = autofs_sasl_bind(logopt, ldap, ctxt); ++ rv = autofs_sasl_bind(logopt, conn, ctxt); + debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv); + } else { +- rv = bind_ldap_simple(logopt, ldap, uri, ctxt); ++ rv = bind_ldap_simple(logopt, conn->ldap, uri, ctxt); + debug(logopt, MODPREFIX "ldap simple bind returned %d", rv); + } + #else +- rv = bind_ldap_simple(logopt, ldap, uri, ctxt); ++ rv = bind_ldap_simple(logopt, conn->ldap, uri, ctxt); + debug(logopt, MODPREFIX "ldap simple bind returned %d", rv); + #endif +- ldapinit_mutex_unlock(); + + if (rv != 0) + return 0; + +- rv = ldap_get_option(ldap, LDAP_OPT_HOST_NAME, &host); ++ rv = ldap_get_option(conn->ldap, LDAP_OPT_HOST_NAME, &host); + if (rv != LDAP_SUCCESS || !host) { + debug(logopt, "failed to get hostname for connection"); + return 0; +@@ -634,15 +629,12 @@ static int do_bind(unsigned logopt, LDAP + return 1; + } + +-static int do_connect(unsigned logopt, LDAP **ldap, ++static int do_connect(unsigned logopt, struct ldap_conn *conn, + const char *uri, struct lookup_context *ctxt) + { + char *cur_host = NULL; +- LDAP *handle; + int ret = NSS_STATUS_SUCCESS; + +- *ldap = NULL; +- + #ifdef WITH_SASL + if (ctxt->extern_cert && ctxt->extern_key) { + set_env(logopt, ENV_LDAPTLS_CERT, ctxt->extern_cert); +@@ -650,8 +642,8 @@ static int do_connect(unsigned logopt, L + } + #endif + +- handle = init_ldap_connection(logopt, uri, ctxt); +- if (!handle) { ++ conn->ldap = init_ldap_connection(logopt, uri, ctxt); ++ if (!conn->ldap) { + ret = NSS_STATUS_UNAVAIL; + goto out; + } +@@ -661,8 +653,8 @@ static int do_connect(unsigned logopt, L + cur_host = ctxt->cur_host; + uris_mutex_unlock(ctxt); + +- if (!do_bind(logopt, handle, uri, ctxt)) { +- unbind_ldap_connection(logopt, handle, ctxt); ++ if (!do_bind(logopt, conn, uri, ctxt)) { ++ __unbind_ldap_connection(logopt, conn, ctxt); + ret = NSS_STATUS_UNAVAIL; + goto out; + } +@@ -673,7 +665,6 @@ static int do_connect(unsigned logopt, L + uris_mutex_lock(ctxt); + if (ctxt->schema && ctxt->qdn && (cur_host == ctxt->cur_host)) { + uris_mutex_unlock(ctxt); +- *ldap = handle; + goto out; + } + uris_mutex_unlock(ctxt); +@@ -684,8 +675,8 @@ static int do_connect(unsigned logopt, L + * base dn for searches. + */ + if (!ctxt->schema) { +- if (!find_query_dn(logopt, handle, ctxt)) { +- unbind_ldap_connection(logopt, handle, ctxt); ++ if (!find_query_dn(logopt, conn->ldap, ctxt)) { ++ __unbind_ldap_connection(logopt, conn, ctxt); + ret = NSS_STATUS_NOTFOUND; + warn(logopt, + MODPREFIX "failed to find valid query dn"); +@@ -694,21 +685,21 @@ static int do_connect(unsigned logopt, L + } else if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) { + const char *class = ctxt->schema->map_class; + const char *key = ctxt->schema->map_attr; +- if (!get_query_dn(logopt, handle, ctxt, class, key)) { +- unbind_ldap_connection(logopt, handle, ctxt); ++ if (!get_query_dn(logopt, conn->ldap, ctxt, class, key)) { ++ __unbind_ldap_connection(logopt, conn, ctxt); + ret = NSS_STATUS_NOTFOUND; + error(logopt, MODPREFIX "failed to get query dn"); + goto out; + } + } + +- *ldap = handle; + out: + return ret; + } + + static unsigned long get_amd_timestamp(struct lookup_context *ctxt) + { ++ struct ldap_conn conn; + LDAP *ldap; + LDAPMessage *result = NULL, *e; + char *query; +@@ -719,9 +710,11 @@ static unsigned long get_amd_timestamp(s + unsigned long timestamp = 0; + int rv, l, ql; + +- rv = do_connect(LOGOPT_ANY, &ldap, ctxt->server, ctxt); ++ memset(&conn, 0, sizeof(struct ldap_conn)); ++ rv = do_connect(LOGOPT_ANY, &conn, ctxt->server, ctxt); + if (rv != NSS_STATUS_SUCCESS) + return 0; ++ ldap = conn.ldap; + + map = amd_timestamp.map_attr; + class = amd_timestamp.entry_class; +@@ -758,7 +751,7 @@ static unsigned long get_amd_timestamp(s + rv = ldap_search_s(ldap, ctxt->base, scope, query, attrs, 0, &result); + if ((rv != LDAP_SUCCESS) || !result) { + crit(LOGOPT_ANY, MODPREFIX "timestamp query failed %s", query); +- unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt); ++ unbind_ldap_connection(LOGOPT_ANY, &conn, ctxt); + if (result) + ldap_msgfree(result); + free(query); +@@ -770,7 +763,7 @@ static unsigned long get_amd_timestamp(s + debug(LOGOPT_ANY, + MODPREFIX "got answer, but no entry for timestamp"); + ldap_msgfree(result); +- unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt); ++ unbind_ldap_connection(LOGOPT_ANY, &conn, ctxt); + free(query); + return CHE_MISSING; + } +@@ -821,18 +814,18 @@ next: + } + + ldap_msgfree(result); +- unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt); ++ unbind_ldap_connection(LOGOPT_ANY, &conn, ctxt); + free(query); + + return timestamp; + } + +-static int connect_to_server(unsigned logopt, LDAP **ldap, ++static int connect_to_server(unsigned logopt, struct ldap_conn *conn, + const char *uri, struct lookup_context *ctxt) + { + int ret; + +- ret = do_connect(logopt, ldap, uri, ctxt); ++ ret = do_connect(logopt, conn, uri, ctxt); + if (ret != NSS_STATUS_SUCCESS) { + warn(logopt, + MODPREFIX "couldn't connect to server %s", +@@ -842,7 +835,7 @@ static int connect_to_server(unsigned lo + return ret; + } + +-static int find_dc_server(unsigned logopt, LDAP **ldap, ++static int find_dc_server(unsigned logopt, struct ldap_conn *conn, + const char *uri, struct lookup_context *ctxt) + { + char *str, *tok, *ptr = NULL; +@@ -858,7 +851,7 @@ static int find_dc_server(unsigned logop + int rv; + + debug(logopt, "trying server uri %s", this); +- rv = connect_to_server(logopt, ldap, this, ctxt); ++ rv = connect_to_server(logopt, conn, this, ctxt); + if (rv == NSS_STATUS_SUCCESS) { + info(logopt, "connected to uri %s", this); + free(str); +@@ -875,7 +868,7 @@ static int find_dc_server(unsigned logop + } + + static int find_server(unsigned logopt, +- LDAP **ldap, struct lookup_context *ctxt) ++ struct ldap_conn *conn, struct lookup_context *ctxt) + { + struct ldap_uri *this = NULL; + struct list_head *p, *first; +@@ -906,7 +899,7 @@ static int find_server(unsigned logopt, + if (!strstr(this->uri, ":///")) { + uri = strdup(this->uri); + debug(logopt, "trying server uri %s", uri); +- rv = connect_to_server(logopt, ldap, uri, ctxt); ++ rv = connect_to_server(logopt, conn, uri, ctxt); + if (rv == NSS_STATUS_SUCCESS) { + ret = NSS_STATUS_SUCCESS; + info(logopt, "connected to uri %s", uri); +@@ -928,7 +921,7 @@ static int find_server(unsigned logopt, + dclist = tmp; + uri = strdup(dclist->uri); + } +- rv = find_dc_server(logopt, ldap, uri, ctxt); ++ rv = find_dc_server(logopt, conn, uri, ctxt); + if (rv == NSS_STATUS_SUCCESS) { + ret = NSS_STATUS_SUCCESS; + free(uri); +@@ -947,7 +940,7 @@ static int find_server(unsigned logopt, + } + + uris_mutex_lock(ctxt); +- if (ldap) ++ if (conn->ldap) + ctxt->uri = this; + if (dclist) { + if (!ctxt->dclist) +@@ -965,37 +958,39 @@ static int find_server(unsigned logopt, + } + + static int do_reconnect(unsigned logopt, +- LDAP **ldap, struct lookup_context *ctxt) ++ struct ldap_conn *conn, struct lookup_context *ctxt) + { + int ret = NSS_STATUS_UNAVAIL; + int dcrv = NSS_STATUS_SUCCESS; + int rv = NSS_STATUS_SUCCESS; + ++ ldapinit_mutex_lock(); + if (ctxt->server || !ctxt->uris) { +- ret = do_connect(logopt, ldap, ctxt->server, ctxt); ++ ret = do_connect(logopt, conn, ctxt->server, ctxt); + #ifdef WITH_SASL + /* Dispose of the sasl authentication connection and try again. */ + if (ctxt->auth_required & LDAP_NEED_AUTH && + ret != NSS_STATUS_SUCCESS && ret != NSS_STATUS_NOTFOUND) { +- ldapinit_mutex_lock(); +- autofs_sasl_dispose(*ldap, ctxt); +- ldapinit_mutex_unlock(); +- ret = connect_to_server(logopt, ldap, ++ autofs_sasl_dispose(conn, ctxt); ++ ret = connect_to_server(logopt, conn, + ctxt->server, ctxt); + } + #endif ++ ldapinit_mutex_unlock(); + return ret; + } + + if (ctxt->dclist) { +- dcrv = find_dc_server(logopt, ldap, ctxt->dclist->uri, ctxt); +- if (dcrv == NSS_STATUS_SUCCESS) ++ dcrv = find_dc_server(logopt, conn, ctxt->dclist->uri, ctxt); ++ if (dcrv == NSS_STATUS_SUCCESS) { ++ ldapinit_mutex_unlock(); + return dcrv; ++ } + } + + uris_mutex_lock(ctxt); + if (ctxt->dclist) { +- if (!ldap || ctxt->dclist->expire < time(NULL)) { ++ if (!conn->ldap || ctxt->dclist->expire < time(NULL)) { + free_dclist(ctxt->dclist); + ctxt->dclist = NULL; + } +@@ -1009,7 +1004,7 @@ static int do_reconnect(unsigned logopt, + if (!ctxt->uri) + goto find_server; + +- rv = do_connect(logopt, ldap, ctxt->uri->uri, ctxt); ++ rv = do_connect(logopt, conn, ctxt->uri->uri, ctxt); + #ifdef WITH_SASL + /* + * Dispose of the sasl authentication connection and try the +@@ -1017,26 +1012,24 @@ static int do_reconnect(unsigned logopt, + */ + if (ctxt->auth_required & LDAP_NEED_AUTH && + rv != NSS_STATUS_SUCCESS && rv != NSS_STATUS_NOTFOUND) { +- ldapinit_mutex_lock(); +- autofs_sasl_dispose(*ldap, ctxt); +- ldapinit_mutex_unlock(); +- rv = connect_to_server(logopt, ldap, ctxt->uri->uri, ctxt); ++ autofs_sasl_dispose(conn, ctxt); ++ rv = connect_to_server(logopt, conn, ctxt->uri->uri, ctxt); + } + #endif +- if (rv == NSS_STATUS_SUCCESS) ++ if (rv == NSS_STATUS_SUCCESS) { ++ ldapinit_mutex_unlock(); + return rv; ++ } + + /* Failed to connect, try to find a new server */ + + find_server: + #ifdef WITH_SASL +- ldapinit_mutex_lock(); +- autofs_sasl_dispose(*ldap, ctxt); +- ldapinit_mutex_unlock(); ++ autofs_sasl_dispose(conn, ctxt); + #endif + + /* Current server failed, try the rest or dc connection */ +- ret = find_server(logopt, ldap, ctxt); ++ ret = find_server(logopt, conn, ctxt); + if (ret != NSS_STATUS_SUCCESS) { + if (ret == NSS_STATUS_NOTFOUND || + dcrv == NSS_STATUS_NOTFOUND || +@@ -1044,6 +1037,7 @@ find_server: + ret = NSS_STATUS_NOTFOUND; + error(logopt, MODPREFIX "failed to find available server"); + } ++ ldapinit_mutex_unlock(); + + return ret; + } +@@ -1877,11 +1871,6 @@ int lookup_reinit(const char *mapfmt, + + *context = new; + +-#ifdef WITH_SASL +- ldapinit_mutex_lock(); +- autofs_sasl_dispose(NULL, ctxt); +- ldapinit_mutex_unlock(); +-#endif + free_context(ctxt); + + return 0; +@@ -1893,6 +1882,8 @@ int lookup_read_master(struct master *ma + unsigned int timeout = master->default_timeout; + unsigned int logging = master->default_logging; + unsigned int logopt = master->logopt; ++ struct ldap_conn conn; ++ LDAP *ldap; + int rv, l, count; + char buf[MAX_ERR_BUF]; + char parse_buf[PARSE_MAX_BUF]; +@@ -1903,12 +1894,13 @@ int lookup_read_master(struct master *ma + char **values = NULL; + char *attrs[3]; + int scope = LDAP_SCOPE_SUBTREE; +- LDAP *ldap = NULL; + + /* Initialize the LDAP context. */ +- rv = do_reconnect(logopt, &ldap, ctxt); ++ memset(&conn, 0, sizeof(struct ldap_conn)); ++ rv = do_reconnect(logopt, &conn, ctxt); + if (rv) + return rv; ++ ldap = conn.ldap; + + class = ctxt->schema->entry_class; + entry = ctxt->schema->entry_attr; +@@ -1942,7 +1934,7 @@ int lookup_read_master(struct master *ma + if ((rv != LDAP_SUCCESS) || !result) { + error(logopt, MODPREFIX "query failed for %s: %s", + query, ldap_err2string(rv)); +- unbind_ldap_connection(logging, ldap, ctxt); ++ unbind_ldap_connection(logging, &conn, ctxt); + if (result) + ldap_msgfree(result); + free(query); +@@ -1955,7 +1947,7 @@ int lookup_read_master(struct master *ma + MODPREFIX "query succeeded, no matches for %s", + query); + ldap_msgfree(result); +- unbind_ldap_connection(logging, ldap, ctxt); ++ unbind_ldap_connection(logging, &conn, ctxt); + free(query); + return NSS_STATUS_NOTFOUND; + } else +@@ -2076,7 +2068,7 @@ next: + + /* Clean up. */ + ldap_msgfree(result); +- unbind_ldap_connection(logopt, ldap, ctxt); ++ unbind_ldap_connection(logopt, &conn, ctxt); + free(query); + + return NSS_STATUS_SUCCESS; +@@ -2796,6 +2788,7 @@ static int read_one_map(struct autofs_po + struct lookup_context *ctxt, + time_t age, int *result_ldap) + { ++ struct ldap_conn conn; + struct ldap_search_params sp; + char buf[MAX_ERR_BUF]; + char *class, *info, *entry; +@@ -2816,10 +2809,11 @@ static int read_one_map(struct autofs_po + sp.age = age; + + /* Initialize the LDAP context. */ +- sp.ldap = NULL; +- rv = do_reconnect(ap->logopt, &sp.ldap, ctxt); ++ memset(&conn, 0, sizeof(struct ldap_conn)); ++ rv = do_reconnect(ap->logopt, &conn, ctxt); + if (rv) + return rv; ++ sp.ldap = conn.ldap; + + class = ctxt->schema->entry_class; + entry = ctxt->schema->entry_attr; +@@ -2878,7 +2872,7 @@ static int read_one_map(struct autofs_po + if (sp.pageSize < 5) { + debug(ap->logopt, MODPREFIX + "result size too small"); +- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + *result_ldap = rv; + free(sp.query); + return NSS_STATUS_UNAVAIL; +@@ -2887,7 +2881,7 @@ static int read_one_map(struct autofs_po + } + + if (rv != LDAP_SUCCESS || !sp.result) { +- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + *result_ldap = rv; + if (sp.result) + ldap_msgfree(sp.result); +@@ -2903,7 +2897,7 @@ static int read_one_map(struct autofs_po + rv = do_get_entries(&sp, source, ctxt); + if (rv != LDAP_SUCCESS) { + ldap_msgfree(sp.result); +- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + *result_ldap = rv; + if (sp.cookie) + ber_bvfree(sp.cookie); +@@ -2916,7 +2910,7 @@ static int read_one_map(struct autofs_po + + debug(ap->logopt, MODPREFIX "done updating map"); + +- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + + source->age = age; + if (sp.cookie) +@@ -2959,6 +2953,8 @@ static int lookup_one(struct autofs_poin + char *qKey, int qKey_len, struct lookup_context *ctxt) + { + struct mapent_cache *mc; ++ struct ldap_conn conn; ++ LDAP *ldap; + int rv, i, l, ql, count; + char buf[MAX_ERR_BUF]; + time_t age = time(NULL); +@@ -2971,7 +2967,6 @@ static int lookup_one(struct autofs_poin + struct berval **bvValues; + char *attrs[3]; + int scope = LDAP_SCOPE_SUBTREE; +- LDAP *ldap = NULL; + struct mapent *we; + unsigned int wild = 0; + int ret = CHE_MISSING; +@@ -2984,11 +2979,13 @@ static int lookup_one(struct autofs_poin + } + + /* Initialize the LDAP context. */ +- rv = do_reconnect(ap->logopt, &ldap, ctxt); ++ memset(&conn, 0, sizeof(struct ldap_conn)); ++ rv = do_reconnect(ap->logopt, &conn, ctxt); + if (rv == NSS_STATUS_UNAVAIL) + return CHE_UNAVAIL; + if (rv == NSS_STATUS_NOTFOUND) + return ret; ++ ldap = conn.ldap; + + class = ctxt->schema->entry_class; + entry = ctxt->schema->entry_attr; +@@ -3076,7 +3073,7 @@ static int lookup_one(struct autofs_poin + + if ((rv != LDAP_SUCCESS) || !result) { + crit(ap->logopt, MODPREFIX "query failed for %s", query); +- unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + if (result) + ldap_msgfree(result); + free(query); +@@ -3091,7 +3088,7 @@ static int lookup_one(struct autofs_poin + debug(ap->logopt, + MODPREFIX "got answer, but no entry for %s", query); + ldap_msgfree(result); +- unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + free(query); + return CHE_MISSING; + } +@@ -3277,7 +3274,7 @@ next: + } + + ldap_msgfree(result); +- unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + + /* Failed to find wild entry, update cache if needed */ + cache_writelock(mc); +@@ -3317,7 +3314,8 @@ static int lookup_one_amd(struct autofs_ + struct lookup_context *ctxt) + { + struct mapent_cache *mc = source->mc; +- LDAP *ldap = NULL; ++ struct ldap_conn conn; ++ LDAP *ldap; + LDAPMessage *result = NULL, *e; + char *query; + int scope = LDAP_SCOPE_SUBTREE; +@@ -3336,11 +3334,13 @@ static int lookup_one_amd(struct autofs_ + } + + /* Initialize the LDAP context. */ +- rv = do_reconnect(ap->logopt, &ldap, ctxt); ++ memset(&conn, 0, sizeof(struct ldap_conn)); ++ rv = do_reconnect(ap->logopt, &conn, ctxt); + if (rv == NSS_STATUS_UNAVAIL) + return CHE_UNAVAIL; + if (rv == NSS_STATUS_NOTFOUND) + return ret; ++ ldap = conn.ldap; + + map = ctxt->schema->map_attr; + class = ctxt->schema->entry_class; +@@ -3382,7 +3382,7 @@ static int lookup_one_amd(struct autofs_ + rv = ldap_search_s(ldap, ctxt->base, scope, query, attrs, 0, &result); + if ((rv != LDAP_SUCCESS) || !result) { + crit(ap->logopt, MODPREFIX "query failed for %s", query); +- unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + if (result) + ldap_msgfree(result); + free(query); +@@ -3397,7 +3397,7 @@ static int lookup_one_amd(struct autofs_ + debug(ap->logopt, + MODPREFIX "got answer, but no entry for %s", query); + ldap_msgfree(result); +- unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + free(query); + return CHE_MISSING; + } +@@ -3459,7 +3459,7 @@ next: + } + + ldap_msgfree(result); +- unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + free(query); + + return ret; diff --git a/SOURCES/autofs-5.1.1-fix-typo-in-autofs_sasl_bind.patch b/SOURCES/autofs-5.1.1-fix-typo-in-autofs_sasl_bind.patch new file mode 100644 index 0000000..7e138c1 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-typo-in-autofs_sasl_bind.patch @@ -0,0 +1,33 @@ +autofs-5.1.1 - fix typo in autofs_sasl_bind() + +From: Ian Kent + +Changes to autofs_sasl_bind() introduced an incorrect variable reference. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/cyrus-sasl.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -202,6 +202,7 @@ + - fix memory leak in ldap do_init(). + - fix use after free in sun parser parse_init(). + - fix use after free in open_lookup(). ++- fix typo in autofs_sasl_bind(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/cyrus-sasl.c ++++ autofs-5.0.7/modules/cyrus-sasl.c +@@ -928,7 +928,7 @@ autofs_sasl_bind(unsigned logopt, + else + sasl_conn = sasl_choose_mech(logopt, conn->ldap, ctxt); + +- if (!conn) ++ if (!sasl_conn) + return -1; + + conn->sasl_conn = sasl_conn; diff --git a/SOURCES/autofs-5.1.1-fix-unbind-external-mech.patch b/SOURCES/autofs-5.1.1-fix-unbind-external-mech.patch new file mode 100644 index 0000000..a01cdaf --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-unbind-external-mech.patch @@ -0,0 +1,132 @@ +autofs-5.1.1 - fix unbind sasl external mech + +From: Ian Kent + +If the sasl EXTERNAL mechanism is being used autofs leaks ldap +connection resources. + +In this case the current ldap connection needs to be unbound +when calling autofs_sasl_unbind() or autofs_sasl_dispose(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/lookup_ldap.h | 4 ++-- + modules/cyrus-sasl.c | 15 +++++++++++++-- + modules/lookup_ldap.c | 12 ++++++------ + 4 files changed, 22 insertions(+), 10 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -196,6 +196,7 @@ + - fix missing source sss in multi map lookup. + - fix update_hosts_mounts() return. + - change lookup to use reinit instead of reopen. ++- fix unbind sasl external mech. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/lookup_ldap.h ++++ autofs-5.0.7/include/lookup_ldap.h +@@ -121,8 +121,8 @@ int authtype_requires_creds(const char * + int autofs_sasl_client_init(unsigned logopt); + 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_dispose(struct lookup_context *ctxt); ++void autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt); ++void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt); + void autofs_sasl_done(void); + /* cyrus-sasl-extern */ + int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt); +--- autofs-5.0.7.orig/modules/cyrus-sasl.c ++++ autofs-5.0.7/modules/cyrus-sasl.c +@@ -855,8 +855,13 @@ sasl_choose_mech(unsigned logopt, LDAP * + * Routine called when unbinding an ldap connection. + */ + void +-autofs_sasl_unbind(struct lookup_context *ctxt) ++autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt) + { ++ if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) { ++ ldap_unbind_s(ldap); ++ return; ++ } ++ + if (ctxt->sasl_conn) { + sasl_dispose(&ctxt->sasl_conn); + ctxt->sasl_conn = NULL; +@@ -933,10 +938,16 @@ autofs_sasl_bind(unsigned logopt, LDAP * + * Destructor routine. This should be called when finished with an ldap + * session. + */ +-void autofs_sasl_dispose(struct lookup_context *ctxt) ++void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt) + { + int status, ret; + ++ if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) { ++ if (ldap) ++ ldap_unbind_s(ldap); ++ return; ++ } ++ + if (ctxt->sasl_conn) { + sasl_dispose(&ctxt->sasl_conn); + ctxt->sasl_conn = NULL; +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -222,7 +222,7 @@ int __unbind_ldap_connection(unsigned lo + ctxt->use_tls = LDAP_TLS_INIT; + #ifdef WITH_SASL + if (ctxt->auth_required & LDAP_NEED_AUTH) +- autofs_sasl_unbind(ctxt); ++ autofs_sasl_unbind(ldap, ctxt); + else + rv = ldap_unbind_ext(ldap, NULL, NULL); + #else +@@ -978,7 +978,7 @@ static int do_reconnect(unsigned logopt, + if (ctxt->auth_required & LDAP_NEED_AUTH && + ret != NSS_STATUS_SUCCESS && ret != NSS_STATUS_NOTFOUND) { + ldapinit_mutex_lock(); +- autofs_sasl_dispose(ctxt); ++ autofs_sasl_dispose(*ldap, ctxt); + ldapinit_mutex_unlock(); + ret = connect_to_server(logopt, ldap, + ctxt->server, ctxt); +@@ -1018,7 +1018,7 @@ static int do_reconnect(unsigned logopt, + if (ctxt->auth_required & LDAP_NEED_AUTH && + rv != NSS_STATUS_SUCCESS && rv != NSS_STATUS_NOTFOUND) { + ldapinit_mutex_lock(); +- autofs_sasl_dispose(ctxt); ++ autofs_sasl_dispose(*ldap, ctxt); + ldapinit_mutex_unlock(); + rv = connect_to_server(logopt, ldap, ctxt->uri->uri, ctxt); + } +@@ -1031,7 +1031,7 @@ static int do_reconnect(unsigned logopt, + find_server: + #ifdef WITH_SASL + ldapinit_mutex_lock(); +- autofs_sasl_dispose(ctxt); ++ autofs_sasl_dispose(*ldap, ctxt); + ldapinit_mutex_unlock(); + #endif + +@@ -1879,7 +1879,7 @@ int lookup_reinit(const char *mapfmt, + + #ifdef WITH_SASL + ldapinit_mutex_lock(); +- autofs_sasl_dispose(ctxt); ++ autofs_sasl_dispose(NULL, ctxt); + ldapinit_mutex_unlock(); + #endif + free_context(ctxt); +@@ -3816,7 +3816,7 @@ int lookup_done(void *context) + int rv = close_parse(ctxt->parse); + #ifdef WITH_SASL + ldapinit_mutex_lock(); +- autofs_sasl_dispose(ctxt); ++ autofs_sasl_dispose(NULL, ctxt); + autofs_sasl_done(); + ldapinit_mutex_unlock(); + #endif diff --git a/SOURCES/autofs-5.1.1-fix-update_hosts_mounts-return.patch b/SOURCES/autofs-5.1.1-fix-update_hosts_mounts-return.patch new file mode 100644 index 0000000..d2c9b34 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-update_hosts_mounts-return.patch @@ -0,0 +1,55 @@ +autofs-5.1.1 - fix update_hosts_mounts() return + +From: Ian Kent + +The return of update_hosts_mounts() isn't used so set it to void type +and log a warning if the map entry fails the parse. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 11 ++++++----- + 2 files changed, 7 insertions(+), 5 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -194,6 +194,7 @@ + - fix error handling on ldap bind fail. + - fix gcc5 complaints. + - fix missing source sss in multi map lookup. ++- fix update_hosts_mounts() return. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_hosts.c ++++ autofs-5.0.7/modules/lookup_hosts.c +@@ -162,9 +162,9 @@ static int do_parse_mount(struct autofs_ + return NSS_STATUS_SUCCESS; + } + +-static int update_hosts_mounts(struct autofs_point *ap, +- struct map_source *source, time_t age, +- struct lookup_context *ctxt) ++static void update_hosts_mounts(struct autofs_point *ap, ++ struct map_source *source, time_t age, ++ struct lookup_context *ctxt) + { + struct mapent_cache *mc; + struct mapent *me; +@@ -212,13 +212,14 @@ next: + ap->flags |= MOUNT_FLAG_REMOUNT; + ret = ctxt->parse->parse_mount(ap, me->key, strlen(me->key), + me->mapent, ctxt->parse->context); ++ if (ret) ++ warn(ap->logopt, MODPREFIX ++ "failed to parse mount %s", me->mapent); + ap->flags &= ~MOUNT_FLAG_REMOUNT; + cont: + me = cache_lookup_next(mc, me); + } + pthread_cleanup_pop(1); +- +- return NSS_STATUS_SUCCESS; + } + + int lookup_read_map(struct autofs_point *ap, time_t age, void *context) diff --git a/SOURCES/autofs-5.1.1-fix-use-after-free-in-open_lookup.patch b/SOURCES/autofs-5.1.1-fix-use-after-free-in-open_lookup.patch new file mode 100644 index 0000000..20a2bfe --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-use-after-free-in-open_lookup.patch @@ -0,0 +1,32 @@ +autofs-5.1.1 - fix use after free in open_lookup() + +From: Ian Kent + +If storage can't be allocated for module type error exit. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/module.c | 1 + + 2 files changed, 2 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -201,6 +201,7 @@ + - fix memory leak in nisplus lookup_reinit(). + - fix memory leak in ldap do_init(). + - fix use after free in sun parser parse_init(). ++- fix use after free in open_lookup(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/module.c ++++ autofs-5.0.7/daemon/module.c +@@ -83,6 +83,7 @@ int open_lookup(const char *name, const + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr("%s%s", err_prefix, estr); + } ++ return NSS_STATUS_UNAVAIL; + } + + size = snprintf(fnbuf, sizeof(fnbuf), diff --git a/SOURCES/autofs-5.1.1-fix-use-after-free-in-sun-parser-parse_init.patch b/SOURCES/autofs-5.1.1-fix-use-after-free-in-sun-parser-parse_init.patch new file mode 100644 index 0000000..32211d9 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-use-after-free-in-sun-parser-parse_init.patch @@ -0,0 +1,33 @@ +autofs-5.1.1 - fix use after free in sun parser parse_init() + +From: Ian Kent + +Change to free context in function it was allocated (parse_init) on +error to avoid use after free. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -200,6 +200,7 @@ + - fix sasl connection concurrancy problem. + - fix memory leak in nisplus lookup_reinit(). + - fix memory leak in ldap do_init(). ++- fix use after free in sun parser parse_init(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -345,7 +345,6 @@ static int do_init(int argc, const char + } + if (!noptstr) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- kill_context(ctxt); + logerr(MODPREFIX "%s", estr); + return 1; + } diff --git a/SOURCES/autofs-5.1.1-fix-use-after-free-st_queue_handler.patch b/SOURCES/autofs-5.1.1-fix-use-after-free-st_queue_handler.patch new file mode 100644 index 0000000..207c80c --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-use-after-free-st_queue_handler.patch @@ -0,0 +1,37 @@ +autofs-5.1.1 - fix use-after-free in st_queue_handler() + +From: Frank Sorenson + +The task may be referenced after being freed. Move the +free to after the list_del_init. + +Signed-off-by: Frank Sorenson +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/state.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -204,6 +204,7 @@ + - fix use after free in open_lookup(). + - fix typo in autofs_sasl_bind(). + - add configuration option to use fqdn in mounts. ++- fix use-after-free in st_queue_handler(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/state.c ++++ autofs-5.0.7/daemon/state.c +@@ -1179,9 +1179,9 @@ remove: + struct state_queue, pending); + + list_del(&task->list); ++ list_del_init(&next->pending); + free(task); + +- list_del_init(&next->pending); + list_add_tail(&next->list, head); + if (p == head) + p = head->next; diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-file-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-file-lookup-module.patch new file mode 100644 index 0000000..fae1f5f --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-file-lookup-module.patch @@ -0,0 +1,147 @@ +autofs-5.1.1 - implement reinit in file lookup module + +From: Ian Kent + +Refactor the file lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_file.c | 85 +++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 65 insertions(+), 20 deletions(-) + +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index c32a4cd..aed3cba 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -50,23 +50,13 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) + { +- struct lookup_context *ctxt; +- char buf[MAX_ERR_BUF]; +- +- *context = NULL; +- +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "malloc: %s", estr); +- return 1; +- } ++ int ret = 0; + + if (argc < 1) { +- free(ctxt); + logerr(MODPREFIX "No map name"); + return 1; + } +@@ -74,14 +64,12 @@ int lookup_init(const char *mapfmt, + ctxt->mapname = argv[0]; + + if (ctxt->mapname[0] != '/') { +- free(ctxt); + logmsg(MODPREFIX + "file map %s is not an absolute pathname", argv[0]); + return 1; + } + + if (access(ctxt->mapname, R_OK)) { +- free(ctxt); + warn(LOGOPT_NONE, MODPREFIX + "file map %s missing or not readable", argv[0]); + return 1; +@@ -95,19 +83,51 @@ int lookup_init(const char *mapfmt, + + ctxt->opts_argv = copy_argv(argc, (const char **) argv); + if (ctxt->opts_argv == NULL) { +- free(ctxt); + warn(LOGOPT_NONE, MODPREFIX "failed to duplicate options"); + return 1; + } + ctxt->opts_argc = argc; + +- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc, argv); +- if (!ctxt->parse) { ++ if (reinit) { ++ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc, argv); ++ if (ret) ++ logmsg(MODPREFIX "failed to reinit parse context"); ++ } else { ++ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc, argv); ++ if (!ctxt->parse) { ++ logmsg(MODPREFIX "failed to open parse context"); ++ ret = 1; ++ } ++ } ++ ++ if (ret) + free_argv(ctxt->opts_argc, ctxt->opts_argv); ++ ++ return ret; ++} ++ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ ++ *context = NULL; ++ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ if (do_init(mapfmt, argc, argv, ctxt, 0)) { + free(ctxt); +- logmsg(MODPREFIX "failed to open parse context"); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -116,6 +136,31 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(new, 0, sizeof(struct lookup_context)); ++ ++ new->parse = ctxt->parse; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) { ++ free(new); ++ return 1; ++ } ++ ++ *context = new; ++ ++ free_argv(ctxt->opts_argc, ctxt->opts_argv); ++ free(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-hesiod-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-hesiod-lookup-module.patch new file mode 100644 index 0000000..1f060b9 --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-hesiod-lookup-module.patch @@ -0,0 +1,154 @@ +autofs-5.1.1 - implement reinit in hesiod lookup module + +From: Ian Kent + +Refactor the hesiod lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_hesiod.c | 96 ++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 74 insertions(+), 22 deletions(-) + +diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c +index de5ec08..c0f7f51 100644 +--- a/modules/lookup_hesiod.c ++++ b/modules/lookup_hesiod.c +@@ -37,24 +37,12 @@ static pthread_mutex_t hesiod_mutex = PTHREAD_MUTEX_INITIALIZER; + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-/* This initializes a context (persistent non-global data) for queries to +- this module. */ +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) + { +- struct lookup_context *ctxt = NULL; + char buf[MAX_ERR_BUF]; +- +- *context = NULL; +- +- /* If we can't build a context, bail. */ +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "malloc: %s", estr); +- return 1; +- } +- memset(ctxt, 0, sizeof(struct lookup_context)); ++ int ret = 0; + + /* Initialize the resolver. */ + res_init(); +@@ -63,7 +51,6 @@ int lookup_init(const char *mapfmt, + if (hesiod_init(&(ctxt->hesiod_context)) != 0) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "hesiod_init(): %s", estr); +- free(ctxt); + return 1; + } + +@@ -75,9 +62,9 @@ int lookup_init(const char *mapfmt, + /* amd formated hesiod maps have a map name */ + const char *mapname = argv[0]; + if (strncmp(mapname, AMD_MAP_PREFIX, AMD_MAP_PREFIX_LEN)) { ++ hesiod_end(ctxt->hesiod_context); + logerr(MODPREFIX + "incorrect prefix for hesiod map %s", mapname); +- free(ctxt); + return 1; + } + ctxt->mapname = mapname; +@@ -85,13 +72,52 @@ int lookup_init(const char *mapfmt, + argv++; + } + +- /* Open the parser, if we can. */ +- ctxt->parser = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); +- if (!ctxt->parser) { +- logerr(MODPREFIX "failed to open parse context"); ++ if (reinit) { ++ ret = reinit_parse(ctxt->parser, mapfmt, ++ MODPREFIX, argc - 1, argv - 1); ++ if (ret) ++ logerr(MODPREFIX "failed to reinit parse context"); ++ } else { ++ ctxt->parser = open_parse(mapfmt, ++ MODPREFIX, argc - 1, argv + 1); ++ if (!ctxt->parser) { ++ logerr(MODPREFIX "failed to open parse context"); ++ ret = 1; ++ } ++ } ++ ++ if (ret) ++ hesiod_end(ctxt->hesiod_context); ++ ++ return ret; ++} ++ ++/* This initializes a context (persistent non-global data) for queries to ++ this module. */ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ *context = NULL; ++ ++ /* If we can't build a context, bail. */ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ ret = do_init(mapfmt, argc, argv, ctxt, 0); ++ if (ret) { + free(ctxt); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -100,6 +126,32 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ /* If we can't build a context, bail. */ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(new, 0, sizeof(struct lookup_context)); ++ ++ new->parser = ctxt->parser; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) { ++ free(new); ++ return 1; ++ } ++ ++ *context = new; ++ ++ hesiod_end(ctxt->hesiod_context); ++ free(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-hosts-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-hosts-lookup-module.patch new file mode 100644 index 0000000..4180980 --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-hosts-lookup-module.patch @@ -0,0 +1,40 @@ +autofs-5.1.1 - implement reinit in hosts lookup module + +From: Ian Kent + +Refactor the hosts lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_hosts.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index 8ba0a4a..0a64655 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -69,6 +69,7 @@ int lookup_init(const char *mapfmt, + free(ctxt); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -77,6 +78,15 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ int ret; ++ ++ mapfmt = MAPFMT_DEFAULT; ++ ++ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc, argv); ++ if (ret) ++ return 1; ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-ldap-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-ldap-lookup-module.patch new file mode 100644 index 0000000..23214bd --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-ldap-lookup-module.patch @@ -0,0 +1,216 @@ +autofs-5.1.1 - implement reinit in ldap lookup module + +From: Ian Kent + +Refactor the ldap lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_ldap.c | 109 +++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 77 insertions(+), 32 deletions(-) + +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 0f5bc48..578d6c6 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -1683,39 +1683,23 @@ static void validate_uris(struct list_head *list) + return; + } + +-/* +- * This initializes a context (persistent non-global data) for queries to +- * this module. Return zero if we succeed. +- */ +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) + { + unsigned int is_amd_format; +- struct lookup_context *ctxt; +- char buf[MAX_ERR_BUF]; + int ret; + +- *context = NULL; +- +- /* If we can't build a context, bail. */ +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- char *estr = strerror_r(errno, buf, sizeof(buf)); +- logerr(MODPREFIX "malloc: %s", estr); +- return 1; +- } +- memset(ctxt, 0, sizeof(struct lookup_context)); +- + ret = pthread_mutex_init(&ctxt->uris_mutex, NULL); + if (ret) { + error(LOGOPT_ANY, MODPREFIX "failed to init uris mutex"); +- free(ctxt); + return 1; + } + + /* If a map type isn't explicitly given, parse it like sun entries. */ + if (mapfmt == NULL) + mapfmt = MAPFMT_DEFAULT; ++ + is_amd_format = 0; + if (!strcmp(mapfmt, "amd")) { + is_amd_format = 1; +@@ -1733,7 +1717,6 @@ int lookup_init(const char *mapfmt, + */ + if (!parse_server_string(LOGOPT_NONE, argv[0], ctxt)) { + error(LOGOPT_ANY, MODPREFIX "cannot parse server string"); +- free_context(ctxt); + return 1; + } + +@@ -1758,7 +1741,6 @@ int lookup_init(const char *mapfmt, + char *tmp = conf_amd_get_ldap_base(); + if (!tmp) { + error(LOGOPT_ANY, MODPREFIX "failed to get base dn"); +- free_context(ctxt); + return 1; + } + ctxt->base = tmp; +@@ -1767,7 +1749,6 @@ int lookup_init(const char *mapfmt, + if (!tmp) { + error(LOGOPT_ANY, + MODPREFIX "failed to get ldap_hostports"); +- free_context(ctxt); + return 1; + } + +@@ -1777,21 +1758,18 @@ int lookup_init(const char *mapfmt, + */ + if (!parse_server_string(LOGOPT_NONE, tmp, ctxt)) { + error(LOGOPT_ANY, MODPREFIX "cannot parse server string"); +- free_context(ctxt); + return 1; + } + free(tmp); + + if (!ctxt->server) { + error(LOGOPT_ANY, MODPREFIX "ldap_hostports not valid"); +- free_context(ctxt); + return 1; + } + + tmp = strdup(argv[0]); + if (!tmp) { + error(LOGOPT_ANY, MODPREFIX "failed to set mapname"); +- free_context(ctxt); + return 1; + } + ctxt->mapname = tmp; +@@ -1805,7 +1783,7 @@ int lookup_init(const char *mapfmt, + */ + ret = parse_ldap_config(LOGOPT_NONE, ctxt); + if (ret) { +- free_context(ctxt); ++ error(LOGOPT_ANY, MODPREFIX "failed to parse ldap config"); + return 1; + } + +@@ -1815,7 +1793,6 @@ int lookup_init(const char *mapfmt, + if (!autofs_sasl_client_init(LOGOPT_NONE)) { + error(LOGOPT_ANY, "failed to init sasl client"); + ldapinit_mutex_unlock(); +- free_context(ctxt); + return 1; + } + ldapinit_mutex_unlock(); +@@ -1824,13 +1801,51 @@ int lookup_init(const char *mapfmt, + if (is_amd_format) + ctxt->timestamp = get_amd_timestamp(ctxt); + +- /* Open the parser, if we can. */ +- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); +- if (!ctxt->parse) { ++ if (reinit) { ++ ret = reinit_parse(ctxt->parse, ++ mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (ret) ++ logmsg(MODPREFIX "failed to reinit parse context"); ++ } else { ++ /* Open the parser, if we can. */ ++ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (!ctxt->parse) { ++ logerr(MODPREFIX "failed to open parse context"); ++ ret = 1; ++ } ++ } ++ ++ return ret; ++} ++ ++/* ++ * This initializes a context (persistent non-global data) for queries to ++ * this module. Return zero if we succeed. ++ */ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ *context = NULL; ++ ++ /* If we can't build a context, bail. */ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ ret = do_init(mapfmt, argc, argv, ctxt, 0); ++ if (ret) { + free_context(ctxt); +- logerr(MODPREFIX "failed to open parse context"); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -1839,6 +1854,36 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ /* If we can't build a context, bail. */ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(new, 0, sizeof(struct lookup_context)); ++ ++ new->parse = ctxt->parse; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) { ++ free_context(new); ++ return 1; ++ } ++ ++ *context = new; ++ ++#ifdef WITH_SASL ++ ldapinit_mutex_lock(); ++ autofs_sasl_dispose(ctxt); ++ ldapinit_mutex_unlock(); ++#endif ++ free_context(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-multi-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-multi-lookup-module.patch new file mode 100644 index 0000000..bb669fa --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-multi-lookup-module.patch @@ -0,0 +1,265 @@ +autofs-5.1.1 - implement reinit in multi lookup module + +From: Ian Kent + +Update the multi lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_multi.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 227 insertions(+), 1 deletion(-) + +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index f8ebf94..fadd2ea 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -146,6 +146,31 @@ static int free_multi_context(struct lookup_context *ctxt) + return rv; + } + ++static struct lookup_context *update_multi_context(struct lookup_context *ctxt, ++ struct lookup_context *new) ++{ ++ int i; ++ ++ for (i = 0; i < new->n && i < ctxt->n; i++) { ++ if (new->m[i].mod) ++ continue; ++ ++ if (!ctxt->m[i].mod) ++ continue; ++ ++ /* reinit or open failed, use old one, questionable but ++ * we need to do something. ++ */ ++ new->m[i].mod = ctxt->m[i].mod; ++ ctxt->m[i].mod = NULL; ++ new->m[i].argc = ctxt->m[i].argc; ++ new->m[i].argv = ctxt->m[i].argv; ++ ctxt->m[i].argv = NULL; ++ } ++ ++ return new; ++} ++ + static struct lookup_mod *nss_open_lookup(const char *format, int argc, const char **argv) + { + struct list_head nsslist; +@@ -268,6 +293,8 @@ int lookup_init(const char *my_mapfmt, + struct lookup_context *ctxt; + int i; + ++ *context = NULL; ++ + ctxt = alloc_context(my_mapfmt, argc, argv); + if (!ctxt) + return 1; +@@ -291,7 +318,206 @@ int lookup_init(const char *my_mapfmt, + int lookup_reinit(const char *my_mapfmt, + int argc, const char *const *argv, void **context) + { +- return 0; ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct list_head nsslist; ++ struct list_head *head, *p; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF], *estr; ++ int i, ret = 0; ++ int status; ++ ++ new = alloc_context(my_mapfmt, argc, argv); ++ if (!new) ++ return 1; ++ ++ for (i = 0; i < new->n; i++) { ++ if (i >= ctxt->n) { ++ new->m[i].mod = nss_open_lookup(my_mapfmt, ++ new->m[i].argc, ++ new->m[i].argv); ++ if (!new->m[i].mod) { ++ logerr(MODPREFIX "error opening module"); ++ /* TODO: check */ ++ ret = 1; ++ goto out; ++ } ++ continue; ++ } ++ ++ if (*new->m[i].argv[0] == '/') { ++ if (strcmp(new->m[i].argv[0], ctxt->m[i].argv[0])) ++ open_lookup("file", MODPREFIX, ++ my_mapfmt, ++ new->m[i].argc, ++ new->m[i].argv, ++ &new->m[i].mod); ++ else { ++ new->m[i].mod = ctxt->m[i].mod; ++ if (reinit_lookup(new->m[i].mod, "file", ++ MODPREFIX, my_mapfmt, ++ new->m[i].argc, new->m[i].argv)) ++ new->m[i].mod = NULL; ++ else ++ ctxt->m[i].mod = NULL; ++ } ++ continue; ++ } ++ ++ if (!strncmp(new->m[i].argv[0], "file", 4) || ++ !strncmp(new->m[i].argv[0], "yp", 2) || ++ !strncmp(new->m[i].argv[0], "nisplus", 7) || ++ !strncmp(new->m[i].argv[0], "nis", 3) || ++ !strncmp(new->m[i].argv[0], "ldaps", 5) || ++ !strncmp(new->m[i].argv[0], "ldap", 4) || ++ !strncmp(new->m[i].argv[0], "sss", 3)) { ++ char type[MAX_MAP_TYPE_STRING]; ++ char *fmt; ++ ++ strcpy(type, new->m[i].argv[0]); ++ fmt = strchr(type, ','); ++ if (!fmt) ++ fmt = (char *) my_mapfmt; ++ else { ++ *fmt = '\0'; ++ fmt++; ++ } ++ ++ if (!strcmp(new->m[i].argv[0], ctxt->m[i].argv[0]) && ++ !strcmp(new->m[i].argv[1], ctxt->m[i].argv[1])) { ++ new->m[i].mod = ctxt->m[i].mod; ++ if (reinit_lookup(new->m[i].mod, new->m[i].argv[0], ++ MODPREFIX, fmt, ++ new->m[i].argc - 1, new->m[i].argv + 1)) ++ new->m[i].mod = NULL; ++ else ++ ctxt->m[i].mod = NULL; ++ } else { ++ open_lookup(type, MODPREFIX, fmt, ++ new->m[i].argc - 1, ++ new->m[i].argv + 1, ++ &new->m[i].mod); ++ } ++ continue; ++ } ++ ++ INIT_LIST_HEAD(&nsslist); ++ ++ if (nsswitch_parse(&nsslist)) { ++ if (!list_empty(&nsslist)) ++ free_sources(&nsslist); ++ logerr("can't to read name service switch config."); ++ /* TODO: check */ ++ ret = 1; ++ goto out; ++ } ++ ++ head = &nsslist; ++ list_for_each(p, head) { ++ struct nss_source *this; ++ ++ this = list_entry(p, struct nss_source, list); ++ ++ if (!strcmp(this->source, ctxt->m[i].mod->type)) { ++ new->m[i].mod = ctxt->m[i].mod; ++ if (reinit_lookup(new->m[i].mod, this->source, ++ MODPREFIX, my_mapfmt, ++ new->m[i].argc, new->m[i].argv)) ++ new->m[i].mod = NULL; ++ else ++ ctxt->m[i].mod = NULL; ++ continue; ++ } ++ ++ 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(new->m[i].argv[0]) + 2); ++ if (!path) { ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "error: %s", estr); ++ free_sources(&nsslist); ++ ret = 1; ++ goto out; ++ } ++ strcpy(path, AUTOFS_MAP_DIR); ++ strcat(path, "/"); ++ strcat(path, new->m[i].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 *) new->m[i].argv[0]; ++ new->m[i].argv[0] = path; ++ ++ if (strcmp(type, ctxt->m[i].mod->type)) { ++ status = open_lookup(type, ++ MODPREFIX, ++ my_mapfmt, ++ new->m[i].argc, ++ new->m[i].argv, ++ &new->m[i].mod); ++ if (status == NSS_STATUS_SUCCESS) { ++ free(save_argv0); ++ break; ++ } ++ } else { ++ new->m[i].mod = ctxt->m[i].mod; ++ if (reinit_lookup(new->m[i].mod, type, ++ MODPREFIX, my_mapfmt, ++ new->m[i].argc, new->m[i].argv)) ++ new->m[i].mod = NULL; ++ else { ++ ctxt->m[i].mod = NULL; ++ free(save_argv0); ++ break; ++ } ++ } ++ ++ new->m[i].argv[0] = save_argv0; ++ free(path); ++ continue; ++ } ++ ++ if (strcmp(this->source, ctxt->m[i].mod->type)) { ++ status = open_lookup(this->source, MODPREFIX, ++ my_mapfmt, ++ new->m[i].argc, ++ new->m[i].argv, ++ &new->m[i].mod); ++ if (status == NSS_STATUS_SUCCESS) ++ break; ++ } else { ++ new->m[i].mod = ctxt->m[i].mod; ++ if (reinit_lookup(new->m[i].mod, this->source, ++ MODPREFIX, my_mapfmt, ++ new->m[i].argc, new->m[i].argv)) ++ new->m[i].mod = NULL; ++ else { ++ ctxt->m[i].mod = NULL; ++ break; ++ } ++ } ++ } ++ free_sources(&nsslist); ++ } ++out: ++ /* Update new context with any needed old context */ ++ *context = update_multi_context(ctxt, new); ++ free_multi_context(ctxt); ++ free(ctxt); ++ ++ return ret; + } + + int lookup_read_master(struct master *master, time_t age, void *context) diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-nisplus-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-nisplus-lookup-module.patch new file mode 100644 index 0000000..eb0eb5c --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-nisplus-lookup-module.patch @@ -0,0 +1,133 @@ +autofs-5.1.1 - implement reinit in nisplus lookup module + +From: Ian Kent + +Refactor the nisplus lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_nisplus.c | 83 +++++++++++++++++++++++++++++++++++----------- + 1 file changed, 63 insertions(+), 20 deletions(-) + +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index 0c66152..5fd1d89 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -30,25 +30,16 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) + { +- struct lookup_context *ctxt; +- char buf[MAX_ERR_BUF]; +- +- *context = NULL; +- +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "%s", estr); +- return 1; +- } ++ int ret = 0; + + if (argc < 1) { +- free(ctxt); + logmsg(MODPREFIX "No map name"); +- return 1; ++ ret = 1; ++ goto out; + } + ctxt->mapname = argv[0]; + +@@ -58,20 +49,50 @@ int lookup_init(const char *mapfmt, + */ + ctxt->domainname = nis_local_directory(); + if (!ctxt->domainname) { +- free(ctxt); + logmsg(MODPREFIX "NIS+ domain not set"); +- return 1; ++ ret = 1; ++ goto out; + } + + if (!mapfmt) + mapfmt = MAPFMT_DEFAULT; + +- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); +- if (!ctxt->parse) { ++ if (reinit) { ++ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc, argv); ++ if (ret) ++ logmsg(MODPREFIX "failed to reinit parse context"); ++ } else { ++ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (!ctxt->parse) { ++ logerr(MODPREFIX "failed to open parse context"); ++ ret = 1; ++ } ++ } ++out: ++ return ret; ++} ++ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ ++ *context = NULL; ++ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "%s", estr); ++ return 1; ++ } ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ if (do_init(mapfmt, argc, argv, ctxt, 0)) { + free(ctxt); +- logerr(MODPREFIX "failed to open parse context"); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -80,6 +101,28 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "%s", estr); ++ return 1; ++ } ++ memset(new, 0, sizeof(struct lookup_context)); ++ ++ new->parse = ctxt->parse; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) ++ return 1; ++ ++ *context = new; ++ ++ free(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-parse-modules.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-parse-modules.patch new file mode 100644 index 0000000..b39731b --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-parse-modules.patch @@ -0,0 +1,146 @@ +autofs-5.1.1 - implement reinit in parse modules + +From: Ian Kent + +Refactor the parse modules to add an implementation for the newly added +reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/parse_hesiod.c | 1 + + modules/parse_sun.c | 70 ++++++++++++++++++++++++++++++++++++------------ + 2 files changed, 54 insertions(+), 17 deletions(-) + +diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c +index 0b2b57f..a02da82 100644 +--- a/modules/parse_hesiod.c ++++ b/modules/parse_hesiod.c +@@ -258,6 +258,7 @@ static int parse_generic(struct autofs_point *ap, + + int parse_init(int argc, const char *const *argv, void **context) + { ++ *context = NULL; + return 0; + } + +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 35d6da5..a164fba 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -232,27 +232,15 @@ int expandsunent(const char *src, char *dst, const char *key, + return len; + } + +-int parse_init(int argc, const char *const *argv, void **context) ++static int do_init(int argc, const char *const *argv, struct parse_context *ctxt) + { +- struct parse_context *ctxt; +- char buf[MAX_ERR_BUF]; + char *noptstr, *def, *val, *macros, *gbl_options; +- const char *xopt; ++ char buf[MAX_ERR_BUF]; + int optlen, len, offset; ++ const char *xopt; + int i, bval; + unsigned int append_options; + +- /* Set up context and escape chain */ +- +- if (!(ctxt = (struct parse_context *) malloc(sizeof(struct parse_context)))) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "malloc: %s", estr); +- *context = NULL; +- return 1; +- } +- *context = (void *) ctxt; +- +- *ctxt = default_context; + optlen = 0; + + /* Look for options and capture, and create new defines if we need to */ +@@ -359,7 +347,6 @@ int parse_init(int argc, const char *const *argv, void **context) + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + kill_context(ctxt); + logerr(MODPREFIX "%s", estr); +- *context = NULL; + return 1; + } + ctxt->optstr = noptstr; +@@ -391,9 +378,36 @@ int parse_init(int argc, const char *const *argv, void **context) + } + } + options_done: ++ + debug(LOGOPT_NONE, + MODPREFIX "init gathered global options: %s", ctxt->optstr); + ++ return 0; ++} ++ ++int parse_init(int argc, const char *const *argv, void **context) ++{ ++ struct parse_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ ++ *context = NULL; ++ ++ /* Set up context and escape chain */ ++ ++ ctxt = (struct parse_context *) malloc(sizeof(struct parse_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ ++ *ctxt = default_context; ++ ++ if (do_init(argc, argv, ctxt)) { ++ free(ctxt); ++ return 1; ++ } ++ + /* We only need this once. NFS mounts are so common that we cache + this module. */ + instance_mutex_lock(); +@@ -404,17 +418,39 @@ options_done: + init_ctr++; + } else { + kill_context(ctxt); +- *context = NULL; + instance_mutex_unlock(); + return 1; + } + } + instance_mutex_unlock(); ++ ++ *context = (void *) ctxt; ++ + return 0; + } + + int parse_reinit(int argc, const char *const *argv, void **context) + { ++ struct parse_context *ctxt = (struct parse_context *) *context; ++ struct parse_context *new; ++ char buf[MAX_ERR_BUF]; ++ ++ new = (struct parse_context *) malloc(sizeof(struct parse_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ ++ *new = default_context; ++ ++ if (do_init(argc, argv, new)) ++ return 1; ++ ++ kill_context(ctxt); ++ ++ *context = (void *) new; ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-program-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-program-lookup-module.patch new file mode 100644 index 0000000..4b43b98 --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-program-lookup-module.patch @@ -0,0 +1,153 @@ +autofs-5.1.1 - implement reinit in program lookup module + +From: Ian Kent + +Refactor the program lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_program.c | 98 ++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 76 insertions(+), 22 deletions(-) + +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index fa4f54d..3e9c448 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -49,53 +49,82 @@ struct parse_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) + { +- struct lookup_context *ctxt; +- char buf[MAX_ERR_BUF]; +- +- *context = NULL; +- +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "malloc: %s", estr); +- return 1; +- } ++ int ret = 0; + + if (argc < 1) { + logmsg(MODPREFIX "No map name"); +- free(ctxt); +- return 1; ++ ret = 1; ++ goto out; + } + ctxt->mapname = argv[0]; + + if (ctxt->mapname[0] != '/') { + logmsg(MODPREFIX "program map %s is not an absolute pathname", + ctxt->mapname); +- free(ctxt); +- return 1; ++ ret = 1; ++ goto out; + } + + if (access(ctxt->mapname, X_OK)) { + logmsg(MODPREFIX "program map %s missing or not executable", + ctxt->mapname); +- free(ctxt); +- return 1; ++ ret = 1; ++ goto out; + } + + if (!mapfmt) + mapfmt = MAPFMT_DEFAULT; + + ctxt->mapfmt = strdup(mapfmt); ++ if (!ctxt->mapfmt) { ++ logmsg(MODPREFIX "failed to allocate storage for map format"); ++ ret = 1; ++ goto out; ++ } + +- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); +- if (!ctxt->parse) { +- logmsg(MODPREFIX "failed to open parse context"); ++ if (reinit) { ++ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (ret) ++ logmsg(MODPREFIX "failed to reinit parse context"); ++ } else { ++ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (!ctxt->parse) { ++ logmsg(MODPREFIX "failed to open parse context"); ++ ret = 1; ++ } ++ } ++out: ++ if (ret && ctxt->mapfmt) ++ free(ctxt->mapfmt); ++ ++ return ret; ++} ++ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ ++ *context = NULL; ++ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ if (do_init(mapfmt, argc, argv, ctxt, 0)) { + free(ctxt); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -104,6 +133,31 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(new, 0, sizeof(struct lookup_context)); ++ ++ new->parse = ctxt->parse; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) { ++ free(new); ++ return 1; ++ } ++ ++ *context = new; ++ ++ free(ctxt->mapfmt); ++ free(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-sss-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-sss-lookup-module.patch new file mode 100644 index 0000000..ab1104c --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-sss-lookup-module.patch @@ -0,0 +1,189 @@ +autofs-5.1.1 - implement reinit in sss lookup module + +From: Ian Kent + +Refactor the sss lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_sss.c | 130 +++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 95 insertions(+), 35 deletions(-) + +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index c58a272..2f32e94 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -56,39 +56,16 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int open_sss_lib(struct lookup_context *ctxt) + { +- struct lookup_context *ctxt; +- char buf[MAX_ERR_BUF]; + char dlbuf[PATH_MAX]; + char *estr; + void *dh; + size_t size; + +- *context = NULL; +- +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "malloc: %s", estr); +- return 1; +- } +- +- if (argc < 1) { +- free(ctxt); +- logerr(MODPREFIX "No map name"); +- return 1; +- } +- ctxt->mapname = argv[0]; +- +- if (!mapfmt) +- mapfmt = MAPFMT_DEFAULT; +- + size = snprintf(dlbuf, sizeof(dlbuf), + "%s/%s.so", SSS_LIB_DIR, SSS_SO_NAME); + if (size >= sizeof(dlbuf)) { +- free(ctxt); + logmsg(MODPREFIX "sss library path too long"); + return 1; + } +@@ -96,7 +73,6 @@ int lookup_init(const char *mapfmt, + dh = dlopen(dlbuf, RTLD_LAZY); + if (!dh) { + logerr(MODPREFIX "failed to open %s: %s", dlbuf, dlerror()); +- free(ctxt); + return 1; + } + ctxt->dlhandle = dh; +@@ -117,15 +93,6 @@ int lookup_init(const char *mapfmt, + if (!ctxt->setautomntent) + goto lib_names_fail; + +- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); +- if (!ctxt->parse) { +- logmsg(MODPREFIX "failed to open parse context"); +- dlclose(dh); +- free(ctxt); +- return 1; +- } +- *context = ctxt; +- + return 0; + + lib_names_fail: +@@ -134,13 +101,106 @@ lib_names_fail: + else + logerr(MODPREFIX "dlsym: %s", estr); + dlclose(dh); +- free(ctxt); ++ + return 1; + } + ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) ++{ ++ int ret = 0; ++ ++ if (argc < 1) { ++ logerr(MODPREFIX "No map name"); ++ ret = 1; ++ goto out; ++ } ++ ctxt->mapname = argv[0]; ++ ++ if (!mapfmt) ++ mapfmt = MAPFMT_DEFAULT; ++ ++ if (!reinit) { ++ ret = open_sss_lib(ctxt); ++ if (ret) ++ goto out; ++ } ++ ++ if (reinit) { ++ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (ret) ++ logmsg(MODPREFIX "failed to reinit parse context"); ++ } else { ++ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (!ctxt->parse) { ++ logmsg(MODPREFIX "failed to open parse context"); ++ dlclose(ctxt->dlhandle); ++ ret = 1; ++ } ++ } ++out: ++ return ret; ++} ++ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ ++ *context = NULL; ++ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ ++ if (do_init(mapfmt, argc, argv, ctxt, 0)) { ++ free(ctxt); ++ return 1; ++ } ++ ++ *context = ctxt; ++ ++ return 0; ++} ++ + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ ++ new->parse = ctxt->parse; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) { ++ free(new); ++ return 1; ++ } ++ ++ new->dlhandle = ctxt->dlhandle; ++ new->setautomntent = ctxt->setautomntent; ++ new->getautomntent_r = ctxt->getautomntent_r; ++ new->getautomntbyname_r = ctxt->getautomntbyname_r; ++ new->endautomntent = ctxt->endautomntent; ++ ++ *context = new; ++ ++ free(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-yp-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-yp-lookup-module.patch new file mode 100644 index 0000000..b0761cc --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-yp-lookup-module.patch @@ -0,0 +1,151 @@ +autofs-5.1.1 - implement reinit in yp lookup module + +From: Ian Kent + +Refactor the yp lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_yp.c | 93 +++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 71 insertions(+), 22 deletions(-) + +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index 1e5a7ed..e31c2cf 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -103,27 +103,18 @@ static unsigned int get_map_order(const char *domain, const char *map) + return (unsigned int) last_changed; + } + +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) + { +- struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; + int err; +- +- *context = NULL; +- +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "malloc: %s", estr); +- return 1; +- } +- memset(ctxt, 0, sizeof(struct lookup_context)); ++ int ret = 0; + + if (argc < 1) { +- free(ctxt); + logerr(MODPREFIX "no map name"); +- return 1; ++ ret = 1; ++ goto out; + } + ctxt->mapname = argv[0]; + ctxt->check_defaults = 1; +@@ -138,15 +129,15 @@ int lookup_init(const char *mapfmt, + if (err) { + logerr(MODPREFIX + "map %s: %s", ctxt->mapname, yperr_string(err)); +- free(ctxt); +- return 1; ++ ret = 1; ++ goto out; + } + ctxt->domainname = strdup(domainname); + if (!ctxt->domainname) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "strdup: %s", estr); +- free(ctxt); +- return 1; ++ ret = 1; ++ goto out; + } + } + +@@ -155,12 +146,45 @@ int lookup_init(const char *mapfmt, + if (!mapfmt) + mapfmt = MAPFMT_DEFAULT; + +- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); +- if (!ctxt->parse) { ++ if (reinit) { ++ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (ret) ++ logmsg(MODPREFIX "failed to reinit parse context"); ++ } else { ++ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (!ctxt->parse) { ++ logmsg(MODPREFIX "failed to open parse context"); ++ ret = 1; ++ } ++ } ++out: ++ if (ret && ctxt->domainname) ++ free(ctxt->domainname); ++ ++ return ret; ++} ++ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ ++ *context = NULL; ++ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ if (do_init(mapfmt, argc, argv, ctxt, 0)) { + free(ctxt); +- logmsg(MODPREFIX "failed to open parse context"); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -169,6 +193,31 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(new, 0, sizeof(struct lookup_context)); ++ ++ new->parse = ctxt->parse; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) { ++ free(new); ++ return 1; ++ } ++ ++ *context = new; ++ ++ free(ctxt->domainname); ++ free(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-log-pipe-read-errors.patch b/SOURCES/autofs-5.1.1-log-pipe-read-errors.patch new file mode 100644 index 0000000..36d8279 --- /dev/null +++ b/SOURCES/autofs-5.1.1-log-pipe-read-errors.patch @@ -0,0 +1,76 @@ +autofs-5.1.1 - log pipe read errors + +From: Ian Kent + +Log any unexpected pipe read (possible error) returns. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 24 ++++++++++++++++++++---- + 2 files changed, 21 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -187,6 +187,7 @@ + - gaurd against incorrect umount return. + - fix typo in autofs.conf. + - always set direct mounts catatonic at exit. ++- log pipe read errors. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -968,6 +968,8 @@ static int get_pkt(struct autofs_point * + struct pollfd fds[3]; + int pollfds = 3; + char buf[MAX_ERR_BUF]; ++ size_t read; ++ char *estr; + + fds[0].fd = ap->pipefd; + fds[0].events = POLLIN; +@@ -980,7 +982,6 @@ static int get_pkt(struct autofs_point * + + for (;;) { + if (poll(fds, pollfds, -1) == -1) { +- char *estr; + if (errno == EINTR) + continue; + estr = strerror_r(errno, buf, MAX_ERR_BUF); +@@ -999,7 +1000,13 @@ static int get_pkt(struct autofs_point * + + state_pipe = ap->state_pipe[0]; + +- if (fullread(state_pipe, &next_state, read_size)) { ++ read = fullread(state_pipe, &next_state, read_size); ++ if (read) { ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ "read error on state pipe, " ++ "read %u, error %s", ++ read, estr); + st_mutex_unlock(); + continue; + } +@@ -1010,8 +1017,17 @@ static int get_pkt(struct autofs_point * + return -1; + } + +- if (fds[0].revents & POLLIN) +- return fullread(ap->pipefd, pkt, kpkt_len); ++ if (fds[0].revents & POLLIN) { ++ read = fullread(ap->pipefd, pkt, kpkt_len); ++ if (read) { ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ "read error on request pipe, " ++ "read %u, expected %u error %s", ++ read, kpkt_len, estr); ++ } ++ return read; ++ } + + if (fds[2].fd != -1 && fds[2].revents & POLLIN) { + debug(ap->logopt, "message pending on control fifo."); diff --git a/SOURCES/autofs-5.1.1-make-open_lookup-return-nss-status.patch b/SOURCES/autofs-5.1.1-make-open_lookup-return-nss-status.patch new file mode 100644 index 0000000..15367f0 --- /dev/null +++ b/SOURCES/autofs-5.1.1-make-open_lookup-return-nss-status.patch @@ -0,0 +1,260 @@ +autofs-5.1.1 - make open_lookup() return nss status + +From: Ian Kent + +In order to distinguish between source unavailable and map not found +when opening nsswitch sources that have non-default actions open_lookup() +needs to return distinct results for these two cases. + +Signed-off-by: Ian Kent +--- + daemon/lookup.c | 21 +++++++++++---------- + daemon/module.c | 22 +++++++++++++--------- + include/automount.h | 4 ++-- + modules/lookup_multi.c | 20 +++++++++++++------- + modules/parse_amd.c | 6 ++++-- + 5 files changed, 43 insertions(+), 30 deletions(-) + +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 53455a1..0579f98 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -44,9 +44,9 @@ static int do_read_master(struct master *master, char *type, time_t age) + argv[0] = master->name; + argv[1] = NULL; + +- lookup = open_lookup(type, "", NULL, argc, argv); +- if (!lookup) +- return NSS_STATUS_UNAVAIL; ++ status = open_lookup(type, "", NULL, argc, argv, &lookup); ++ if (status != NSS_STATUS_SUCCESS) ++ return status; + + status = lookup->lookup_read_master(master, age, lookup->context); + +@@ -300,10 +300,11 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a + struct lookup_mod *lookup; + int status; + +- lookup = open_lookup(map->type, "", map->format, map->argc, map->argv); +- if (!lookup) { ++ status = open_lookup(map->type, "", map->format, ++ map->argc, map->argv, &lookup); ++ if (status != NSS_STATUS_SUCCESS) { + debug(ap->logopt, "lookup module %s failed", map->type); +- return NSS_STATUS_UNAVAIL; ++ return status; + } + + master_source_writelock(ap->entry); +@@ -737,12 +738,12 @@ int do_lookup_mount(struct autofs_point *ap, struct map_source *map, const char + int status; + + if (!map->lookup) { +- lookup = open_lookup(map->type, "", +- map->format, map->argc, map->argv); +- if (!lookup) { ++ status = open_lookup(map->type, "", ++ map->format, map->argc, map->argv, &lookup); ++ if (status != NSS_STATUS_SUCCESS) { + debug(ap->logopt, + "lookup module %s failed", map->type); +- return NSS_STATUS_UNAVAIL; ++ return status; + } + map->lookup = lookup; + } +diff --git a/daemon/module.c b/daemon/module.c +index 466d8d7..9028aaa 100644 +--- a/daemon/module.c ++++ b/daemon/module.c +@@ -17,6 +17,7 @@ + #include + #include + #include "automount.h" ++#include "nsswitch.h" + + int load_autofs4_module(void) + { +@@ -53,8 +54,8 @@ int load_autofs4_module(void) + return 1; + } + +-struct lookup_mod *open_lookup(const char *name, const char *err_prefix, +- const char *mapfmt, int argc, const char *const *argv) ++int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, ++ int argc, const char *const *argv, struct lookup_mod **lookup) + { + struct lookup_mod *mod; + char buf[MAX_ERR_BUF]; +@@ -63,6 +64,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + void *dh; + int *ver; + ++ *lookup = NULL; + + mod = malloc(sizeof(struct lookup_mod)); + if (!mod) { +@@ -70,7 +72,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr("%s%s", err_prefix, estr); + } +- return NULL; ++ return NSS_STATUS_UNAVAIL; + } + + size = snprintf(fnbuf, sizeof(fnbuf), +@@ -81,7 +83,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr("%s%s", err_prefix, estr); + } +- return NULL; ++ return NSS_STATUS_UNAVAIL; + } + + if (!(dh = dlopen(fnbuf, RTLD_NOW))) { +@@ -89,7 +91,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + logerr("%scannot open lookup module %s (%s)", + err_prefix, name, dlerror()); + free(mod); +- return NULL; ++ return NSS_STATUS_UNAVAIL; + } + + if (!(ver = (int *) dlsym(dh, "lookup_version")) +@@ -99,7 +101,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + err_prefix, name); + dlclose(dh); + free(mod); +- return NULL; ++ return NSS_STATUS_UNAVAIL; + } + + if (!(mod->lookup_init = (lookup_init_t) dlsym(dh, "lookup_init")) || +@@ -111,16 +113,18 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + logerr("%slookup module %s corrupt", err_prefix, name); + dlclose(dh); + free(mod); +- return NULL; ++ return NSS_STATUS_UNAVAIL; + } + + if (mod->lookup_init(mapfmt, argc, argv, &mod->context)) { + dlclose(dh); + free(mod); +- return NULL; ++ return NSS_STATUS_NOTFOUND; + } + mod->dlhandle = dh; +- return mod; ++ *lookup = mod; ++ ++ return NSS_STATUS_SUCCESS; + } + + int close_lookup(struct lookup_mod *mod) +diff --git a/include/automount.h b/include/automount.h +index 447aba1..d614c10 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -302,8 +302,8 @@ struct lookup_mod { + void *context; + }; + +-struct lookup_mod *open_lookup(const char *name, const char *err_prefix, +- const char *mapfmt, int argc, const char *const *argv); ++int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, ++ int argc, const char *const *argv, struct lookup_mod **lookup); + int close_lookup(struct lookup_mod *); + + /* parse module */ +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index ffb236c..55035e4 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -50,8 +50,10 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + if (!argv || !argv[0]) + return NULL; + +- if (*argv[0] == '/') +- return open_lookup("file", MODPREFIX, format, argc, argv); ++ if (*argv[0] == '/') { ++ open_lookup("file", MODPREFIX, format, argc, argv, &mod); ++ return mod; ++ } + + if (!strncmp(argv[0], "file", 4) || + !strncmp(argv[0], "yp", 2) || +@@ -65,7 +67,8 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + fmt++; + else + fmt = format; +- return open_lookup(argv[0], MODPREFIX, fmt, argc -1, argv + 1); ++ open_lookup(argv[0], MODPREFIX, fmt, argc - 1, argv + 1, &mod); ++ return mod; + } + + INIT_LIST_HEAD(&nsslist); +@@ -80,6 +83,7 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + head = &nsslist; + list_for_each(p, head) { + struct nss_source *this; ++ int status; + + this = list_entry(p, struct nss_source, list); + +@@ -113,8 +117,9 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + save_argv0 = (char *) argv[0]; + argv[0] = path; + +- mod = open_lookup(type, MODPREFIX, format, argc, argv); +- if (mod) { ++ status = open_lookup(type, MODPREFIX, ++ format, argc, argv, &mod); ++ if (status == NSS_STATUS_SUCCESS) { + free_sources(&nsslist); + free(save_argv0); + return mod; +@@ -124,8 +129,9 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + free(path); + } + +- mod = open_lookup(this->source, MODPREFIX, format, argc, argv); +- if (mod) { ++ status = open_lookup(this->source, MODPREFIX, ++ format, argc, argv, &mod); ++ if (status == NSS_STATUS_SUCCESS) { + free_sources(&nsslist); + return mod; + } +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 899be40..2e3d21f 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -31,6 +31,7 @@ + + #define MODULE_PARSE + #include "automount.h" ++#include "nsswitch.h" + + #define MODPREFIX "parse(amd): " + +@@ -1129,6 +1130,7 @@ static int do_host_mount(struct autofs_point *ap, const char *name, + struct mapent *me; + const char *argv[2]; + const char **pargv = NULL; ++ int status; + int argc = 0; + int ret = 1; + +@@ -1170,8 +1172,8 @@ static int do_host_mount(struct autofs_point *ap, const char *name, + } + + instance_mutex_lock(); +- lookup = open_lookup("hosts", MODPREFIX, NULL, argc, pargv); +- if (!lookup) { ++ status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup); ++ if (status != NSS_STATUS_SUCCESS) { + debug(ap->logopt, "open lookup module hosts failed"); + instance_mutex_unlock(); + goto out; diff --git a/SOURCES/autofs-5.1.1-move-check_nss_result-to-nsswitch_c.patch b/SOURCES/autofs-5.1.1-move-check_nss_result-to-nsswitch_c.patch new file mode 100644 index 0000000..68aeed1 --- /dev/null +++ b/SOURCES/autofs-5.1.1-move-check_nss_result-to-nsswitch_c.patch @@ -0,0 +1,138 @@ +autofs-5.1.1 - move check_nss_result() to nsswitchr.c + +From: Ian Kent + +The check_nss_result() function will be needed by the multi-map lookup +module so move it to the nss library module. + +Signed-off-by: Ian Kent +--- + daemon/lookup.c | 45 --------------------------------------------- + include/nsswitch.h | 1 + + lib/nsswitch.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 46 insertions(+), 45 deletions(-) + +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 62071df..53455a1 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -25,51 +25,6 @@ + #include "automount.h" + #include "nsswitch.h" + +-static int check_nss_result(struct nss_source *this, enum nsswitch_status result) +-{ +- enum nsswitch_status status; +- struct nss_action a; +- +- /* Check if we have negated actions */ +- for (status = 0; status < NSS_STATUS_MAX; status++) { +- a = this->action[status]; +- if (a.action == NSS_ACTION_UNKNOWN) +- continue; +- +- if (a.negated && result != status) { +- if (a.action == NSS_ACTION_RETURN) { +- if (result == NSS_STATUS_SUCCESS) +- return 1; +- else +- return 0; +- } +- } +- } +- +- a = this->action[result]; +- +- /* Check if we have other actions for this status */ +- switch (result) { +- case NSS_STATUS_SUCCESS: +- if (a.action == NSS_ACTION_CONTINUE) +- break; +- return 1; +- +- case NSS_STATUS_NOTFOUND: +- case NSS_STATUS_UNAVAIL: +- case NSS_STATUS_TRYAGAIN: +- if (a.action == NSS_ACTION_RETURN) { +- return 0; +- } +- break; +- +- default: +- break; +- } +- +- return -1; +-} +- + static void nsslist_cleanup(void *arg) + { + struct list_head *nsslist = (struct list_head *) arg; +diff --git a/include/nsswitch.h b/include/nsswitch.h +index 2b445a9..d3e4027 100644 +--- a/include/nsswitch.h ++++ b/include/nsswitch.h +@@ -56,6 +56,7 @@ struct nss_source { + }; + + int set_action(struct nss_action *a, char *status, char *action, int negated); ++int check_nss_result(struct nss_source *this, enum nsswitch_status result); + struct nss_source *add_source(struct list_head *head, char *source); + int free_sources(struct list_head *list); + +diff --git a/lib/nsswitch.c b/lib/nsswitch.c +index c6163a7..74c7525 100644 +--- a/lib/nsswitch.c ++++ b/lib/nsswitch.c +@@ -55,6 +55,51 @@ int set_action(struct nss_action *act, char *status, char *action, int negated) + return 1; + } + ++int check_nss_result(struct nss_source *this, enum nsswitch_status result) ++{ ++ enum nsswitch_status status; ++ struct nss_action a; ++ ++ /* Check if we have negated actions */ ++ for (status = 0; status < NSS_STATUS_MAX; status++) { ++ a = this->action[status]; ++ if (a.action == NSS_ACTION_UNKNOWN) ++ continue; ++ ++ if (a.negated && result != status) { ++ if (a.action == NSS_ACTION_RETURN) { ++ if (result == NSS_STATUS_SUCCESS) ++ return 1; ++ else ++ return 0; ++ } ++ } ++ } ++ ++ a = this->action[result]; ++ ++ /* Check if we have other actions for this status */ ++ switch (result) { ++ case NSS_STATUS_SUCCESS: ++ if (a.action == NSS_ACTION_CONTINUE) ++ break; ++ return 1; ++ ++ case NSS_STATUS_NOTFOUND: ++ case NSS_STATUS_UNAVAIL: ++ case NSS_STATUS_TRYAGAIN: ++ if (a.action == NSS_ACTION_RETURN) { ++ return 0; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ return -1; ++} ++ + struct nss_source *add_source(struct list_head *head, char *source) + { + struct nss_source *s; diff --git a/SPECS/autofs.spec b/SPECS/autofs.spec index 71396d5..9b903b1 100644 --- a/SPECS/autofs.spec +++ b/SPECS/autofs.spec @@ -8,7 +8,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.0.7 -Release: 54%{?dist} +Release: 56%{?dist} Epoch: 1 License: GPLv2+ Group: System Environment/Daemons @@ -297,6 +297,62 @@ Patch653: autofs-5.1.1-fix-direct-map-expire-not-set-for-initial-empty-map.patch Patch654: autofs-5.1.1-update-map_hash_table_size-description.patch Patch655: autofs-5.1.1-fix-out-of-order-call-in-program-map-lookup.patch +Patch700: autofs-5.1.0-make-service-want-network-online.patch +Patch701: autofs-5.1.1-add-remote-fs-target-systemd-dependency.patch +Patch702: autofs-5.0.9-revert-special-case-cifs-escapes.patch +Patch703: autofs-5.1.0-guard-against-incorrect-umount-return.patch +Patch704: autofs-5.1.1-fix-nameing-typo-in-autofs-conf.patch + +Patch705: autofs-5.1.1-always-set-direct-mounts-catatonic-at-exit.patch +Patch706: autofs-5.1.1-log-pipe-read-errors.patch +Patch707: autofs-5.1.1-fix-rwlock-unlock-crash.patch +Patch708: autofs-5.1.1-fix-handle_mounts-termination-condition-check.patch + +# Series 1 - additional bug fixes (bug 1300500) +Patch709: autofs-5.1.1-fix-config-old-name-lookup.patch +Patch710: autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch +Patch711: autofs-5.1.0-fix-gcc5-complaints.patch +Patch712: autofs-5.1.1-fix-fix-gcc5-complaints.patch + +# Series2 - add reinit method and change lookup to use reinit +# instead of reopen (bug 1300500) +Patch713: autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch +Patch714: autofs-5.1.1-fix-update_hosts_mounts-return.patch +Patch715: autofs-5.1.1-move-check_nss_result-to-nsswitch_c.patch +Patch716: autofs-5.1.1-make-open_lookup-return-nss-status.patch +Patch717: autofs-5.1.1-fix-nsswitch-handling-when-opening-multi-map.patch +Patch718: autofs-5.1.1-add-reinit-entry-point-to-modules.patch +Patch719: autofs-5.1.1-implement-reinit-in-parse-modules.patch +Patch720: autofs-5.1.1-implement-reinit-in-file-lookup-module.patch +Patch721: autofs-5.1.1-implement-reinit-in-hesiod-lookup-module.patch +Patch722: autofs-5.1.1-implement-reinit-in-hosts-lookup-module.patch +Patch723: autofs-5.1.1-implement-reinit-in-ldap-lookup-module.patch +Patch724: autofs-5.1.1-implement-reinit-in-nisplus-lookup-module.patch +Patch725: autofs-5.1.1-implement-reinit-in-program-lookup-module.patch +Patch726: autofs-5.1.1-implement-reinit-in-sss-lookup-module.patch +Patch727: autofs-5.1.1-implement-reinit-in-yp-lookup-module.patch +Patch728: autofs-5.1.1-add-type-to-struct-lookup_mod.patch +Patch729: autofs-5.1.1-factor-out-free-multi-map-context.patch +Patch730: autofs-5.1.1-factor-out-alloc-multi-map-context.patch +Patch731: autofs-5.1.1-fix-map-format-check-in-nss_open_lookup-multi-map-module.patch +Patch732: autofs-5.1.1-implement-reinit-in-multi-lookup-module.patch +Patch733: autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch + +# Aditional bug fixes (bug 1300500) +Patch734: autofs-5.1.1-fix-unbind-external-mech.patch +Patch735: autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch + +# Some Coverity fixes identified for recent changes (bug 1300500) +Patch736: autofs-5.1.1-fix-memory-leak-in-nisplus-lookup_reinit.patch +Patch737: autofs-5.1.1-fix-memory-leak-in-ldap-do_init.patch +Patch738: autofs-5.1.1-fix-use-after-free-in-sun-parser-parse_init.patch +Patch739: autofs-5.1.1-fix-use-after-free-in-open_lookup.patch +Patch740: autofs-5.1.1-fix-typo-in-autofs_sasl_bind.patch + +Patch741: autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch +Patch742: autofs-5.1.1-fix-use-after-free-st_queue_handler.patch +Patch743: autofs-5.1.1-add-config-option-to-suppress-not-found-log-message.patch + Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %if %{with_systemd} BuildRequires: systemd-units @@ -631,6 +687,62 @@ echo %{version}-%{release} > .version %patch654 -p1 %patch655 -p1 +%patch700 -p1 +%patch701 -p1 +%patch702 -p1 +%patch703 -p1 +%patch704 -p1 + +%patch705 -p1 +%patch706 -p1 +%patch707 -p1 +%patch708 -p1 + +# Series 1 - additional bug fixes (bug 1300500) +%patch709 -p1 +%patch710 -p1 +%patch711 -p1 +%patch712 -p1 + +# Series2 - add reinit method and change lookup to use reinit +# instead of reopen (bug 1300500) +%patch713 -p1 +%patch714 -p1 +%patch715 -p1 +%patch716 -p1 +%patch717 -p1 +%patch718 -p1 +%patch719 -p1 +%patch720 -p1 +%patch721 -p1 +%patch722 -p1 +%patch723 -p1 +%patch724 -p1 +%patch725 -p1 +%patch726 -p1 +%patch727 -p1 +%patch728 -p1 +%patch729 -p1 +%patch730 -p1 +%patch731 -p1 +%patch732 -p1 +%patch733 -p1 + +# Aditional bug fixes (bug 1300500) +%patch734 -p1 +%patch735 -p1 + +# Some Coverity fixes identified for recent changes (bug 1300500) +%patch736 -p1 +%patch737 -p1 +%patch738 -p1 +%patch739 -p1 +%patch740 -p1 + +%patch741 -p1 +%patch742 -p1 +%patch743 -p1 + %build LDFLAGS=-Wl,-z,now %configure --disable-mount-locking --enable-ignore-busy --with-libtirpc %{?systemd_configure_arg:} @@ -723,6 +835,49 @@ fi %dir /etc/auto.master.d %changelog +* Wed May 25 2016 Ian Kent - 1:5.0.7-56 +- bz1327388 - Fix use-after-free in st_queue_handler + - fix use-after-free in st_queue_handler(). +- bz1252071 - [RFE] Disable alerting on non-existent automounts + - add config option to suppress not found log message. +- Resolves: rhbz#1327388 rhbz#1252071 + +* Tue May 17 2016 Ian Kent - 1:5.0.7-55 +- bz1298115 - The autofs service fails to load maps on boot if the maps + are stored on a NFS mount + - make service want network-online. + - add remote-fs.target systemd dependency. +- bz1300496 - Duplicate mounts created or leftovers in mtab + - revert special case cifs escapes. +- bz1300498 - Parent directory in nested mount gets unmounted while the + child remains mounted + - guard against incorrect umount return. +- bz1305721 - autofs.conf: Fix 'nameing' typo + - fix 'nameing' typo in autofs.conf. +- bz1329869 - RHEL6.7: shutdown / reboot hangs with findmnt in a readlink + system call, doing path_walk and stuck in autofs4_wait + - always set direct mounts catatonic at exit. + - log pipe read errors. + - fix rwlock unlock crash. + - fix handle_mounts() termination condition check. +- bz1300500 - double free or corruption (fasttop) causes abort in + ldap_int_tls_destroy + - fix config old name lookup. + - fix error handling on ldap bind fail. + - fix gcc5 complaints. + - fix fix gcc5 complaints. + - fix missing source sss in multi map lookup. + - fix update_hosts_mounts() return. + - change lookup to use reinit instead of reopen. + - fix unbind sasl external mech. + - fix sasl connection concurrancy problem. + - add some Coverity fixes identified for recent changes. +- bz1300501 - Request to add a configuration option to force use of the map + entry hostname for mounts + - add configuration option to use fqdn in mounts +- Resolves: rhbz#1298115 rhbz#1300496 rhbz#1300498 rhbz#1305721 +- Resolves: rhbz#1329869 rhbz#1300500 rhbz#1300501 + * Thu Sep 17 2015 Ian Kent - 1:5.0.7-54 - bz1263508 - Heavy program map usage can lead to a hang - fix out of order call in program map lookup.