From 1cd346b2428bd38f88c001d030e37ae7c6b1c75b Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Jan 20 2016 04:50:32 +0000 Subject: - add current released upstream patches plus fix incorrect committer changelog entries. --- diff --git a/autofs-5.1.1-Add-a-mode-option-for-master-map-entries.patch b/autofs-5.1.1-Add-a-mode-option-for-master-map-entries.patch new file mode 100644 index 0000000..5c2bd53 --- /dev/null +++ b/autofs-5.1.1-Add-a-mode-option-for-master-map-entries.patch @@ -0,0 +1,243 @@ +autofs-5.1.1 - Add a mode option for master map entries + +From: Cyril B + +Add a --mode map option to change the mode for the base location mount +point. If this option is given, autofs will chmod the mount point right +after mounting it (as the kernel autofs filesystem doesn't support a +'mode' option). + +Changing the mode of the base location mount point is normally not needed, +but if one wants to do that, it's much better to do it inside autofs rather +than outside to avoid race conditions and making sure the correct permissions +are always set. + +Signed-off-by: Cyril B +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 4 ++++ + daemon/indirect.c | 4 ++++ + include/automount.h | 1 + + lib/master.c | 1 + + lib/master_parse.y | 9 ++++++++- + lib/master_tok.l | 19 ++++++++++++++++++- + man/auto.master.5.in | 5 +++++ + 8 files changed, 42 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 8d27e55..f954018 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -22,6 +22,7 @@ + - add configuration option to use fqdn in mounts. + - fix out of order call in program map lookup. + - fix error handling of is_mounted(). ++- Add a mode option for master map entries. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/daemon/direct.c b/daemon/direct.c +index 5569299..1962a58 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -339,6 +339,7 @@ int do_mount_autofs_direct(struct autofs_point *ap, + int status, ret, ioctlfd; + const char *map_name; + time_t runfreq; ++ int err; + + if (timeout) { + /* Calculate the expire run frequency */ +@@ -433,6 +434,9 @@ int do_mount_autofs_direct(struct autofs_point *ap, + goto out_umount; + } + ++ if (ap->mode && (err = chmod(me->key, ap->mode))) ++ warn(ap->logopt, "failed to change mode of %s", me->key); ++ + ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key); + if (ioctlfd < 0) { + crit(ap->logopt, "failed to create ioctl fd for %s", me->key); +diff --git a/daemon/indirect.c b/daemon/indirect.c +index a04a624..bfd181d 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -95,6 +95,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) + struct stat st; + struct mnt_list *mnts; + int ret; ++ int err; + + ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + +@@ -163,6 +164,9 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) + goto out_umount; + } + ++ if (ap->mode && (err = chmod(root, ap->mode))) ++ warn(ap->logopt, "failed to change mode of %s", ap->path); ++ + if (ops->open(ap->logopt, &ap->ioctlfd, st.st_dev, root)) { + crit(ap->logopt, + "failed to create ioctl fd for autofs path %s", ap->path); +diff --git a/include/automount.h b/include/automount.h +index 3ea2381..c56e265 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -508,6 +508,7 @@ struct kernel_mod_version { + struct autofs_point { + pthread_t thid; + char *path; /* Mount point name */ ++ mode_t mode; /* Mount point mode */ + char *pref; /* amd prefix */ + int pipefd; /* File descriptor for pipe */ + int kpipefd; /* Kernel end descriptor for pipe */ +diff --git a/lib/master.c b/lib/master.c +index 6c38b1c..4588fa7 100644 +--- a/lib/master.c ++++ b/lib/master.c +@@ -129,6 +129,7 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt, + free(ap); + return 0; + } ++ ap->mode = 0; + + entry->ap = ap; + +diff --git a/lib/master_parse.y b/lib/master_parse.y +index 9da78fc..0011429 100644 +--- a/lib/master_parse.y ++++ b/lib/master_parse.y +@@ -63,6 +63,7 @@ static unsigned ghost; + extern unsigned global_selection_options; + static unsigned random_selection; + static unsigned use_weight; ++static unsigned long mode; + static char **tmp_argv; + static int tmp_argc; + static char **local_argv; +@@ -101,7 +102,7 @@ static int master_fprintf(FILE *, char *, ...); + %token COMMENT + %token MAP + %token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE +-%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK ++%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE + %token COLON COMMA NL DDASH + %type map + %type options +@@ -126,6 +127,7 @@ static int master_fprintf(FILE *, char *, ...); + %token MAPXFN + %token MAPNAME + %token NUMBER ++%token OCTALNUMBER + %token OPTION + + %start file +@@ -192,6 +194,7 @@ line: + | PATH OPT_GHOST { master_notify($1); YYABORT; } + | PATH OPT_NOGHOST { master_notify($1); YYABORT; } + | PATH OPT_VERBOSE { master_notify($1); YYABORT; } ++ | PATH OPT_MODE { master_notify($1); YYABORT; } + | PATH { master_notify($1); YYABORT; } + | QUOTE { master_notify($1); YYABORT; } + | OPTION { master_notify($1); YYABORT; } +@@ -576,6 +579,7 @@ daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; } + | OPT_DEBUG { debug = 1; } + | OPT_RANDOM { random_selection = 1; } + | OPT_USE_WEIGHT { use_weight = 1; } ++ | OPT_MODE OCTALNUMBER { mode = $2; } + ; + + mount_option: OPTION +@@ -644,6 +648,7 @@ static void local_init_vars(void) + ghost = defaults_get_browse_mode(); + random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT; + use_weight = 0; ++ mode = 0; + tmp_argv = NULL; + tmp_argc = 0; + local_argv = NULL; +@@ -847,6 +852,8 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne + entry->ap->flags |= MOUNT_FLAG_SYMLINK; + if (negative_timeout) + entry->ap->negative_timeout = negative_timeout; ++ if (mode && mode < LONG_MAX) ++ entry->ap->mode = mode; + + /* + source = master_find_map_source(entry, type, format, +diff --git a/lib/master_tok.l b/lib/master_tok.l +index c692e14..b32918d 100644 +--- a/lib/master_tok.l ++++ b/lib/master_tok.l +@@ -84,7 +84,7 @@ unsigned int tlen; + + %option nounput + +-%x PATHSTR MAPSTR DNSTR OPTSTR ++%x PATHSTR MAPSTR DNSTR OPTSTR OCTAL + + WS [[:blank:]]+ + OPTWS [[:blank:]]* +@@ -95,6 +95,7 @@ OPTIONSTR ([\-]?([[:alpha:]_]([[:alnum:]_\-])*(=(\"?([[:alnum:]_\-\:])+\"?))?)+) + MACROSTR (-D{OPTWS}([[:alpha:]_]([[:alnum:]_\-\.])*)=([[:alnum:]_\-\.])+) + SLASHIFYSTR (--(no-)?slashify-colons) + NUMBER [0-9]+ ++OCTALNUMBER [0-7]+ + + DNSERVSTR1 ([[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?:) + DNSERVSTR2 (\[([[:xdigit:]]:.)+\](:[0-9]+)?:) +@@ -125,6 +126,8 @@ MTYPE ((file|program|exec|sss|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|h + OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS}) + OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeout{OPTWS}={OPTWS}) + ++MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS}) ++ + %% + + { +@@ -392,6 +395,11 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo + -w|--use-weight-only { return(OPT_USE_WEIGHT); } + -r|--random-multimount-selection { return(OPT_RANDOM); } + ++ {MODE}/{OCTALNUMBER} { ++ BEGIN(OCTAL); ++ return(OPT_MODE); ++ } ++ + {OPTWS}","{OPTWS} { return(COMMA); } + + {OPTWS} {} +@@ -423,6 +431,15 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo + <> { BEGIN(INITIAL); } + } + ++{ ++ {OCTALNUMBER} { ++ master_lval.longtype = strtoul(master_text, NULL, 8); ++ return(OCTALNUMBER); ++ } ++ ++ . { BEGIN(OPTSTR); yyless(0); } ++} ++ + %% + + #include "automount.h" +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index 2e475dc..ba28494 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -211,6 +211,11 @@ or in the configuration. + Set the timeout for caching failed key lookups. This option can be + used to override the global default given either on the command line + or in the configuration. ++.TP ++.I "\-\-mode " ++Set the directory mode for the base location of the \fBautofs\fP mount point. ++If this option is given, \fBautofs\fP will chmod that directory with this ++mode. + .SH BUILTIN MAP \-hosts + If "\-hosts" is given as the map then accessing a key under the mount point + which corresponds to a hostname will allow access to the exports of that diff --git a/autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch b/autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch new file mode 100644 index 0000000..24bcd77 --- /dev/null +++ b/autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch @@ -0,0 +1,198 @@ +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(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 2b8d224..2c516e4 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -19,6 +19,7 @@ + - fix update_hosts_mounts() return. + - change lookup to use reinit instead of reopen. + - update map_hash_table_size description. ++- add configuration option to use fqdn in mounts. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/include/defaults.h b/include/defaults.h +index 4f32e12..3788078 100644 +--- a/include/defaults.h ++++ b/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(void); + 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); +diff --git a/lib/defaults.c b/lib/defaults.c +index 74fafc5..7159536 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -73,6 +73,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" +@@ -335,6 +337,11 @@ static int conf_load_autofs_defaults(void) + 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); +@@ -1701,6 +1708,17 @@ unsigned int defaults_get_map_hash_table_size(void) + 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); +diff --git a/man/autofs.conf.5.in b/man/autofs.conf.5.in +index 4434eb8..6eb5d02 100644 +--- a/man/autofs.conf.5.in ++++ b/man/autofs.conf.5.in +@@ -111,6 +111,24 @@ entries, in this case, is usually much less than the number of entries + 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: +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 15e1043..aa786f3 100644 +--- a/modules/mount_nfs.c ++++ b/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; +diff --git a/modules/replicated.c b/modules/replicated.c +index 32860d5..8437f5f 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -667,6 +667,12 @@ int prune_host_list(unsigned logopt, struct host **list, + 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; +diff --git a/redhat/autofs.conf.default.in b/redhat/autofs.conf.default.in +index da0882f..b751043 100644 +--- a/redhat/autofs.conf.default.in ++++ b/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. + # +diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in +index 80abb43..4b48c63 100644 +--- a/samples/autofs.conf.default.in ++++ b/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/autofs-5.1.1-add-reinit-entry-point-to-modules.patch b/autofs-5.1.1-add-reinit-entry-point-to-modules.patch new file mode 100644 index 0000000..0c801a9 --- /dev/null +++ b/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/autofs-5.1.1-add-type-to-struct-lookup_mod.patch b/autofs-5.1.1-add-type-to-struct-lookup_mod.patch new file mode 100644 index 0000000..3b148e0 --- /dev/null +++ b/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/autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch b/autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch new file mode 100644 index 0000000..df55823 --- /dev/null +++ b/autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch @@ -0,0 +1,77 @@ +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(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 77aad99..16e5344 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -17,6 +17,7 @@ + - fix direct map expire not set for initail empty map. + - fix missing source sss in multi map lookup. + - fix update_hosts_mounts() return. ++- change lookup to use reinit instead of reopen. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 0579f98..afd14ab 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -300,17 +300,27 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a + 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 *ap, struct map_source *map, const char + 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/autofs-5.1.1-change-remaining-gettimeofday-to-use-clock_gettime.patch b/autofs-5.1.1-change-remaining-gettimeofday-to-use-clock_gettime.patch new file mode 100644 index 0000000..e740aca --- /dev/null +++ b/autofs-5.1.1-change-remaining-gettimeofday-to-use-clock_gettime.patch @@ -0,0 +1,170 @@ +autofs-5.1.1 - change remaining gettimeofday() to use clock_gettime() + +From: Yu Ning + +The time returned by gettimeofday() is affected by discontinuous jumps +in the system time, so it causes an issue that autofs may not auto +unmount a mount point if system time is manually changed by the system +administrator. + +To fix the issue we need to convert to using a monotonic clock source +instead of the clock source used by gettimeofday(). + +Change the reamining gettimeofday() function calls to clock_gettime() +calls. + +Signed-off-by: Yu Ning +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/rpc_subs.c | 9 ++++----- + modules/replicated.c | 30 ++++++++++++++---------------- + 3 files changed, 19 insertions(+), 21 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index c243a8a..49520d3 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -28,6 +28,7 @@ + - define pending condition init helper function. + - use monotonic clock for direct mount condition. + - use monotonic clock for indirect mount condition. ++- change remaining gettimeofday() to use clock_gettime(). + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index e0e1979..4a84c16 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -1092,19 +1092,18 @@ int rpc_time(const char *host, + { + int status; + double taken; +- struct timeval start, end; +- struct timezone tz; ++ struct timespec start, end; + int proto = (ping_proto & RPC_PING_UDP) ? IPPROTO_UDP : IPPROTO_TCP; + unsigned long vers = ping_vers; + +- gettimeofday(&start, &tz); ++ clock_gettime(CLOCK_MONOTONIC, &start); + status = __rpc_ping(host, vers, proto, seconds, micros, option); +- gettimeofday(&end, &tz); ++ clock_gettime(CLOCK_MONOTONIC, &end); + + if (status == RPC_PING_FAIL || status < 0) + return status; + +- taken = elapsed(start, end); ++ taken = monotonic_elapsed(start, end); + + if (result != NULL) + *result = taken; +diff --git a/modules/replicated.c b/modules/replicated.c +index 8437f5f..f4cae3e 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -231,8 +231,7 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host, + socklen_t len = INET6_ADDRSTRLEN; + char buf[len + 1]; + struct pmap parms; +- struct timeval start, end; +- struct timezone tz; ++ struct timespec start, end; + unsigned int supported = 0; + double taken = 0; + int status, count = 0; +@@ -292,9 +291,9 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host, + supported = status; + goto done_ver; + } else if (!status) { +- gettimeofday(&start, &tz); ++ clock_gettime(CLOCK_MONOTONIC, &start); + status = rpc_ping_proto(rpc_info); +- gettimeofday(&end, &tz); ++ clock_gettime(CLOCK_MONOTONIC, &end); + if (status == -ETIMEDOUT) { + supported = status; + goto done_ver; +@@ -306,7 +305,7 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host, + debug(logopt, + "nfs v4 random selection time: %f", reply); + } else { +- reply = elapsed(start, end); ++ reply = monotonic_elapsed(start, end); + debug(logopt, "nfs v4 rpc ping time: %f", reply); + } + taken += reply; +@@ -351,9 +350,9 @@ v3_ver: + supported = status; + goto done_ver; + } else if (!status) { +- gettimeofday(&start, &tz); ++ clock_gettime(CLOCK_MONOTONIC, &start); + status = rpc_ping_proto(rpc_info); +- gettimeofday(&end, &tz); ++ clock_gettime(CLOCK_MONOTONIC, &end); + if (status == -ETIMEDOUT) { + supported = status; + goto done_ver; +@@ -365,7 +364,7 @@ v3_ver: + debug(logopt, + "nfs v3 random selection time: %f", reply); + } else { +- reply = elapsed(start, end); ++ reply = monotonic_elapsed(start, end); + debug(logopt, "nfs v3 rpc ping time: %f", reply); + } + taken += reply; +@@ -407,9 +406,9 @@ v2_ver: + supported = status; + goto done_ver; + } else if (!status) { +- gettimeofday(&start, &tz); ++ clock_gettime(CLOCK_MONOTONIC, &start); + status = rpc_ping_proto(rpc_info); +- gettimeofday(&end, &tz); ++ clock_gettime(CLOCK_MONOTONIC, &end); + if (status == -ETIMEDOUT) + supported = status; + else if (status > 0) { +@@ -420,7 +419,7 @@ v2_ver: + debug(logopt, + "nfs v2 random selection time: %f", reply); + } else { +- reply = elapsed(start, end);; ++ reply = monotonic_elapsed(start, end);; + debug(logopt, "nfs v2 rpc ping time: %f", reply); + } + taken += reply; +@@ -523,8 +522,7 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, + struct conn_info pm_info, rpc_info; + int proto; + unsigned int vers; +- struct timeval start, end; +- struct timezone tz; ++ struct timespec start, end; + double taken = 0; + time_t timeout = RPC_TIMEOUT; + int status = 0; +@@ -610,16 +608,16 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, + if (status == -EHOSTUNREACH) + goto done; + else if (!status) { +- gettimeofday(&start, &tz); ++ clock_gettime(CLOCK_MONOTONIC, &start); + status = rpc_ping_proto(&rpc_info); +- gettimeofday(&end, &tz); ++ clock_gettime(CLOCK_MONOTONIC, &end); + if (status > 0) { + if (random_selection) { + /* Random value between 0 and 1 */ + taken = ((float) random())/((float) RAND_MAX+1); + debug(logopt, "random selection time %f", taken); + } else { +- taken = elapsed(start, end); ++ taken = monotonic_elapsed(start, end); + debug(logopt, "rpc ping time %f", taken); + } + } diff --git a/autofs-5.1.1-change-time-to-use-monotonic_clock.patch b/autofs-5.1.1-change-time-to-use-monotonic_clock.patch new file mode 100644 index 0000000..f11e54a --- /dev/null +++ b/autofs-5.1.1-change-time-to-use-monotonic_clock.patch @@ -0,0 +1,581 @@ +autofs-5.1.1 - change time() to use monotonic_clock() + +From: Yu Ning + +The time returned by gettimeofday() is affected by discontinuous jumps +in the system time, so it causes an issue that autofs may not auto +unmount a mount point if system time is manually changed by the system +administrator. + +To fix the issue we need to convert to using a monotonic clock source +instead of the clock source used by gettimeofday(). + +Finally hange the time() function calls to monotonic_clock() calls. + +Signed-off-by: Yu Ning +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 4 ++-- + daemon/direct.c | 4 ++-- + daemon/indirect.c | 4 ++-- + daemon/lookup.c | 6 +++--- + daemon/state.c | 2 +- + lib/cache.c | 2 +- + lib/master.c | 4 ++-- + modules/dclist.c | 2 +- + modules/lookup_file.c | 8 ++++---- + modules/lookup_hesiod.c | 6 +++--- + modules/lookup_hosts.c | 4 ++-- + modules/lookup_ldap.c | 10 +++++----- + modules/lookup_nisplus.c | 10 +++++----- + modules/lookup_program.c | 10 +++++----- + modules/lookup_sss.c | 6 +++--- + modules/lookup_userhome.c | 2 +- + modules/lookup_yp.c | 8 ++++---- + modules/mount_autofs.c | 2 +- + modules/parse_amd.c | 2 +- + modules/replicated.c | 4 ++-- + 21 files changed, 51 insertions(+), 50 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 49520d3..4f589db 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -29,6 +29,7 @@ + - use monotonic clock for direct mount condition. + - use monotonic clock for indirect mount condition. + - change remaining gettimeofday() to use clock_gettime(). ++- change time() to use monotonic_clock(). + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/daemon/automount.c b/daemon/automount.c +index 6cba3db..74e62a1 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -1454,7 +1454,7 @@ static void *statemachine(void *arg) + break; + + case SIGHUP: +- do_hup_signal(master_list, time(NULL)); ++ do_hup_signal(master_list, monotonic_time(NULL)); + break; + + default: +@@ -2005,7 +2005,7 @@ int main(int argc, char *argv[]) + unsigned ghost, logging, daemon_check; + unsigned dumpmaps, foreground, have_global_options; + time_t timeout; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + struct rlimit rlim; + const char *options = "+hp:t:vmdD:fVrO:l:n:CF"; + static const struct option long_options[] = { +diff --git a/daemon/direct.c b/daemon/direct.c +index 9b7fd76..d427580 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -468,7 +468,7 @@ int mount_autofs_direct(struct autofs_point *ap) + struct mapent_cache *nc, *mc; + struct mapent *me, *ne, *nested; + struct mnt_list *mnts; +- time_t now = time(NULL); ++ time_t now = monotonic_time(NULL); + + if (strcmp(ap->path, "/-")) { + error(ap->logopt, "expected direct map, exiting"); +@@ -1387,7 +1387,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + } + + /* Check if we recorded a mount fail for this key */ +- if (me->status >= time(NULL)) { ++ if (me->status >= monotonic_time(NULL)) { + ops->send_fail(ap->logopt, + ioctlfd, pkt->wait_queue_token, -ENOENT); + ops->close(ap->logopt, ioctlfd); +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 263fff1..4c32bdb 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -201,7 +201,7 @@ out_err: + + int mount_autofs_indirect(struct autofs_point *ap, const char *root) + { +- time_t now = time(NULL); ++ time_t now = monotonic_time(NULL); + int status; + int map; + +@@ -817,7 +817,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, pkt->name, LKP_DISTINCT); + if (me) { +- if (me->status >= time(NULL)) { ++ if (me->status >= monotonic_time(NULL)) { + ops->send_fail(ap->logopt, ap->ioctlfd, + pkt->wait_queue_token, -ENOENT); + cache_unlock(me->mc); +diff --git a/daemon/lookup.c b/daemon/lookup.c +index afd14ab..0129f75 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -841,7 +841,7 @@ static int lookup_name_file_source_instance(struct autofs_point *ap, struct map_ + struct map_source *instance; + char src_file[] = "file"; + char src_prog[] = "program"; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + struct stat st; + char *type, *format; + +@@ -881,7 +881,7 @@ static int lookup_name_source_instance(struct autofs_point *ap, struct map_sourc + { + struct map_source *instance; + const char *format; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + + if (*name == '/' && map->flags & MAP_FLAG_FORMAT_AMD) + return lookup_amd_instance(ap, map, name, name_len); +@@ -1045,7 +1045,7 @@ static void update_negative_cache(struct autofs_point *ap, struct map_source *so + else + map = entry->maps; + if (map) { +- time_t now = time(NULL); ++ time_t now = monotonic_time(NULL); + int rv = CHE_FAIL; + + cache_writelock(map->mc); +diff --git a/daemon/state.c b/daemon/state.c +index 6c8c4f6..3ef8d95 100644 +--- a/daemon/state.c ++++ b/daemon/state.c +@@ -564,7 +564,7 @@ static unsigned int st_readmap(struct autofs_point *ap) + pthread_t thid; + struct readmap_args *ra; + int status; +- int now = time(NULL); ++ int now = monotonic_time(NULL); + + debug(ap->logopt, "state %d path %s", ap->state, ap->path); + +diff --git a/lib/cache.c b/lib/cache.c +index 631d275..44e323d 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -775,7 +775,7 @@ void cache_update_negative(struct mapent_cache *mc, + struct map_source *ms, const char *key, + time_t timeout) + { +- time_t now = time(NULL); ++ time_t now = monotonic_time(NULL); + struct mapent *me; + int rv = CHE_OK; + +diff --git a/lib/master.c b/lib/master.c +index 4588fa7..9ffdd1a 100644 +--- a/lib/master.c ++++ b/lib/master.c +@@ -1484,7 +1484,7 @@ int dump_map(struct master *master, const char *type, const char *name) + struct map_source *source; + struct master_mapent *this; + struct autofs_point *ap; +- time_t now = time(NULL); ++ time_t now = monotonic_time(NULL); + + this = list_entry(p, struct master_mapent, list); + p = p->next; +@@ -1602,7 +1602,7 @@ int master_show_mounts(struct master *master) + struct map_source *source; + struct master_mapent *this; + struct autofs_point *ap; +- time_t now = time(NULL); ++ time_t now = monotonic_time(NULL); + unsigned int count = 0; + + this = list_entry(p, struct master_mapent, list); +diff --git a/modules/dclist.c b/modules/dclist.c +index af21ce0..4daa199 100644 +--- a/modules/dclist.c ++++ b/modules/dclist.c +@@ -568,7 +568,7 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri) + if (!list) + goto out_error; + +- dclist->expire = time(NULL) + min_ttl; ++ dclist->expire = monotonic_time(NULL) + min_ttl; + dclist->uri = list; + + return dclist; +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index aed3cba..72444fe 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -795,7 +795,7 @@ static int match_key(struct autofs_point *ap, + { + char buf[MAX_ERR_BUF]; + struct mapent_cache *mc; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + char *lkp_key; + char *prefix; + size_t map_key_len; +@@ -860,7 +860,7 @@ static int lookup_one(struct autofs_point *ap, + struct mapent_cache *mc = source->mc; + char mkey[KEY_MAX_LEN + 1]; + char mapent[MAPENT_MAX_LEN + 1]; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + FILE *f; + unsigned int k_len, m_len; + int entry, ret; +@@ -966,7 +966,7 @@ static int lookup_wild(struct autofs_point *ap, + struct mapent_cache *mc; + char mkey[KEY_MAX_LEN + 1]; + char mapent[MAPENT_MAX_LEN + 1]; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + FILE *f; + unsigned int k_len, m_len; + int entry, ret; +@@ -1170,7 +1170,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, key, LKP_DISTINCT); + if (me) { +- if (me->status >= time(NULL)) { ++ if (me->status >= monotonic_time(NULL)) { + cache_unlock(me->mc); + return NSS_STATUS_NOTFOUND; + } else { +diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c +index c0f7f51..12ccf41 100644 +--- a/modules/lookup_hesiod.c ++++ b/modules/lookup_hesiod.c +@@ -222,7 +222,7 @@ static int lookup_one(struct autofs_point *ap, + } + + cache_writelock(mc); +- ret = cache_update(mc, source, key, best_record, time(NULL)); ++ ret = cache_update(mc, source, key, best_record, monotonic_time(NULL)); + cache_unlock(mc); + if (ret == CHE_FAIL) { + hesiod_free_list(ctxt->hesiod_context, hes_result); +@@ -287,7 +287,7 @@ static int lookup_one_amd(struct autofs_point *ap, + } + + cache_writelock(mc); +- ret = cache_update(mc, source, lkp_key, *hes_result, time(NULL)); ++ ret = cache_update(mc, source, lkp_key, *hes_result, monotonic_time(NULL)); + cache_unlock(mc); + + if (hes_result) +@@ -398,7 +398,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, name, LKP_DISTINCT); + if (me) { +- if (me->status >= time(NULL)) { ++ if (me->status >= monotonic_time(NULL)) { + cache_unlock(me->mc); + return NSS_STATUS_NOTFOUND; + } else { +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index 0a64655..163b02d 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -302,7 +302,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + struct mapent *me; + char *mapent = NULL; + int mapent_len; +- time_t now = time(NULL); ++ time_t now = monotonic_time(NULL); + int ret; + + source = ap->entry->current; +@@ -314,7 +314,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, name, LKP_DISTINCT); + if (me) { +- if (me->status >= time(NULL)) { ++ if (me->status >= monotonic_time(NULL)) { + cache_unlock(me->mc); + return NSS_STATUS_NOTFOUND; + } else { +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 578d6c6..afc89c1 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -995,7 +995,7 @@ static int do_reconnect(unsigned logopt, + + uris_mutex_lock(ctxt); + if (ctxt->dclist) { +- if (!ldap || ctxt->dclist->expire < time(NULL)) { ++ if (!ldap || ctxt->dclist->expire < monotonic_time(NULL)) { + free_dclist(ctxt->dclist); + ctxt->dclist = NULL; + } +@@ -2961,7 +2961,7 @@ static int lookup_one(struct autofs_point *ap, struct map_source *source, + struct mapent_cache *mc; + int rv, i, l, ql, count; + char buf[MAX_ERR_BUF]; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + char *query; + LDAPMessage *result = NULL, *e; + char *class, *info, *entry; +@@ -3326,7 +3326,7 @@ static int lookup_one_amd(struct autofs_point *ap, + struct berval **bvKey; + struct berval **bvValues; + char buf[MAX_ERR_BUF]; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + int rv, l, ql, count; + int ret = CHE_MISSING; + +@@ -3531,7 +3531,7 @@ static int check_map_indirect(struct autofs_point *ap, + unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD; + struct mapent_cache *mc; + struct mapent *me; +- time_t now = time(NULL); ++ time_t now = monotonic_time(NULL); + time_t t_last_read; + int ret, cur_state; + int status; +@@ -3669,7 +3669,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, key, LKP_DISTINCT); + if (me) { +- if (me->status >= time(NULL)) { ++ if (me->status >= monotonic_time(NULL)) { + cache_unlock(me->mc); + return NSS_STATUS_NOTFOUND; + } else { +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index 5fd1d89..27f9856 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -338,7 +338,7 @@ static int lookup_one(struct autofs_point *ap, + nis_result *result; + nis_object *this; + char *mapent; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + int ret, cur_state; + char buf[MAX_ERR_BUF]; + +@@ -450,7 +450,7 @@ static int lookup_wild(struct autofs_point *ap, + nis_result *result; + nis_object *this; + char *mapent; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + int ret, cur_state; + char buf[MAX_ERR_BUF]; + +@@ -537,7 +537,7 @@ static int lookup_amd_defaults(struct autofs_point *ap, + mapent = ENTRY_VAL(this, 1); + + cache_writelock(mc); +- ret = cache_update(mc, source, "/defaults", mapent, time(NULL)); ++ ret = cache_update(mc, source, "/defaults", mapent, monotonic_time(NULL)); + cache_unlock(mc); + + nis_freeresult(result); +@@ -555,7 +555,7 @@ static int check_map_indirect(struct autofs_point *ap, + unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD; + struct mapent_cache *mc; + struct mapent *me, *exists; +- time_t now = time(NULL); ++ time_t now = monotonic_time(NULL); + time_t t_last_read; + int ret = 0; + +@@ -700,7 +700,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, key, LKP_DISTINCT); + if (me) { +- if (me->status >= time(NULL)) { ++ if (me->status >= monotonic_time(NULL)) { + cache_unlock(me->mc); + return NSS_STATUS_NOTFOUND; + } else { +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index a46ff0e..b3f1c1f 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -430,7 +430,7 @@ static int lookup_amd_defaults(struct autofs_point *ap, + while (isblank(*start)) + start++; + cache_writelock(mc); +- ret = cache_update(mc, source, "/defaults", start, time(NULL)); ++ ret = cache_update(mc, source, "/defaults", start, monotonic_time(NULL)); + cache_unlock(mc); + if (ret == CHE_FAIL) { + free(ment); +@@ -499,7 +499,7 @@ static int match_key(struct autofs_point *ap, + start++; + } + cache_writelock(mc); +- ret = cache_update(mc, source, lkp_key, start, time(NULL)); ++ ret = cache_update(mc, source, lkp_key, start, monotonic_time(NULL)); + cache_unlock(mc); + if (ret == CHE_FAIL) { + free(ment); +@@ -552,7 +552,7 @@ static int match_key(struct autofs_point *ap, + while (isblank(*start)) + start++; + cache_writelock(mc); +- ret = cache_update(mc, source, match, start, time(NULL)); ++ ret = cache_update(mc, source, match, start, monotonic_time(NULL)); + cache_unlock(mc); + if (ret == CHE_FAIL) { + free(match); +@@ -598,7 +598,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, name, LKP_DISTINCT); + if (me) { +- if (me->status >= time(NULL)) { ++ if (me->status >= monotonic_time(NULL)) { + cache_unlock(me->mc); + return NSS_STATUS_NOTFOUND; + } else { +@@ -647,7 +647,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + * proceed with the program map lookup. + */ + if (strchr(name, '/') || +- me->age + ap->negative_timeout > time(NULL)) { ++ me->age + ap->negative_timeout > monotonic_time(NULL)) { + char *ent = NULL; + + if (me->mapent) { +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 2f32e94..e01dd28 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -447,7 +447,7 @@ static int lookup_one(struct autofs_point *ap, + struct mapent_cache *mc; + struct mapent *we; + void *sss_ctxt = NULL; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + char buf[MAX_ERR_BUF]; + char *value = NULL; + char *s_key; +@@ -568,7 +568,7 @@ static int check_map_indirect(struct autofs_point *ap, + struct map_source *source; + struct mapent_cache *mc; + struct mapent *me; +- time_t now = time(NULL); ++ time_t now = monotonic_time(NULL); + time_t t_last_read; + int ret, cur_state; + +@@ -662,7 +662,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, key, LKP_DISTINCT); + if (me) { +- if (me->status >= time(NULL)) { ++ if (me->status >= monotonic_time(NULL)) { + cache_unlock(me->mc); + return NSS_STATUS_NOTFOUND; + } else { +diff --git a/modules/lookup_userhome.c b/modules/lookup_userhome.c +index c21dee9..8117640 100644 +--- a/modules/lookup_userhome.c ++++ b/modules/lookup_userhome.c +@@ -84,7 +84,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + } + + cache_writelock(mc); +- ret = cache_update(mc, source, name, NULL, time(NULL)); ++ ret = cache_update(mc, source, name, NULL, monotonic_time(NULL)); + cache_unlock(mc); + + if (ret == CHE_FAIL) { +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index e31c2cf..eda2aba 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -461,7 +461,7 @@ static int lookup_one(struct autofs_point *ap, + char *mapname; + char *mapent; + int mapent_len; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + int ret; + + mc = source->mc; +@@ -573,7 +573,7 @@ static int lookup_wild(struct autofs_point *ap, + char *mapname; + char *mapent; + int mapent_len; +- time_t age = time(NULL); ++ time_t age = monotonic_time(NULL); + int ret; + + mc = source->mc; +@@ -654,7 +654,7 @@ static int lookup_amd_defaults(struct autofs_point *ap, + return CHE_FAIL; + + cache_writelock(mc); +- ret = cache_update(mc, source, "/defaults", mapent, time(NULL)); ++ ret = cache_update(mc, source, "/defaults", mapent, monotonic_time(NULL)); + cache_unlock(mc); + + return ret; +@@ -809,7 +809,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, key, LKP_DISTINCT); + if (me) { +- if (me->status >= time(NULL)) { ++ if (me->status >= monotonic_time(NULL)) { + cache_unlock(me->mc); + return NSS_STATUS_NOTFOUND; + } else { +diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c +index 39948e6..c6a3199 100644 +--- a/modules/mount_autofs.c ++++ b/modules/mount_autofs.c +@@ -247,7 +247,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + + source = master_add_map_source(entry, + info->type, info->format, +- time(NULL), argc, argv); ++ monotonic_time(NULL), argc, argv); + if (!source) { + error(ap->logopt, + MODPREFIX "failed to add map source to entry"); +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 0626bf4..b8e0078 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -1188,7 +1188,7 @@ static int do_host_mount(struct autofs_point *ap, const char *name, + "hosts", "sun", argc, pargv); + if (!instance) { + instance = master_add_source_instance(source, +- "hosts", "sun", time(NULL), argc, pargv); ++ "hosts", "sun", monotonic_time(NULL), argc, pargv); + if (!instance) { + error(ap->logopt, MODPREFIX + "failed to create source instance for hosts map"); +diff --git a/modules/replicated.c b/modules/replicated.c +index f4cae3e..315e300 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -69,14 +69,14 @@ void seed_random(void) + + fd = open_fd("/dev/urandom", O_RDONLY); + if (fd < 0) { +- srandom(time(NULL)); ++ srandom(monotonic_time(NULL)); + return; + } + + if (read(fd, &seed, sizeof(seed)) != -1) + srandom(seed); + else +- srandom(time(NULL)); ++ srandom(monotonic_time(NULL)); + + close(fd); + diff --git a/autofs-5.1.1-define-monotonic-clock-helper-functions.patch b/autofs-5.1.1-define-monotonic-clock-helper-functions.patch new file mode 100644 index 0000000..db6e747 --- /dev/null +++ b/autofs-5.1.1-define-monotonic-clock-helper-functions.patch @@ -0,0 +1,91 @@ +autofs-5.1.1 - define monotonic clock helper functions + +From: Yu Ning + +The time returned by gettimeofday() is affected by discontinuous jumps +in the system time, so it causes an issue that autofs may not auto +unmount a mount point if system time is manually changed by the system +administrator. + +To fix the issue we need to convert to using a monotonic clock source +instead of the clock source used by gettimeofday(). + +Start by defining two helper functions that will be used by later +patches. + +Signed-off-by: Yu Ning +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 10 ++++++++++ + include/rpc_subs.h | 1 + + lib/rpc_subs.c | 11 +++++++++++ + 4 files changed, 23 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index f954018..566a6c6 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -23,6 +23,7 @@ + - fix out of order call in program map lookup. + - fix error handling of is_mounted(). + - Add a mode option for master map entries. ++- define monotonic clock helper functions. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/include/automount.h b/include/automount.h +index c56e265..9e82048 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -582,6 +582,16 @@ do { \ + fatal(_m_unlock); \ + } while(0) + ++static inline time_t monotonic_time(time_t *t) ++{ ++ struct timespec ts; ++ ++ clock_gettime(CLOCK_MONOTONIC, &ts); ++ if (t) ++ *t = (time_t) ts.tv_sec; ++ return (time_t) ts.tv_sec; ++} ++ + /* Expire alarm handling routines */ + int alarm_start_handler(void); + int alarm_add(struct autofs_point *ap, time_t seconds); +diff --git a/include/rpc_subs.h b/include/rpc_subs.h +index b6d59f9..e329224 100644 +--- a/include/rpc_subs.h ++++ b/include/rpc_subs.h +@@ -71,6 +71,7 @@ int rpc_portmap_getport(struct conn_info *, struct pmap *, unsigned short *); + int rpc_ping_proto(struct conn_info *); + int rpc_ping(const char *, long, long, unsigned int); + double elapsed(struct timeval, struct timeval); ++double monotonic_elapsed(struct timespec, struct timespec); + int rpc_time(const char *, unsigned int, unsigned int, long, long, unsigned int, double *); + const char *get_addr_string(struct sockaddr *, char *, socklen_t); + +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 68d68f4..e0e1979 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -1075,6 +1075,17 @@ double elapsed(struct timeval start, struct timeval end) + return t2-t1; + } + ++double monotonic_elapsed(struct timespec start, struct timespec end) ++{ ++ double t1, t2; ++ ++ t1 = (double) start.tv_sec + ++ (double) (start.tv_nsec/(1000*1000*1000)); ++ t2 = (double) end.tv_sec + ++ (double) (end.tv_nsec/(1000*1000*1000)); ++ return t2 - t1; ++} ++ + int rpc_time(const char *host, + unsigned int ping_vers, unsigned int ping_proto, + long seconds, long micros, unsigned int option, double *result) diff --git a/autofs-5.1.1-define-pending-condition-init-helper-function.patch b/autofs-5.1.1-define-pending-condition-init-helper-function.patch new file mode 100644 index 0000000..49715aa --- /dev/null +++ b/autofs-5.1.1-define-pending-condition-init-helper-function.patch @@ -0,0 +1,68 @@ +autofs-5.1.1 - define pending condition init helper function + +From: Yu Ning + +The time returned by gettimeofday() is affected by discontinuous jumps +in the system time, so it causes an issue that autofs may not auto +unmount a mount point if system time is manually changed by the system +administrator. + +To fix the issue we need to convert to using a monotonic clock source +instead of the clock source used by gettimeofday(). + +We also want to use a monotonic clock source for the condition wait +of both the direct and indirect mount thread creation as well the +expire thread creation of each. So create a common helper function +to initialize a condition variable to use a monotonic clock source. + +Signed-off-by: Yu Ning +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 21 +++++++++++++++++++++ + 2 files changed, 22 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index c443f49..20a64a7 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -25,6 +25,7 @@ + - Add a mode option for master map entries. + - define monotonic clock helper functions. + - use monotonic clock for alarm thread condition wait. ++- define pending condition init helper function. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/include/automount.h b/include/automount.h +index 9e82048..2cf0611 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -429,6 +429,27 @@ struct pending_args { + }; + + #ifdef INCLUDE_PENDING_FUNCTIONS ++static void pending_cond_init(void *arg) ++{ ++ struct pending_args *mt = (struct pending_args *) arg; ++ pthread_condattr_t condattrs; ++ int status; ++ ++ status = pthread_condattr_init(&condattrs); ++ if (status) ++ fatal(status); ++ ++ status = pthread_condattr_setclock(&condattrs, CLOCK_MONOTONIC); ++ if (status) ++ fatal(status); ++ ++ status = pthread_cond_init(&mt->cond, &condattrs); ++ if (status) ++ fatal(status); ++ ++ pthread_condattr_destroy(&condattrs); ++} ++ + static void pending_cond_destroy(void *arg) + { + struct pending_args *mt = (struct pending_args *) arg; diff --git a/autofs-5.1.1-factor-out-alloc-multi-map-context.patch b/autofs-5.1.1-factor-out-alloc-multi-map-context.patch new file mode 100644 index 0000000..f42e418 --- /dev/null +++ b/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/autofs-5.1.1-factor-out-free-multi-map-context.patch b/autofs-5.1.1-factor-out-free-multi-map-context.patch new file mode 100644 index 0000000..19670bd --- /dev/null +++ b/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/autofs-5.1.1-fix-config-old-name-lookup.patch b/autofs-5.1.1-fix-config-old-name-lookup.patch new file mode 100644 index 0000000..e076fd4 --- /dev/null +++ b/autofs-5.1.1-fix-config-old-name-lookup.patch @@ -0,0 +1,58 @@ +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(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 3bd7145..ebd66d8 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -11,6 +11,7 @@ + - make find_server() return a status. + - fix return handling of do_reconnect() in ldap module. + - fix rwlock unlock crash. ++- fix config old name lookup. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/lib/defaults.c b/lib/defaults.c +index 5711e65..74fafc5 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -728,6 +728,17 @@ static struct conf_option *conf_lookup(const char *section, const char *key) + */ + 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/autofs-5.1.1-fix-direct-map-expire-not-set-for-initial-empty-map.patch b/autofs-5.1.1-fix-direct-map-expire-not-set-for-initial-empty-map.patch new file mode 100644 index 0000000..9e49880 --- /dev/null +++ b/autofs-5.1.1-fix-direct-map-expire-not-set-for-initial-empty-map.patch @@ -0,0 +1,56 @@ +autofs-5.1.1 - fix direct map expire not set for initial empty map + +From: Ian Kent + +If an empty direct map is present at startup the expire alarm can't be +set because the expire run frequency isn't known. But if the map is +re-read and is no longer empty the expire alarm wasn't being set. + +Fix suggested by xuw at redhat dot com, thanks. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/state.c | 10 ++++++++++ + 2 files changed, 11 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 7bd261a..52b166d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -14,6 +14,7 @@ + - fix config old name lookup. + - fix error handling on ldap bind fail. + - fix direct mount stale instance flag reset. ++- fix direct map expire not set for initail empty map. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/daemon/state.c b/daemon/state.c +index 3bea4af..6c8c4f6 100644 +--- a/daemon/state.c ++++ b/daemon/state.c +@@ -488,6 +488,7 @@ static void *do_readmap(void *arg) + status = lookup_ghost(ap, ap->path); + } else { + struct mapent *me; ++ unsigned int append_alarm = !ap->exp_runfreq; + + mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/"); + pthread_cleanup_push(tree_mnts_cleanup, mnts); +@@ -517,6 +518,15 @@ static void *do_readmap(void *arg) + map->stale = 0; + map = map->next; + } ++ ++ /* If the direct mount map was empty at startup no expire ++ * alarm will have been added. So add it here if there are ++ * now map entries. ++ */ ++ if (append_alarm && ap->exp_runfreq) ++ alarm_add(ap, ap->exp_runfreq + ++ rand() % ap->exp_runfreq); ++ + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); diff --git a/autofs-5.1.1-fix-direct-mount-stale-instance-flag-reset.patch b/autofs-5.1.1-fix-direct-mount-stale-instance-flag-reset.patch new file mode 100644 index 0000000..e3edca2 --- /dev/null +++ b/autofs-5.1.1-fix-direct-mount-stale-instance-flag-reset.patch @@ -0,0 +1,38 @@ +autofs-5.1.1 - fix direct mount stale instance flag reset + +From: Ian Kent + +When re-reading a direct map the stale map instance flag was not being +reset. This caused the map to be seen as stale on subsequent lookups +thereby triggering a map re-read. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/state.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index cbe039c..7bd261a 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -13,6 +13,7 @@ + - fix rwlock unlock crash. + - fix config old name lookup. + - fix error handling on ldap bind fail. ++- fix direct mount stale instance flag reset. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/daemon/state.c b/daemon/state.c +index 3174a9c..3bea4af 100644 +--- a/daemon/state.c ++++ b/daemon/state.c +@@ -513,6 +513,7 @@ static void *do_readmap(void *arg) + } + lookup_prune_one_cache(ap, map->mc, now); + pthread_cleanup_pop(1); ++ clear_stale_instances(map); + map->stale = 0; + map = map->next; + } diff --git a/autofs-5.1.1-fix-error-handling-of-is_mounted.patch b/autofs-5.1.1-fix-error-handling-of-is_mounted.patch new file mode 100644 index 0000000..604214f --- /dev/null +++ b/autofs-5.1.1-fix-error-handling-of-is_mounted.patch @@ -0,0 +1,71 @@ +autofs-5.1.1 - fix error handling of is_mounted() + +From: Ian Kent + +If the ops->ismountpoint() ioctl call fails for some reason is_mounted() +would return 0 indicating the path isn't mounted even if it is. + +In this case fall back to the resource intensive mount table lookup. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 15 +++++++++++---- + 2 files changed, 12 insertions(+), 4 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 3dd28cc..8d27e55 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -21,6 +21,7 @@ + - update map_hash_table_size description. + - add configuration option to use fqdn in mounts. + - fix out of order call in program map lookup. ++- fix error handling of is_mounted(). + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/lib/mounts.c b/lib/mounts.c +index f665721..455bdca 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1032,12 +1032,19 @@ static int table_is_mounted(const char *table, const char *path, unsigned int ty + return ret; + } + +-static int ioctl_is_mounted(const char *path, unsigned int type) ++static int ioctl_is_mounted(const char *table, const char *path, unsigned int type) + { + struct ioctl_ops *ops = get_ioctl_ops(); + unsigned int mounted; ++ int ret; ++ ++ /* If the ioctl fails fall back to the potentially resource ++ * intensive mount table check. ++ */ ++ ret = ops->ismountpoint(LOGOPT_NONE, -1, path, &mounted); ++ if (ret == -1) ++ return table_is_mounted(table, path, type); + +- ops->ismountpoint(LOGOPT_NONE, -1, path, &mounted); + if (mounted) { + switch (type) { + case MNTS_ALL: +@@ -1056,7 +1063,7 @@ int is_mounted(const char *table, const char *path, unsigned int type) + struct ioctl_ops *ops = get_ioctl_ops(); + + if (ops->ismountpoint) +- return ioctl_is_mounted(path, type); ++ return ioctl_is_mounted(table, path, type); + else + return table_is_mounted(table, path, type); + } +@@ -1439,7 +1446,7 @@ int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type) + int mounted = 0; + + if (ops->ismountpoint) +- return ioctl_is_mounted(path, type); ++ return ioctl_is_mounted(_PROC_MOUNTS, path, type); + + INIT_LIST_HEAD(&list); + diff --git a/autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch b/autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch new file mode 100644 index 0000000..3540847 --- /dev/null +++ b/autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch @@ -0,0 +1,91 @@ +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(-) + +diff --git a/CHANGELOG b/CHANGELOG +index ebd66d8..cbe039c 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -12,6 +12,7 @@ + - fix return handling of do_reconnect() in ldap module. + - fix rwlock unlock crash. + - fix config old name lookup. ++- fix error handling on ldap bind fail. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 7e23869..d846d8e 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -216,15 +216,18 @@ int bind_ldap_simple(unsigned logopt, LDAP *ldap, const char *uri, struct lookup + + 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 logopt, const char *uri, struct lookup_con + + 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 *ldap, const char *uri, struct lookup_c + 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 *ldap, const char *uri, struct lookup_c + 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/autofs-5.1.1-fix-left-mount-count-return.patch b/autofs-5.1.1-fix-left-mount-count-return.patch new file mode 100644 index 0000000..b3a52e1 --- /dev/null +++ b/autofs-5.1.1-fix-left-mount-count-return.patch @@ -0,0 +1,41 @@ +autofs-5.1.1 - fix left mount count return from umount_multi_triggers() + +From: Xu Wang + +If a umount of an NFS mount at the root of a multi-mount fails +umount_multi_triggers() will return an zero (success) when it should +return 1 (a fail). In this case do_expire_direct() will close the +me->ioctlfd fd used for expires stopping further expires of the +direct mount. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 3a9266d..bd7b981 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -2,6 +2,7 @@ + ======================= + - update libtirpc workaround for new soname. + - revert fix libtirpc name clash. ++- fix left mount count return from umount_multi_triggers(). + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/lib/mounts.c b/lib/mounts.c +index 84af6be..f665721 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2131,7 +2131,7 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root + if (mount_multi_triggers(ap, me, root, strlen(root), "/") < 0) + warn(ap->logopt, + "failed to remount offset triggers"); +- return left++; ++ return ++left; + } + } + diff --git a/autofs-5.1.1-fix-map-format-check-in-nss_open_lookup-multi-map-module.patch b/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/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/autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch b/autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch new file mode 100644 index 0000000..7b5b44a --- /dev/null +++ b/autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch @@ -0,0 +1,38 @@ +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(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 52b166d..e22877e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -15,6 +15,7 @@ + - fix error handling on ldap bind fail. + - fix direct mount stale instance flag reset. + - fix direct map expire not set for initail empty map. ++- fix missing source sss in multi map lookup. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index 6ec8434..ffb236c 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -58,7 +58,8 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + !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/autofs-5.1.1-fix-nsswitch-handling-when-opening-multi-map.patch b/autofs-5.1.1-fix-nsswitch-handling-when-opening-multi-map.patch new file mode 100644 index 0000000..720eaf2 --- /dev/null +++ b/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/autofs-5.1.1-fix-out-of-order-call-in-program-map-lookup.patch b/autofs-5.1.1-fix-out-of-order-call-in-program-map-lookup.patch new file mode 100644 index 0000000..c0fbbc1 --- /dev/null +++ b/autofs-5.1.1-fix-out-of-order-call-in-program-map-lookup.patch @@ -0,0 +1,69 @@ +autofs-5.1.1 - fix out of order call in program map lookup + +From: Ian Kent + +Commit 91e42e58b4 fixed a problem with program map environment variable +naming and commit 743deb0e4e added a configuration option to force use +of the old environment names for those who need it and are sure it is +safe to continue to use them. + +But the call to get the configuration entry was placed after a fork() +so the state of the mutex used when querying the configuration is +undefined and can lead to a deadlock. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_program.c | 20 ++++++++++---------- + 2 files changed, 11 insertions(+), 10 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 2c516e4..3dd28cc 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -20,6 +20,7 @@ + - change lookup to use reinit instead of reopen. + - update map_hash_table_size description. + - add configuration option to use fqdn in mounts. ++- fix out of order call in program map lookup. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index 3e9c448..a46ff0e 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -200,6 +200,16 @@ static char *lookup_one(struct autofs_point *ap, + } + + /* ++ * By default use a prefix with standard environment ++ * variables to prevent system subversion by interpreted ++ * languages. ++ */ ++ if (defaults_force_std_prog_map_env()) ++ prefix = NULL; ++ else ++ prefix = "AUTOFS_"; ++ ++ /* + * We don't use popen because we don't want to run /bin/sh plus we + * want to send stderr to the syslog, and we don't use spawnl() + * because we need the pipe hooks +@@ -238,16 +248,6 @@ static char *lookup_one(struct autofs_point *ap, + ap->path, ctxt->mapname); + + /* +- * By default use a prefix with standard environment +- * variables to prevent system subversion by interpreted +- * languages. +- */ +- if (defaults_force_std_prog_map_env()) +- prefix = NULL; +- else +- prefix = "AUTOFS_"; +- +- /* + * MAPFMT_DEFAULT must be "sun" for ->parse_init() to have setup + * the macro table. + */ diff --git a/autofs-5.1.1-fix-return-handling-in-sss-lookup-module.patch b/autofs-5.1.1-fix-return-handling-in-sss-lookup-module.patch new file mode 100644 index 0000000..0693ce3 --- /dev/null +++ b/autofs-5.1.1-fix-return-handling-in-sss-lookup-module.patch @@ -0,0 +1,98 @@ +autofs-5.1.1 - fix return handling in sss lookup module + +From: Ian Kent + +In the sss lookup module some of the calls don't distinguish between +no entry found and service unavailable. + +If service unavailable gets returned from a master map read it results +in autofs not updating the mounts. A notfound return doesn't because it +indicates the map doesn't exist so updating the mounts isn't a problem +as it can be when the source is unavailable. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 24 +++++++++++++++++------- + 2 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index bd7b981..ee078bb 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -3,6 +3,7 @@ + - update libtirpc workaround for new soname. + - revert fix libtirpc name clash. + - fix left mount count return from umount_multi_triggers(). ++- fix return handling in sss lookup module. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 528ab41..720b5e3 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -148,9 +148,8 @@ static int setautomntent(unsigned int logopt, + error(logopt, MODPREFIX "setautomntent: %s", estr); + if (*sss_ctxt) + free(*sss_ctxt); +- return 0; + } +- return 1; ++ return ret; + } + + static int endautomntent(unsigned int logopt, +@@ -161,9 +160,8 @@ static int endautomntent(unsigned int logopt, + char buf[MAX_ERR_BUF]; + char *estr = strerror_r(ret, buf, MAX_ERR_BUF); + error(logopt, MODPREFIX "endautomntent: %s", estr); +- return 0; + } +- return 1; ++ return ret; + } + + int lookup_read_master(struct master *master, time_t age, void *context) +@@ -180,8 +178,12 @@ int lookup_read_master(struct master *master, time_t age, void *context) + char *value = NULL; + int count, ret; + +- if (!setautomntent(logopt, ctxt, ctxt->mapname, &sss_ctxt)) ++ ret = setautomntent(logopt, ctxt, ctxt->mapname, &sss_ctxt); ++ if (ret) { ++ if (ret == ENOENT) ++ return NSS_STATUS_NOTFOUND; + return NSS_STATUS_UNAVAIL; ++ } + + count = 0; + while (1) { +@@ -280,8 +282,12 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + return NSS_STATUS_SUCCESS; + } + +- if (!setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt)) ++ ret = setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt); ++ if (ret) { ++ if (ret == ENOENT) ++ return NSS_STATUS_NOTFOUND; + return NSS_STATUS_UNAVAIL; ++ } + + count = 0; + while (1) { +@@ -386,8 +392,12 @@ static int lookup_one(struct autofs_point *ap, + + mc = source->mc; + +- if (!setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt)) ++ ret = setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt); ++ if (ret) { ++ if (ret == ENOENT) ++ return NSS_STATUS_NOTFOUND; + return NSS_STATUS_UNAVAIL; ++ } + + ret = ctxt->getautomntbyname_r(qKey, &value, sss_ctxt); + if (ret && ret != ENOENT) { diff --git a/autofs-5.1.1-fix-return-handling-of-do_reconnect-in-ldap-module.patch b/autofs-5.1.1-fix-return-handling-of-do_reconnect-in-ldap-module.patch new file mode 100644 index 0000000..4763d8d --- /dev/null +++ b/autofs-5.1.1-fix-return-handling-of-do_reconnect-in-ldap-module.patch @@ -0,0 +1,208 @@ +autofs-5.1.1 - fix return handling of do_reconnect() in ldap module + +From: Ian Kent + +In the ldap lookup module the do_reconnect() call doesn't distinguish +between no entry found and service unavailable. + +If service unavailable gets returned from a master map read it results +in autofs not updating the mounts. A notfound return doesn't because it +indicates the map doesn't exist so updating the mounts isn't a problem +as it can be when the source is unavailable. + +Finally make do_reconnect() return a status instead of an LDAP handle +and pass back the LDAP handle via a function parameter. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 78 ++++++++++++++++++++++++++++--------------------- + 2 files changed, 46 insertions(+), 33 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index bc79bc0..fa8231c 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -9,6 +9,7 @@ + - make connect_to_server() return a status. + - make find_dc_server() return a status. + - make find_server() return a status. ++- fix return handling of do_reconnect() in ldap module. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 783239d..7e23869 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -961,31 +961,33 @@ static int find_server(unsigned logopt, + return ret; + } + +-static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) ++static int do_reconnect(unsigned logopt, ++ LDAP **ldap, struct lookup_context *ctxt) + { +- LDAP *ldap = NULL; +- int ret; ++ int ret = NSS_STATUS_UNAVAIL; ++ int dcrv = NSS_STATUS_SUCCESS; ++ int rv = NSS_STATUS_SUCCESS; + + if (ctxt->server || !ctxt->uris) { +- ret = do_connect(logopt, &ldap, ctxt->server, ctxt); ++ ret = do_connect(logopt, ldap, ctxt->server, ctxt); + #ifdef WITH_SASL + /* Dispose of the sasl authentication connection and try again. */ +- if (ret != NSS_STATUS_SUCCESS && +- ctxt->auth_required & LDAP_NEED_AUTH) { ++ if (ctxt->auth_required & LDAP_NEED_AUTH && ++ ret != NSS_STATUS_SUCCESS && ret != NSS_STATUS_NOTFOUND) { + ldapinit_mutex_lock(); + autofs_sasl_dispose(ctxt); + ldapinit_mutex_unlock(); +- ret = connect_to_server(logopt, &ldap, ++ ret = connect_to_server(logopt, ldap, + ctxt->server, ctxt); + } + #endif +- return ldap; ++ return ret; + } + + if (ctxt->dclist) { +- ret = find_dc_server(logopt, &ldap, ctxt->dclist->uri, ctxt); +- if (ret == NSS_STATUS_SUCCESS) +- return ldap; ++ dcrv = find_dc_server(logopt, ldap, ctxt->dclist->uri, ctxt); ++ if (dcrv == NSS_STATUS_SUCCESS) ++ return dcrv; + } + + uris_mutex_lock(ctxt); +@@ -1004,22 +1006,22 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) + if (!ctxt->uri) + goto find_server; + +- ret = do_connect(logopt, &ldap, ctxt->uri->uri, ctxt); ++ rv = do_connect(logopt, ldap, ctxt->uri->uri, ctxt); + #ifdef WITH_SASL + /* + * Dispose of the sasl authentication connection and try the + * current server again before trying other servers in the list. + */ +- if (ret != NSS_STATUS_SUCCESS && +- ctxt->auth_required & LDAP_NEED_AUTH) { ++ if (ctxt->auth_required & LDAP_NEED_AUTH && ++ rv != NSS_STATUS_SUCCESS && rv != NSS_STATUS_NOTFOUND) { + ldapinit_mutex_lock(); + autofs_sasl_dispose(ctxt); + ldapinit_mutex_unlock(); +- ret = connect_to_server(logopt, &ldap, ctxt->uri->uri, ctxt); ++ rv = connect_to_server(logopt, ldap, ctxt->uri->uri, ctxt); + } + #endif +- if (ldap) +- return ldap; ++ if (rv == NSS_STATUS_SUCCESS) ++ return rv; + + /* Failed to connect, try to find a new server */ + +@@ -1031,11 +1033,16 @@ find_server: + #endif + + /* Current server failed, try the rest or dc connection */ +- ret = find_server(logopt, &ldap, ctxt); +- if (ret != NSS_STATUS_SUCCESS) ++ ret = find_server(logopt, ldap, ctxt); ++ if (ret != NSS_STATUS_SUCCESS) { ++ if (ret == NSS_STATUS_NOTFOUND || ++ dcrv == NSS_STATUS_NOTFOUND || ++ rv == NSS_STATUS_NOTFOUND) ++ ret = NSS_STATUS_NOTFOUND; + error(logopt, MODPREFIX "failed to find available server"); ++ } + +- return ldap; ++ return ret; + } + + int get_property(unsigned logopt, xmlNodePtr node, const char *prop, char **value) +@@ -1841,12 +1848,12 @@ int lookup_read_master(struct master *master, time_t age, void *context) + char **values = NULL; + char *attrs[3]; + int scope = LDAP_SCOPE_SUBTREE; +- LDAP *ldap; ++ LDAP *ldap = NULL; + + /* Initialize the LDAP context. */ +- ldap = do_reconnect(logopt, ctxt); +- if (!ldap) +- return NSS_STATUS_UNAVAIL; ++ rv = do_reconnect(logopt, &ldap, ctxt); ++ if (rv) ++ return rv; + + class = ctxt->schema->entry_class; + entry = ctxt->schema->entry_attr; +@@ -2754,9 +2761,10 @@ static int read_one_map(struct autofs_point *ap, + sp.age = age; + + /* Initialize the LDAP context. */ +- sp.ldap = do_reconnect(ap->logopt, ctxt); +- if (!sp.ldap) +- return NSS_STATUS_UNAVAIL; ++ sp.ldap = NULL; ++ rv = do_reconnect(ap->logopt, &sp.ldap, ctxt); ++ if (rv) ++ return rv; + + class = ctxt->schema->entry_class; + entry = ctxt->schema->entry_attr; +@@ -2908,7 +2916,7 @@ static int lookup_one(struct autofs_point *ap, struct map_source *source, + struct berval **bvValues; + char *attrs[3]; + int scope = LDAP_SCOPE_SUBTREE; +- LDAP *ldap; ++ LDAP *ldap = NULL; + struct mapent *we; + unsigned int wild = 0; + int ret = CHE_MISSING; +@@ -2921,9 +2929,11 @@ static int lookup_one(struct autofs_point *ap, struct map_source *source, + } + + /* Initialize the LDAP context. */ +- ldap = do_reconnect(ap->logopt, ctxt); +- if (!ldap) ++ rv = do_reconnect(ap->logopt, &ldap, ctxt); ++ if (rv == NSS_STATUS_UNAVAIL) + return CHE_UNAVAIL; ++ if (rv == NSS_STATUS_NOTFOUND) ++ return ret; + + class = ctxt->schema->entry_class; + entry = ctxt->schema->entry_attr; +@@ -3252,7 +3262,7 @@ static int lookup_one_amd(struct autofs_point *ap, + struct lookup_context *ctxt) + { + struct mapent_cache *mc = source->mc; +- LDAP *ldap; ++ LDAP *ldap = NULL; + LDAPMessage *result = NULL, *e; + char *query; + int scope = LDAP_SCOPE_SUBTREE; +@@ -3271,9 +3281,11 @@ static int lookup_one_amd(struct autofs_point *ap, + } + + /* Initialize the LDAP context. */ +- ldap = do_reconnect(ap->logopt, ctxt); +- if (!ldap) ++ rv = do_reconnect(ap->logopt, &ldap, ctxt); ++ if (rv == NSS_STATUS_UNAVAIL) + return CHE_UNAVAIL; ++ if (rv == NSS_STATUS_NOTFOUND) ++ return ret; + + map = ctxt->schema->map_attr; + class = ctxt->schema->entry_class; diff --git a/autofs-5.1.1-fix-rwlock-unlock-crash.patch b/autofs-5.1.1-fix-rwlock-unlock-crash.patch new file mode 100644 index 0000000..fc3c8f8 --- /dev/null +++ b/autofs-5.1.1-fix-rwlock-unlock-crash.patch @@ -0,0 +1,67 @@ +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(-) + +diff --git a/CHANGELOG b/CHANGELOG +index fa8231c..3bd7145 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -10,6 +10,7 @@ + - make find_dc_server() return a status. + - make find_server() return a status. + - fix return handling of do_reconnect() in ldap module. ++- fix rwlock unlock crash. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/daemon/automount.c b/daemon/automount.c +index c81b4af..6cba3db 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -1757,6 +1757,7 @@ void *handle_mounts(void *arg) + */ + if (ap->type == LKP_DIRECT) { + umount_autofs(ap, NULL, 1); ++ handle_mounts_cleanup(ap); + break; + } + +@@ -1767,8 +1768,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, +@@ -1789,8 +1792,6 @@ void *handle_mounts(void *arg) + } + } + +- handle_mounts_cleanup(ap); +- + return NULL; + } + diff --git a/autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch b/autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch new file mode 100644 index 0000000..0f4ec5c --- /dev/null +++ b/autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch @@ -0,0 +1,836 @@ +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(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 83412a3..663b867 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -32,6 +32,7 @@ + - change time() to use monotonic_clock(). + - remove unused function elapsed(). + - fix unbind sasl external mech. ++- fix sasl connection concurrancy problem. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h +index be4bc1e..3a7aba7 100644 +--- a/include/lookup_ldap.h ++++ b/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); +diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c +index c5e72f7..11a1178 100644 +--- a/modules/cyrus-sasl.c ++++ b/modules/cyrus-sasl.c +@@ -885,16 +885,19 @@ sasl_choose_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) + * 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; + } + } + +@@ -908,13 +911,10 @@ autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt) + * -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; +@@ -923,7 +923,7 @@ autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) + "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", +@@ -953,14 +953,16 @@ autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) + * 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; + } + +@@ -968,19 +970,21 @@ autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) + * 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) { +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 7f50c34..959890a 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -214,7 +214,9 @@ int bind_ldap_simple(unsigned logopt, LDAP *ldap, const char *uri, struct lookup + 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 logopt, LDAP *ldap, struct lookup_context + 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 logopt, const char *uri, struct lookup_con + 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 logopt, const char *uri, struct lookup_con + 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, LDAP *ldap, struct lookup_context *ctx + 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 *ldap, const char *uri, struct lookup_c + 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, LDAP **ldap, + } + #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, LDAP **ldap, + 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, LDAP **ldap, + 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, LDAP **ldap, + * 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, LDAP **ldap, + } 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(struct lookup_context *ctxt) + 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(struct lookup_context *ctxt) + 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(struct lookup_context *ctxt) + 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 logopt, LDAP **ldap, + 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 logopt, LDAP **ldap, + 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 logopt, LDAP **ldap, + } + + 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 < monotonic_time(NULL)) { ++ if (!conn->ldap || ctxt->dclist->expire < monotonic_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 *master, time_t age, void *context) + 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 *master, time_t age, void *context) + 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 *master, time_t age, void *context) + 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 *master, time_t age, void *context) + 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_point *ap, + 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_point *ap, + 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_point *ap, + 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_point *ap, + } + + 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_point *ap, + 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_point *ap, + + 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_point *ap, struct map_source *source, + 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 = monotonic_time(NULL); +@@ -2971,7 +2967,6 @@ static int lookup_one(struct autofs_point *ap, struct map_source *source, + 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_point *ap, struct map_source *source, + } + + /* 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_point *ap, struct map_source *source, + + 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_point *ap, struct map_source *source, + 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_point *ap, + 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_point *ap, + } + + /* 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_point *ap, + 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_point *ap, + 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/autofs-5.1.1-fix-unbind-external-mech.patch b/autofs-5.1.1-fix-unbind-external-mech.patch new file mode 100644 index 0000000..2530b65 --- /dev/null +++ b/autofs-5.1.1-fix-unbind-external-mech.patch @@ -0,0 +1,140 @@ +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(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 4acb332..83412a3 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -31,6 +31,7 @@ + - change remaining gettimeofday() to use clock_gettime(). + - change time() to use monotonic_clock(). + - remove unused function elapsed(). ++- fix unbind sasl external mech. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h +index ba817aa..be4bc1e 100644 +--- a/include/lookup_ldap.h ++++ b/include/lookup_ldap.h +@@ -121,8 +121,8 @@ int authtype_requires_creds(const char *authtype); + 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); +diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c +index 21bc00c..c5e72f7 100644 +--- a/modules/cyrus-sasl.c ++++ b/modules/cyrus-sasl.c +@@ -885,8 +885,13 @@ sasl_choose_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) + * 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; +@@ -963,10 +968,16 @@ autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) + * 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; +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index afc89c1..7f50c34 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -222,7 +222,7 @@ int __unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context + 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/autofs-5.1.1-fix-update_hosts_mounts-return.patch b/autofs-5.1.1-fix-update_hosts_mounts-return.patch new file mode 100644 index 0000000..885a35c --- /dev/null +++ b/autofs-5.1.1-fix-update_hosts_mounts-return.patch @@ -0,0 +1,59 @@ +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(-) + +diff --git a/CHANGELOG b/CHANGELOG +index e22877e..77aad99 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -16,6 +16,7 @@ + - fix direct mount stale instance flag reset. + - fix direct map expire not set for initail empty map. + - fix missing source sss in multi map lookup. ++- fix update_hosts_mounts() return. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index 0d48356..53aa9d6 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -162,9 +162,9 @@ static int do_parse_mount(struct autofs_point *ap, struct map_source *source, + 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/autofs-5.1.1-implement-reinit-in-dir-lookup-module.patch b/autofs-5.1.1-implement-reinit-in-dir-lookup-module.patch new file mode 100644 index 0000000..b0b7da4 --- /dev/null +++ b/autofs-5.1.1-implement-reinit-in-dir-lookup-module.patch @@ -0,0 +1,121 @@ +autofs-5.1.1 - implement reinit in dir lookup module + +From: Ian Kent + +Refactor the dir lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_dir.c | 58 ++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 39 insertions(+), 19 deletions(-) + +diff --git a/modules/lookup_dir.c b/modules/lookup_dir.c +index 7a95e24..2880447 100644 +--- a/modules/lookup_dir.c ++++ b/modules/lookup_dir.c +@@ -50,24 +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) + { +- struct lookup_context *ctxt; +- char buf[MAX_ERR_BUF]; + struct stat st; + +- *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; +- } +- + if (argc < 1) { +- free(ctxt); + logerr(MODPREFIX "No map name"); + return 1; + } +@@ -75,40 +64,71 @@ int lookup_init(const char *mapfmt, + ctxt->mapname = argv[0]; + + if (ctxt->mapname[0] != '/') { +- free(ctxt); + logmsg(MODPREFIX + "dir map %s is not an absolute pathname", argv[0]); + return 1; + } + + if (access(ctxt->mapname, R_OK)) { +- free(ctxt); + warn(LOGOPT_NONE, MODPREFIX + "dir map %s missing or not readable", argv[0]); + return 1; + } + + if (stat(ctxt->mapname, &st)) { +- free(ctxt); + warn(LOGOPT_NONE, MODPREFIX + "dir map %s, could not stat", argv[0]); + return 1; + } + +- if ( (!S_ISDIR(st.st_mode)) && (!S_ISLNK(st.st_mode)) ) { +- free(ctxt); ++ if ((!S_ISDIR(st.st_mode)) && (!S_ISLNK(st.st_mode))) { + warn(LOGOPT_NONE, MODPREFIX + "dir map %s, is not a directory", argv[0]); + return 1; + } + ++ return 0; ++} ++ ++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)) { ++ 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; ++ int ret; ++ ++ ret = do_init(mapfmt, argc, argv, &new); ++ if (ret) ++ return 1; ++ ++ ctxt->mapname = new.mapname; ++ + return 0; + } + diff --git a/autofs-5.1.1-implement-reinit-in-file-lookup-module.patch b/autofs-5.1.1-implement-reinit-in-file-lookup-module.patch new file mode 100644 index 0000000..fae1f5f --- /dev/null +++ b/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/autofs-5.1.1-implement-reinit-in-hesiod-lookup-module.patch b/autofs-5.1.1-implement-reinit-in-hesiod-lookup-module.patch new file mode 100644 index 0000000..1f060b9 --- /dev/null +++ b/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/autofs-5.1.1-implement-reinit-in-hosts-lookup-module.patch b/autofs-5.1.1-implement-reinit-in-hosts-lookup-module.patch new file mode 100644 index 0000000..4180980 --- /dev/null +++ b/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/autofs-5.1.1-implement-reinit-in-ldap-lookup-module.patch b/autofs-5.1.1-implement-reinit-in-ldap-lookup-module.patch new file mode 100644 index 0000000..23214bd --- /dev/null +++ b/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/autofs-5.1.1-implement-reinit-in-multi-lookup-module.patch b/autofs-5.1.1-implement-reinit-in-multi-lookup-module.patch new file mode 100644 index 0000000..bb669fa --- /dev/null +++ b/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/autofs-5.1.1-implement-reinit-in-nisplus-lookup-module.patch b/autofs-5.1.1-implement-reinit-in-nisplus-lookup-module.patch new file mode 100644 index 0000000..eb0eb5c --- /dev/null +++ b/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/autofs-5.1.1-implement-reinit-in-parse-modules.patch b/autofs-5.1.1-implement-reinit-in-parse-modules.patch new file mode 100644 index 0000000..b39731b --- /dev/null +++ b/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/autofs-5.1.1-implement-reinit-in-program-lookup-module.patch b/autofs-5.1.1-implement-reinit-in-program-lookup-module.patch new file mode 100644 index 0000000..4b43b98 --- /dev/null +++ b/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/autofs-5.1.1-implement-reinit-in-sss-lookup-module.patch b/autofs-5.1.1-implement-reinit-in-sss-lookup-module.patch new file mode 100644 index 0000000..ab1104c --- /dev/null +++ b/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/autofs-5.1.1-implement-reinit-in-yp-lookup-module.patch b/autofs-5.1.1-implement-reinit-in-yp-lookup-module.patch new file mode 100644 index 0000000..b0761cc --- /dev/null +++ b/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/autofs-5.1.1-make-connect_to_server-return-a-status.patch b/autofs-5.1.1-make-connect_to_server-return-a-status.patch new file mode 100644 index 0000000..b8cc1e5 --- /dev/null +++ b/autofs-5.1.1-make-connect_to_server-return-a-status.patch @@ -0,0 +1,115 @@ +autofs-5.1.1 - make connect_to_server() return a status + +From: Ian Kent + +In the ldap lookup module the do_reconnect() call doesn't distinguish +between no entry found and service unavailable. + +If service unavailable gets returned from a master map read it results +in autofs not updating the mounts. A notfound return doesn't because it +indicates the map doesn't exist so updating the mounts isn't a problem +as it can be when the source is unavailable. + +Next step in the update of do_reconnect() is to make connect_to_server() +return a status instead of an LDAP handle and pass back the LDAP handle +via a function parameter. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 25 ++++++++++++++----------- + 2 files changed, 15 insertions(+), 11 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 2f1e380..6d57581 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -6,6 +6,7 @@ + - fix return handling in sss lookup module. + - move query dn calculation from do_bind() to do_connect(). + - make do_connect() return a status. ++- make connect_to_server() return a status. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 268c812..776c174 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -824,20 +824,19 @@ next: + return timestamp; + } + +-static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_context *ctxt) ++static int connect_to_server(unsigned logopt, LDAP **ldap, ++ const char *uri, struct lookup_context *ctxt) + { +- LDAP *ldap; + int ret; + +- ret = do_connect(logopt, &ldap, uri, ctxt); ++ ret = do_connect(logopt, ldap, uri, ctxt); + if (ret != NSS_STATUS_SUCCESS) { + warn(logopt, + MODPREFIX "couldn't connect to server %s", + uri ? uri : "default"); +- return NULL; + } + +- return ldap; ++ return ret; + } + + static LDAP *find_dc_server(unsigned logopt, const char *uri, struct lookup_context *ctxt) +@@ -852,9 +851,11 @@ static LDAP *find_dc_server(unsigned logopt, const char *uri, struct lookup_cont + tok = strtok_r(str, " ", &ptr); + while (tok) { + const char *this = (const char *) tok; ++ int ret; ++ + debug(logopt, "trying server uri %s", this); +- ldap = connect_to_server(logopt, this, ctxt); +- if (ldap) { ++ ret = connect_to_server(logopt, &ldap, this, ctxt); ++ if (ret == NSS_STATUS_SUCCESS) { + info(logopt, "connected to uri %s", this); + free(str); + return ldap; +@@ -874,6 +875,7 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + struct list_head *p, *first; + struct dclist *dclist; + char *uri = NULL; ++ int ret; + + uris_mutex_lock(ctxt); + dclist = ctxt->dclist; +@@ -896,8 +898,8 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + if (!strstr(this->uri, ":///")) { + uri = strdup(this->uri); + debug(logopt, "trying server uri %s", uri); +- ldap = connect_to_server(logopt, uri, ctxt); +- if (ldap) { ++ ret = connect_to_server(logopt, &ldap, uri, ctxt); ++ if (ret == NSS_STATUS_SUCCESS) { + info(logopt, "connected to uri %s", uri); + free(uri); + break; +@@ -962,7 +964,8 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) + ldapinit_mutex_lock(); + autofs_sasl_dispose(ctxt); + ldapinit_mutex_unlock(); +- ldap = connect_to_server(logopt, ctxt->server, ctxt); ++ ret = connect_to_server(logopt, &ldap, ++ ctxt->server, ctxt); + } + #endif + return ldap; +@@ -1001,7 +1004,7 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) + ldapinit_mutex_lock(); + autofs_sasl_dispose(ctxt); + ldapinit_mutex_unlock(); +- ldap = connect_to_server(logopt, ctxt->uri->uri, ctxt); ++ ret = connect_to_server(logopt, &ldap, ctxt->uri->uri, ctxt); + } + #endif + if (ldap) diff --git a/autofs-5.1.1-make-do_connect-return-a-status.patch b/autofs-5.1.1-make-do_connect-return-a-status.patch new file mode 100644 index 0000000..8949437 --- /dev/null +++ b/autofs-5.1.1-make-do_connect-return-a-status.patch @@ -0,0 +1,184 @@ +autofs-5.1.1 - make do_connect() return a status + +From: Ian Kent + +In the ldap lookup module the do_reconnect() call doesn't distinguish +between no entry found and service unavailable. + +If service unavailable gets returned from a master map read it results +in autofs not updating the mounts. A notfound return doesn't because it +indicates the map doesn't exist so updating the mounts isn't a problem +as it can be when the source is unavailable. + +The next step in the update of do_reconnect() is to make do_connect() +return a status instead of an LDAP handle and pass back the LDAP handle +via a function parameter. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 60 ++++++++++++++++++++++++++++++------------------- + 2 files changed, 38 insertions(+), 23 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 0be1bf2..2f1e380 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -5,6 +5,7 @@ + - fix left mount count return from umount_multi_triggers(). + - fix return handling in sss lookup module. + - move query dn calculation from do_bind() to do_connect(). ++- make do_connect() return a status. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index ea63736..268c812 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -631,10 +631,14 @@ static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_c + return 1; + } + +-static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context *ctxt) ++static int do_connect(unsigned logopt, LDAP **ldap, ++ const char *uri, struct lookup_context *ctxt) + { + char *cur_host = NULL; +- LDAP *ldap; ++ LDAP *handle; ++ int ret = NSS_STATUS_SUCCESS; ++ ++ *ldap = NULL; + + #ifdef WITH_SASL + if (ctxt->extern_cert && ctxt->extern_key) { +@@ -643,18 +647,20 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context + } + #endif + +- ldap = init_ldap_connection(logopt, uri, ctxt); +- if (!ldap) ++ handle = init_ldap_connection(logopt, uri, ctxt); ++ if (!handle) { ++ ret = NSS_STATUS_UNAVAIL; + goto out; ++ } + + uris_mutex_lock(ctxt); + if (ctxt->cur_host) + cur_host = ctxt->cur_host; + uris_mutex_unlock(ctxt); + +- if (!do_bind(logopt, ldap, uri, ctxt)) { +- unbind_ldap_connection(logopt, ldap, ctxt); +- ldap = NULL; ++ if (!do_bind(logopt, handle, uri, ctxt)) { ++ unbind_ldap_connection(logopt, handle, ctxt); ++ ret = NSS_STATUS_UNAVAIL; + goto out; + } + +@@ -664,7 +670,8 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context + uris_mutex_lock(ctxt); + if (ctxt->schema && ctxt->qdn && (cur_host == ctxt->cur_host)) { + uris_mutex_unlock(ctxt); +- return ldap; ++ *ldap = handle; ++ goto out; + } + uris_mutex_unlock(ctxt); + +@@ -674,9 +681,9 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context + * base dn for searches. + */ + if (!ctxt->schema) { +- if (!find_query_dn(logopt, ldap, ctxt)) { +- unbind_ldap_connection(logopt, ldap, ctxt); +- ldap = NULL; ++ if (!find_query_dn(logopt, handle, ctxt)) { ++ unbind_ldap_connection(logopt, handle, ctxt); ++ ret = NSS_STATUS_NOTFOUND; + warn(logopt, + MODPREFIX "failed to find valid query dn"); + goto out; +@@ -684,14 +691,17 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context + } 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, ldap, ctxt, class, key)) { +- unbind_ldap_connection(logopt, ldap, ctxt); +- ldap = NULL; ++ if (!get_query_dn(logopt, handle, ctxt, class, key)) { ++ unbind_ldap_connection(logopt, handle, ctxt); ++ ret = NSS_STATUS_NOTFOUND; + error(logopt, MODPREFIX "failed to get query dn"); ++ goto out; + } + } ++ ++ *ldap = handle; + out: +- return ldap; ++ return ret; + } + + static unsigned long get_amd_timestamp(struct lookup_context *ctxt) +@@ -706,8 +716,8 @@ static unsigned long get_amd_timestamp(struct lookup_context *ctxt) + unsigned long timestamp = 0; + int rv, l, ql; + +- ldap = do_connect(LOGOPT_ANY, ctxt->server, ctxt); +- if (!ldap) ++ rv = do_connect(LOGOPT_ANY, &ldap, ctxt->server, ctxt); ++ if (rv != NSS_STATUS_SUCCESS) + return 0; + + map = amd_timestamp.map_attr; +@@ -817,9 +827,10 @@ next: + static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_context *ctxt) + { + LDAP *ldap; ++ int ret; + +- ldap = do_connect(logopt, uri, ctxt); +- if (!ldap) { ++ ret = do_connect(logopt, &ldap, uri, ctxt); ++ if (ret != NSS_STATUS_SUCCESS) { + warn(logopt, + MODPREFIX "couldn't connect to server %s", + uri ? uri : "default"); +@@ -940,12 +951,14 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) + { + LDAP *ldap = NULL; ++ int ret; + + if (ctxt->server || !ctxt->uris) { +- ldap = do_connect(logopt, ctxt->server, ctxt); ++ ret = do_connect(logopt, &ldap, ctxt->server, ctxt); + #ifdef WITH_SASL + /* Dispose of the sasl authentication connection and try again. */ +- if (!ldap && ctxt->auth_required & LDAP_NEED_AUTH) { ++ if (ret != NSS_STATUS_SUCCESS && ++ ctxt->auth_required & LDAP_NEED_AUTH) { + ldapinit_mutex_lock(); + autofs_sasl_dispose(ctxt); + ldapinit_mutex_unlock(); +@@ -977,13 +990,14 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) + if (!ctxt->uri) + goto find_server; + +- ldap = do_connect(logopt, ctxt->uri->uri, ctxt); ++ ret = do_connect(logopt, &ldap, ctxt->uri->uri, ctxt); + #ifdef WITH_SASL + /* + * Dispose of the sasl authentication connection and try the + * current server again before trying other servers in the list. + */ +- if (!ldap && ctxt->auth_required & LDAP_NEED_AUTH) { ++ if (ret != NSS_STATUS_SUCCESS && ++ ctxt->auth_required & LDAP_NEED_AUTH) { + ldapinit_mutex_lock(); + autofs_sasl_dispose(ctxt); + ldapinit_mutex_unlock(); diff --git a/autofs-5.1.1-make-find_dc_server-return-a-status.patch b/autofs-5.1.1-make-find_dc_server-return-a-status.patch new file mode 100644 index 0000000..5b6df5c --- /dev/null +++ b/autofs-5.1.1-make-find_dc_server-return-a-status.patch @@ -0,0 +1,105 @@ +autofs-5.1.1 - make find_dc_server() return a status + +From: Ian Kent + +In the ldap lookup module the do_reconnect() call doesn't distinguish +between no entry found and service unavailable. + +If service unavailable gets returned from a master map read it results +in autofs not updating the mounts. A notfound return doesn't because it +indicates the map doesn't exist so updating the mounts isn't a problem +as it can be when the source is unavailable. + +Next step in the update of do_reconnect() is to make find_dc_server() +return a status instead of an LDAP handle and pass back the LDAP handle +via a function parameter. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 27 +++++++++++++++------------ + 2 files changed, 16 insertions(+), 12 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 6d57581..99f465a 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -7,6 +7,7 @@ + - move query dn calculation from do_bind() to do_connect(). + - make do_connect() return a status. + - make connect_to_server() return a status. ++- make find_dc_server() return a status. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 776c174..02d9ca9 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -839,33 +839,36 @@ static int connect_to_server(unsigned logopt, LDAP **ldap, + return ret; + } + +-static LDAP *find_dc_server(unsigned logopt, const char *uri, struct lookup_context *ctxt) ++static int find_dc_server(unsigned logopt, LDAP **ldap, ++ const char *uri, struct lookup_context *ctxt) + { + char *str, *tok, *ptr = NULL; +- LDAP *ldap = NULL; ++ int ret = NSS_STATUS_UNAVAIL; + + str = strdup(uri); + if (!str) +- return NULL; ++ return ret; + + tok = strtok_r(str, " ", &ptr); + while (tok) { + const char *this = (const char *) tok; +- int ret; ++ int rv; + + debug(logopt, "trying server uri %s", this); +- ret = connect_to_server(logopt, &ldap, this, ctxt); +- if (ret == NSS_STATUS_SUCCESS) { ++ rv = connect_to_server(logopt, ldap, this, ctxt); ++ if (rv == NSS_STATUS_SUCCESS) { + info(logopt, "connected to uri %s", this); + free(str); +- return ldap; ++ return rv; + } ++ if (rv == NSS_STATUS_NOTFOUND) ++ ret = NSS_STATUS_NOTFOUND; + tok = strtok_r(NULL, " ", &ptr); + } + + free(str); + +- return NULL; ++ return ret; + } + + static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) +@@ -917,8 +920,8 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + dclist = tmp; + uri = strdup(dclist->uri); + } +- ldap = find_dc_server(logopt, uri, ctxt); +- if (ldap) { ++ ret = find_dc_server(logopt, &ldap, uri, ctxt); ++ if (ret == NSS_STATUS_SUCCESS) { + free(uri); + break; + } +@@ -972,8 +975,8 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) + } + + if (ctxt->dclist) { +- ldap = find_dc_server(logopt, ctxt->dclist->uri, ctxt); +- if (ldap) ++ ret = find_dc_server(logopt, &ldap, ctxt->dclist->uri, ctxt); ++ if (ret == NSS_STATUS_SUCCESS) + return ldap; + } + diff --git a/autofs-5.1.1-make-find_server-return-a-status.patch b/autofs-5.1.1-make-find_server-return-a-status.patch new file mode 100644 index 0000000..661d61e --- /dev/null +++ b/autofs-5.1.1-make-find_server-return-a-status.patch @@ -0,0 +1,121 @@ +autofs-5.1.1 - make find_server() return a status + +From: Ian Kent + +In the ldap lookup module the do_reconnect() call doesn't distinguish +between no entry found and service unavailable. + +If service unavailable gets returned from a master map read it results +in autofs not updating the mounts. A notfound return doesn't because it +indicates the map doesn't exist so updating the mounts isn't a problem +as it can be when the source is unavailable. + +Next step in the update of do_reconnect() is to make find_server() +return a status instead of an LDAP handle and pass back the LDAP handle +via a function parameter. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 30 +++++++++++++++++++----------- + 2 files changed, 20 insertions(+), 11 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 99f465a..bc79bc0 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -8,6 +8,7 @@ + - make do_connect() return a status. + - make connect_to_server() return a status. + - make find_dc_server() return a status. ++- make find_server() return a status. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 02d9ca9..783239d 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -871,14 +871,14 @@ static int find_dc_server(unsigned logopt, LDAP **ldap, + return ret; + } + +-static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) ++static int find_server(unsigned logopt, ++ LDAP **ldap, struct lookup_context *ctxt) + { +- LDAP *ldap = NULL; +- struct ldap_uri *this; ++ struct ldap_uri *this = NULL; + struct list_head *p, *first; + struct dclist *dclist; + char *uri = NULL; +- int ret; ++ int ret = NSS_STATUS_UNAVAIL; + + uris_mutex_lock(ctxt); + dclist = ctxt->dclist; +@@ -892,6 +892,8 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + /* Try each uri, save point in server list upon success */ + p = first->next; + while(p != first) { ++ int rv; ++ + /* Skip list head */ + if (p == ctxt->uris) { + p = p->next; +@@ -901,12 +903,15 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + if (!strstr(this->uri, ":///")) { + uri = strdup(this->uri); + debug(logopt, "trying server uri %s", uri); +- ret = connect_to_server(logopt, &ldap, uri, ctxt); +- if (ret == NSS_STATUS_SUCCESS) { ++ rv = connect_to_server(logopt, ldap, uri, ctxt); ++ if (rv == NSS_STATUS_SUCCESS) { ++ ret = NSS_STATUS_SUCCESS; + info(logopt, "connected to uri %s", uri); + free(uri); + break; + } ++ if (rv == NSS_STATUS_NOTFOUND) ++ ret = NSS_STATUS_NOTFOUND; + } else { + if (dclist) + uri = strdup(dclist->uri); +@@ -920,11 +925,14 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + dclist = tmp; + uri = strdup(dclist->uri); + } +- ret = find_dc_server(logopt, &ldap, uri, ctxt); +- if (ret == NSS_STATUS_SUCCESS) { ++ rv = find_dc_server(logopt, ldap, uri, ctxt); ++ if (rv == NSS_STATUS_SUCCESS) { ++ ret = NSS_STATUS_SUCCESS; + free(uri); + break; + } ++ if (rv == NSS_STATUS_NOTFOUND) ++ ret = NSS_STATUS_NOTFOUND; + } + free(uri); + uri = NULL; +@@ -950,7 +958,7 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + } + uris_mutex_unlock(ctxt); + +- return ldap; ++ return ret; + } + + static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) +@@ -1023,8 +1031,8 @@ find_server: + #endif + + /* Current server failed, try the rest or dc connection */ +- ldap = find_server(logopt, ctxt); +- if (!ldap) ++ ret = find_server(logopt, &ldap, ctxt); ++ if (ret != NSS_STATUS_SUCCESS) + error(logopt, MODPREFIX "failed to find available server"); + + return ldap; diff --git a/autofs-5.1.1-make-open_lookup-return-nss-status.patch b/autofs-5.1.1-make-open_lookup-return-nss-status.patch new file mode 100644 index 0000000..15367f0 --- /dev/null +++ b/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/autofs-5.1.1-move-check_nss_result-to-nsswitch_c.patch b/autofs-5.1.1-move-check_nss_result-to-nsswitch_c.patch new file mode 100644 index 0000000..68aeed1 --- /dev/null +++ b/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/autofs-5.1.1-move-query-dn-calculation-from-do_bind-to-do_connect.patch b/autofs-5.1.1-move-query-dn-calculation-from-do_bind-to-do_connect.patch new file mode 100644 index 0000000..cbea3d6 --- /dev/null +++ b/autofs-5.1.1-move-query-dn-calculation-from-do_bind-to-do_connect.patch @@ -0,0 +1,160 @@ +autofs-5.1.1 - move query dn calculation from do_bind() to do_connect() + +From: Ian Kent + +In the ldap lookup module the do_reconnect() call doesn't distinguish +between no entry found and service unavailable. + +If service unavailable gets returned from a master map read it results +in autofs not updating the mounts. A notfound return doesn't because it +indicates the map doesn't exist so updating the mounts isn't a problem +as it can be when the source is unavailable. + +Start the update of do_reconnect() by moving the query dn calculation +from do_bind() to do_connect(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 81 ++++++++++++++++++++++++++++++------------------- + 2 files changed, 51 insertions(+), 31 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index ee078bb..0be1bf2 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -4,6 +4,7 @@ + - revert fix libtirpc name clash. + - fix left mount count return from umount_multi_triggers(). + - fix return handling in sss lookup module. ++- move query dn calculation from do_bind() to do_connect(). + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 5da613e..ea63736 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -574,7 +574,7 @@ static int find_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctx + static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt) + { + char *host = NULL, *nhost; +- int rv, need_base = 1; ++ int rv; + + #ifdef WITH_SASL + debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s", +@@ -610,6 +610,7 @@ static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_c + } + ldap_memfree(host); + ++ uris_mutex_lock(ctxt); + if (!ctxt->cur_host) { + ctxt->cur_host = nhost; + if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) { +@@ -618,43 +619,21 @@ static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_c + } + } else { + /* If connection host has changed update */ +- if (strcmp(ctxt->cur_host, nhost)) { ++ if (!strcmp(ctxt->cur_host, nhost)) ++ free(nhost); ++ else { + free(ctxt->cur_host); + ctxt->cur_host = nhost; +- } else { +- free(nhost); +- need_base = 0; +- } +- } +- +- if (ctxt->schema && ctxt->qdn && !need_base) +- return 1; +- +- /* +- * If the schema isn't defined in the configuration then check for +- * presence of a map dn with a the common schema. Then calculate the +- * base dn for searches. +- */ +- if (!ctxt->schema) { +- if (!find_query_dn(logopt, ldap, ctxt)) { +- warn(logopt, +- MODPREFIX "failed to find valid query dn"); +- return 0; +- } +- } 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, ldap, ctxt, class, key)) { +- error(logopt, MODPREFIX "failed to get query dn"); +- return 0; + } + } ++ uris_mutex_unlock(ctxt); + + return 1; + } + + static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context *ctxt) + { ++ char *cur_host = NULL; + LDAP *ldap; + + #ifdef WITH_SASL +@@ -665,13 +644,53 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context + #endif + + ldap = init_ldap_connection(logopt, uri, ctxt); +- if (ldap) { +- if (!do_bind(logopt, ldap, uri, ctxt)) { ++ if (!ldap) ++ goto out; ++ ++ uris_mutex_lock(ctxt); ++ if (ctxt->cur_host) ++ cur_host = ctxt->cur_host; ++ uris_mutex_unlock(ctxt); ++ ++ if (!do_bind(logopt, ldap, uri, ctxt)) { ++ unbind_ldap_connection(logopt, ldap, ctxt); ++ ldap = NULL; ++ goto out; ++ } ++ ++ /* If the lookup schema and the query dn are set and the ++ * ldap host hasn't changed return. ++ */ ++ uris_mutex_lock(ctxt); ++ if (ctxt->schema && ctxt->qdn && (cur_host == ctxt->cur_host)) { ++ uris_mutex_unlock(ctxt); ++ return ldap; ++ } ++ uris_mutex_unlock(ctxt); ++ ++ /* ++ * If the schema isn't defined in the configuration then check for ++ * presence of a map dn with a the common schema. Then calculate the ++ * base dn for searches. ++ */ ++ if (!ctxt->schema) { ++ if (!find_query_dn(logopt, ldap, ctxt)) { ++ unbind_ldap_connection(logopt, ldap, ctxt); ++ ldap = NULL; ++ warn(logopt, ++ MODPREFIX "failed to find valid query dn"); ++ goto out; ++ } ++ } 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, ldap, ctxt, class, key)) { + unbind_ldap_connection(logopt, ldap, ctxt); + ldap = NULL; ++ error(logopt, MODPREFIX "failed to get query dn"); + } + } +- ++out: + return ldap; + } + diff --git a/autofs-5.1.1-remove-unused-function-elapsed.patch b/autofs-5.1.1-remove-unused-function-elapsed.patch new file mode 100644 index 0000000..4c4f1d7 --- /dev/null +++ b/autofs-5.1.1-remove-unused-function-elapsed.patch @@ -0,0 +1,57 @@ +autofs-5.1.1 - remove unused function elapsed() + +From: Ian Kent + +Now that the monotonic clock source is used the elapsed() function +is no longer used, remove it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/rpc_subs.h | 1 - + lib/rpc_subs.c | 8 -------- + 3 files changed, 1 insertion(+), 9 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 4f589db..4acb332 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -30,6 +30,7 @@ + - use monotonic clock for indirect mount condition. + - change remaining gettimeofday() to use clock_gettime(). + - change time() to use monotonic_clock(). ++- remove unused function elapsed(). + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/include/rpc_subs.h b/include/rpc_subs.h +index e329224..e744e89 100644 +--- a/include/rpc_subs.h ++++ b/include/rpc_subs.h +@@ -70,7 +70,6 @@ int rpc_portmap_getclient(struct conn_info *, const char *, struct sockaddr *, s + int rpc_portmap_getport(struct conn_info *, struct pmap *, unsigned short *); + int rpc_ping_proto(struct conn_info *); + int rpc_ping(const char *, long, long, unsigned int); +-double elapsed(struct timeval, struct timeval); + double monotonic_elapsed(struct timespec, struct timespec); + int rpc_time(const char *, unsigned int, unsigned int, long, long, unsigned int, double *); + const char *get_addr_string(struct sockaddr *, char *, socklen_t); +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 4a84c16..8995996 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -1067,14 +1067,6 @@ int rpc_ping(const char *host, long seconds, long micros, unsigned int option) + return status; + } + +-double elapsed(struct timeval start, struct timeval end) +-{ +- double t1, t2; +- t1 = (double)start.tv_sec + (double)start.tv_usec/(1000*1000); +- t2 = (double)end.tv_sec + (double)end.tv_usec/(1000*1000); +- return t2-t1; +-} +- + double monotonic_elapsed(struct timespec start, struct timespec end) + { + double t1, t2; diff --git a/autofs-5.1.1-update-map_hash_table_size-description.patch b/autofs-5.1.1-update-map_hash_table_size-description.patch new file mode 100644 index 0000000..1885f78 --- /dev/null +++ b/autofs-5.1.1-update-map_hash_table_size-description.patch @@ -0,0 +1,108 @@ +autofs-5.1.1 - update map_hash_table_size description + +From: Ian Kent + +The configuration parameter map_hash_table_size has been ommitted +from the autofs.conf(5) man page and it's description in the +configuration file comments is poor. + +Add a description of the parameter to autofs.conf(5) and update +the configuration file comments to direct people to the map page +for more information. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + man/autofs.conf.5.in | 31 +++++++++++++++++++++++++++++++ + redhat/autofs.conf.default.in | 6 ++++-- + samples/autofs.conf.default.in | 6 ++++-- + 4 files changed, 40 insertions(+), 4 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 16e5344..2b8d224 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -18,6 +18,7 @@ + - fix missing source sss in multi map lookup. + - fix update_hosts_mounts() return. + - change lookup to use reinit instead of reopen. ++- update map_hash_table_size description. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/man/autofs.conf.5.in b/man/autofs.conf.5.in +index 7d66878..4434eb8 100644 +--- a/man/autofs.conf.5.in ++++ b/man/autofs.conf.5.in +@@ -80,6 +80,37 @@ user setting these standard environment variables opens automount(8) to + potential user privilege escalation when the program map is written in a + language that can load components from, for example, a user home directory + (program default "no"). ++.TP ++.B map_hash_table_size ++.br ++This configuration option may be used to change the number of hash ++table slots (default 1024). ++ ++This configuration option affects the overhead of searching the map ++entry cache for map entries when there are a large number of entries. ++It affects the number of entries that must be looked at to locate a ++map entry in the map entry cache. For example, the default of 1024 ++and a direct map with 8000 entries would result in each slot ++containing an average of 8 entries, which should be acceptable. ++ ++However, if excessive CPU usage is observed during automount lookups ++increasing this option can reduce the CPU overhead considerably becuase ++it reduces the length of the search chains. ++ ++Note that the number of entries in a map doesn't necessarily relate ++to the number of entries used in the map entry cache. ++ ++There are three distinct cases, direct maps and indirect maps that ++use the "browse" option must be read in their entirity at program ++start so, in these two cases the map size does retate directly to ++the map entry cache size. ++ ++For indirect maps that do not use the "browse" option entries are ++added to the map entry cache at lookup so the number of active cache ++entries, in this case, is usually much less than the number of entries ++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. + .SS LDAP Configuration + .P + Configuration settings available are: +diff --git a/redhat/autofs.conf.default.in b/redhat/autofs.conf.default.in +index 13bbb7e..da0882f 100644 +--- a/redhat/autofs.conf.default.in ++++ b/redhat/autofs.conf.default.in +@@ -135,8 +135,10 @@ mount_nfs_default_protocol = 4 + #auth_conf_file = @@autofsmapdir@@/autofs_ldap_auth.conf + # + # map_hash_table_size - set the map cache hash table size. +-# Should be a power of 2 with a ratio roughly +-# between 1:10 and 1:20 for each map. ++# Should be a power of 2 with a ratio of ++# close to 1:8 for acceptable performance ++# with maps up to around 8000 entries. ++# See autofs.conf(5) for more details. + # + #map_hash_table_size = 1024 + # +diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in +index 441b68e..80abb43 100644 +--- a/samples/autofs.conf.default.in ++++ b/samples/autofs.conf.default.in +@@ -134,8 +134,10 @@ browse_mode = no + #auth_conf_file = @@autofsmapdir@@/autofs_ldap_auth.conf + # + # map_hash_table_size - set the map cache hash table size. +-# Should be a power of 2 with a ratio roughly +-# between 1:10 and 1:20 for each map. ++# Should be a power of 2 with a ratio of ++# close to 1:8 for acceptable performance ++# with maps up to around 8000 entries. ++# See autofs.conf(5) for more details. + # + #map_hash_table_size = 1024 + # diff --git a/autofs-5.1.1-use-monotonic-clock-for-alarm-thread-condition-wait.patch b/autofs-5.1.1-use-monotonic-clock-for-alarm-thread-condition-wait.patch new file mode 100644 index 0000000..5a388b2 --- /dev/null +++ b/autofs-5.1.1-use-monotonic-clock-for-alarm-thread-condition-wait.patch @@ -0,0 +1,109 @@ +autofs-5.1.1 - use monotonic clock for alarm thread condition wait + +From: Yu Ning + +The time returned by gettimeofday() is affected by discontinuous jumps +in the system time, so it causes an issue that autofs may not auto +unmount a mount point if system time is manually changed by the system +administrator. + +To fix the issue we need to convert to using a monotonic clock source +instead of the clock source used by gettimeofday(). + +Convert the alarm_handler() to use a monotonic clock source. + +Signed-off-by: Yu Ning +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/alarm.c | 28 ++++++++++++++++++++++------ + 2 files changed, 23 insertions(+), 6 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 566a6c6..c443f49 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -24,6 +24,7 @@ + - fix error handling of is_mounted(). + - Add a mode option for master map entries. + - define monotonic clock helper functions. ++- use monotonic clock for alarm thread condition wait. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/lib/alarm.c b/lib/alarm.c +index 0f04ef8..e6a880b 100755 +--- a/lib/alarm.c ++++ b/lib/alarm.c +@@ -23,7 +23,7 @@ struct alarm { + }; + + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +-static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; ++static pthread_cond_t cond; + static LIST_HEAD(alarms); + + #define alarm_lock() \ +@@ -46,7 +46,7 @@ int alarm_add(struct autofs_point *ap, time_t seconds) + struct list_head *head; + struct list_head *p; + struct alarm *new; +- time_t now = time(NULL); ++ time_t now = monotonic_time(NULL); + time_t next_alarm = 0; + unsigned int empty = 1; + int status; +@@ -175,17 +175,18 @@ static void *alarm_handler(void *arg) + + first = list_entry(head->next, struct alarm, list); + +- now = time(NULL); ++ now = monotonic_time(NULL); + + if (first->time > now) { +- struct timeval usecs; ++ struct timespec nsecs; ++ + /* + * Wait for alarm to trigger or a new alarm + * to be added. + */ +- gettimeofday(&usecs, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &nsecs); + expire.tv_sec = first->time; +- expire.tv_nsec = usecs.tv_usec * 1000; ++ expire.tv_nsec = nsecs.tv_nsec; + + status = pthread_cond_timedwait(&cond, &mutex, &expire); + if (status && status != ETIMEDOUT) +@@ -212,6 +213,7 @@ int alarm_start_handler(void) + pthread_t thid; + pthread_attr_t attrs; + pthread_attr_t *pattrs = &attrs; ++ pthread_condattr_t condattrs; + int status; + + status = pthread_attr_init(pattrs); +@@ -224,8 +226,22 @@ int alarm_start_handler(void) + #endif + } + ++ status = pthread_condattr_init(&condattrs); ++ if (status) ++ fatal(status); ++ ++ status = pthread_condattr_setclock(&condattrs, CLOCK_MONOTONIC); ++ if (status) ++ fatal(status); ++ ++ status = pthread_cond_init(&cond, &condattrs); ++ if (status) ++ fatal(status); ++ + status = pthread_create(&thid, pattrs, alarm_handler, NULL); + ++ pthread_condattr_destroy(&condattrs); ++ + if (pattrs) + pthread_attr_destroy(pattrs); + diff --git a/autofs-5.1.1-use-monotonic-clock-for-direct-mount-condition.patch b/autofs-5.1.1-use-monotonic-clock-for-direct-mount-condition.patch new file mode 100644 index 0000000..6e39852 --- /dev/null +++ b/autofs-5.1.1-use-monotonic-clock-for-direct-mount-condition.patch @@ -0,0 +1,100 @@ +autofs-5.1.1 - use monotonic clock for direct mount condition + +From: Yu Ning + +The time returned by gettimeofday() is affected by discontinuous jumps +in the system time, so it causes an issue that autofs may not auto +unmount a mount point if system time is manually changed by the system +administrator. + +To fix the issue we need to convert to using a monotonic clock source +instead of the clock source used by gettimeofday(). + +Change the direct mount and expire thread creation to use a monotonic +clock source. + +Signed-off-by: Yu Ning +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 20 ++++++-------------- + 2 files changed, 7 insertions(+), 14 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 20a64a7..e3b1f04 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -26,6 +26,7 @@ + - define monotonic clock helper functions. + - use monotonic clock for alarm thread condition wait. + - define pending condition init helper function. ++- use monotonic clock for direct mount condition. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/daemon/direct.c b/daemon/direct.c +index 1962a58..9b7fd76 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -1045,7 +1045,6 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di + char buf[MAX_ERR_BUF]; + pthread_t thid; + struct timespec wait; +- struct timeval now; + int status, state; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); +@@ -1115,9 +1114,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di + return 1; + } + +- status = pthread_cond_init(&mt->cond, NULL); +- if (status) +- fatal(status); ++ pending_cond_init(mt); + + status = pthread_mutex_init(&mt->mutex, NULL); + if (status) +@@ -1163,9 +1160,8 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di + + mt->signaled = 0; + while (!mt->signaled) { +- gettimeofday(&now, NULL); +- wait.tv_sec = now.tv_sec + 2; +- wait.tv_nsec = now.tv_usec * 1000; ++ clock_gettime(CLOCK_MONOTONIC, &wait); ++ wait.tv_sec += 2; + status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait); + if (status && status != ETIMEDOUT) + fatal(status); +@@ -1300,7 +1296,6 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + char buf[MAX_ERR_BUF]; + int status = 0; + struct timespec wait; +- struct timeval now; + int ioctlfd, len, state; + unsigned int kver_major = get_kver_major(); + unsigned int kver_minor = get_kver_minor(); +@@ -1431,9 +1426,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + } + memset(mt, 0, sizeof(struct pending_args)); + +- status = pthread_cond_init(&mt->cond, NULL); +- if (status) +- fatal(status); ++ pending_cond_init(mt); + + status = pthread_mutex_init(&mt->mutex, NULL); + if (status) +@@ -1482,9 +1475,8 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + + mt->signaled = 0; + while (!mt->signaled) { +- gettimeofday(&now, NULL); +- wait.tv_sec = now.tv_sec + 2; +- wait.tv_nsec = now.tv_usec * 1000; ++ clock_gettime(CLOCK_MONOTONIC, &wait); ++ wait.tv_sec += 2; + status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait); + if (status && status != ETIMEDOUT) + fatal(status); diff --git a/autofs-5.1.1-use-monotonic-clock-for-indirect-mount-condition.patch b/autofs-5.1.1-use-monotonic-clock-for-indirect-mount-condition.patch new file mode 100644 index 0000000..9d3a4ef --- /dev/null +++ b/autofs-5.1.1-use-monotonic-clock-for-indirect-mount-condition.patch @@ -0,0 +1,100 @@ +autofs-5.1.1 - use monotonic clock for indirect mount condition + +From: Yu Ning + +The time returned by gettimeofday() is affected by discontinuous jumps +in the system time, so it causes an issue that autofs may not auto +unmount a mount point if system time is manually changed by the system +administrator. + +To fix the issue we need to convert to using a monotonic clock source +instead of the clock source used by gettimeofday(). + +Change the indirect mount and expire thread creation to use a monotonic +clock source. + +Signed-off-by: Yu Ning +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/indirect.c | 20 ++++++-------------- + 2 files changed, 7 insertions(+), 14 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index e3b1f04..c243a8a 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -27,6 +27,7 @@ + - use monotonic clock for alarm thread condition wait. + - define pending condition init helper function. + - use monotonic clock for direct mount condition. ++- use monotonic clock for indirect mount condition. + + 21/04/2015 autofs-5.1.1 + ======================= +diff --git a/daemon/indirect.c b/daemon/indirect.c +index bfd181d..263fff1 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -640,7 +640,6 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_ + char buf[MAX_ERR_BUF]; + pthread_t thid; + struct timespec wait; +- struct timeval now; + int status, state; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); +@@ -658,9 +657,7 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_ + return 1; + } + +- status = pthread_cond_init(&mt->cond, NULL); +- if (status) +- fatal(status); ++ pending_cond_init(mt); + + status = pthread_mutex_init(&mt->mutex, NULL); + if (status) +@@ -695,9 +692,8 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_ + + mt->signaled = 0; + while (!mt->signaled) { +- gettimeofday(&now, NULL); +- wait.tv_sec = now.tv_sec + 2; +- wait.tv_nsec = now.tv_usec * 1000; ++ clock_gettime(CLOCK_MONOTONIC, &wait); ++ wait.tv_sec += 2; + status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait); + if (status && status != ETIMEDOUT) + fatal(status); +@@ -799,7 +795,6 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin + char buf[MAX_ERR_BUF]; + struct pending_args *mt; + struct timespec wait; +- struct timeval now; + struct mapent *me; + int status, state; + +@@ -845,9 +840,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin + } + memset(mt, 0, sizeof(struct pending_args)); + +- status = pthread_cond_init(&mt->cond, NULL); +- if (status) +- fatal(status); ++ pending_cond_init(mt); + + status = pthread_mutex_init(&mt->mutex, NULL); + if (status) +@@ -888,9 +881,8 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin + + mt->signaled = 0; + while (!mt->signaled) { +- gettimeofday(&now, NULL); +- wait.tv_sec = now.tv_sec + 2; +- wait.tv_nsec = now.tv_usec * 1000; ++ clock_gettime(CLOCK_MONOTONIC, &wait); ++ wait.tv_sec += 2; + status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait); + if (status && status != ETIMEDOUT) + fatal(status); diff --git a/autofs.spec b/autofs.spec index 3901b0d..0afd429 100644 --- a/autofs.spec +++ b/autofs.spec @@ -8,7 +8,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.1.1 -Release: 7%{?dist} +Release: 20%{?dist} Epoch: 1 License: GPLv2+ Group: System Environment/Daemons @@ -18,6 +18,56 @@ Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Patch1: autofs-5.1.1-fix-fix-gcc5-complaints.patch Patch2: autofs-5.1.1-update-libtirpc-workaround-for-new-soname.patch Patch3: autofs-5.1.1-revert-fix-libtirpc-name-clash.patch +Patch4: autofs-5.1.1-fix-left-mount-count-return.patch +Patch5: autofs-5.1.1-fix-return-handling-in-sss-lookup-module.patch +Patch6: autofs-5.1.1-move-query-dn-calculation-from-do_bind-to-do_connect.patch +Patch7: autofs-5.1.1-make-do_connect-return-a-status.patch +Patch8: autofs-5.1.1-make-connect_to_server-return-a-status.patch +Patch9: autofs-5.1.1-make-find_dc_server-return-a-status.patch +Patch10: autofs-5.1.1-make-find_server-return-a-status.patch +Patch11: autofs-5.1.1-fix-return-handling-of-do_reconnect-in-ldap-module.patch +Patch12: autofs-5.1.1-fix-rwlock-unlock-crash.patch +Patch13: autofs-5.1.1-fix-config-old-name-lookup.patch +Patch14: autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch +Patch15: autofs-5.1.1-fix-direct-mount-stale-instance-flag-reset.patch +Patch16: autofs-5.1.1-fix-direct-map-expire-not-set-for-initial-empty-map.patch +Patch17: autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch +Patch18: autofs-5.1.1-fix-update_hosts_mounts-return.patch +Patch19: autofs-5.1.1-move-check_nss_result-to-nsswitch_c.patch +Patch20: autofs-5.1.1-make-open_lookup-return-nss-status.patch +Patch21: autofs-5.1.1-fix-nsswitch-handling-when-opening-multi-map.patch +Patch22: autofs-5.1.1-add-reinit-entry-point-to-modules.patch +Patch23: autofs-5.1.1-implement-reinit-in-parse-modules.patch +Patch24: autofs-5.1.1-implement-reinit-in-dir-lookup-module.patch +Patch25: autofs-5.1.1-implement-reinit-in-file-lookup-module.patch +Patch26: autofs-5.1.1-implement-reinit-in-hesiod-lookup-module.patch +Patch27: autofs-5.1.1-implement-reinit-in-hosts-lookup-module.patch +Patch28: autofs-5.1.1-implement-reinit-in-ldap-lookup-module.patch +Patch29: autofs-5.1.1-implement-reinit-in-nisplus-lookup-module.patch +Patch30: autofs-5.1.1-implement-reinit-in-program-lookup-module.patch +Patch31: autofs-5.1.1-implement-reinit-in-sss-lookup-module.patch +Patch32: autofs-5.1.1-implement-reinit-in-yp-lookup-module.patch +Patch33: autofs-5.1.1-add-type-to-struct-lookup_mod.patch +Patch34: autofs-5.1.1-factor-out-free-multi-map-context.patch +Patch35: autofs-5.1.1-factor-out-alloc-multi-map-context.patch +Patch36: autofs-5.1.1-fix-map-format-check-in-nss_open_lookup-multi-map-module.patch +Patch37: autofs-5.1.1-implement-reinit-in-multi-lookup-module.patch +Patch38: autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch +Patch39: autofs-5.1.1-update-map_hash_table_size-description.patch +Patch40: autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch +Patch41: autofs-5.1.1-fix-out-of-order-call-in-program-map-lookup.patch +Patch42: autofs-5.1.1-fix-error-handling-of-is_mounted.patch +Patch43: autofs-5.1.1-Add-a-mode-option-for-master-map-entries.patch +Patch44: autofs-5.1.1-define-monotonic-clock-helper-functions.patch +Patch45: autofs-5.1.1-use-monotonic-clock-for-alarm-thread-condition-wait.patch +Patch46: autofs-5.1.1-define-pending-condition-init-helper-function.patch +Patch47: autofs-5.1.1-use-monotonic-clock-for-direct-mount-condition.patch +Patch48: autofs-5.1.1-use-monotonic-clock-for-indirect-mount-condition.patch +Patch49: autofs-5.1.1-change-remaining-gettimeofday-to-use-clock_gettime.patch +Patch50: autofs-5.1.1-change-time-to-use-monotonic_clock.patch +Patch51: autofs-5.1.1-remove-unused-function-elapsed.patch +Patch52: autofs-5.1.1-fix-unbind-external-mech.patch +Patch53: autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch %if %{with_systemd} BuildRequires: systemd-units @@ -80,6 +130,56 @@ echo %{version}-%{release} > .version %patch1 -p1 %patch2 -p1 %patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch45 -p1 +%patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 %build LDFLAGS=-Wl,-z,now @@ -173,13 +273,17 @@ fi %dir /etc/auto.master.d %changelog -* Wed Nov 04 2015 Kalev Lember - 1:5.1.1-7 +* Wed Jan 20 2016 Ian Kent - 1:5.1.1-20 +- fix incorrect committer changelog entries. +- add current released upstream patches. + +* Wed Nov 04 2015 Ian Kent - 1:5.1.1-7 - revert fix libtirpc name clash patch (an old 5.0.6 patch). -* Wed Nov 04 2015 Kalev Lember - 1:5.1.1-6 +* Wed Nov 04 2015 Ian Kent - 1:5.1.1-6 - remove unnecessary nfs-utils BuildRequires (bz1277669). -* Mon Nov 02 2015 Kalev Lember - 1:5.1.1-5 +* Mon Nov 02 2015 Ian Kent - 1:5.1.1-5 - fix fix gcc5 complaints. - update libtirpc workaround for new soname.